From e142e162a5d2d80c0704f0626f191a4a8590b14d Mon Sep 17 00:00:00 2001 From: heyarne Date: Tue, 5 Mar 2019 09:06:02 +0100 Subject: [PATCH] Make sure current queue is displayed again --- src/cljs/airsonic_ui/audio/core.cljs | 18 +++- .../components/audio_player/events.cljs | 20 ++-- .../components/audio_player/views.cljs | 9 +- .../components/current_queue/views.cljs | 95 +++++++++++-------- 4 files changed, 83 insertions(+), 59 deletions(-) diff --git a/src/cljs/airsonic_ui/audio/core.cljs b/src/cljs/airsonic_ui/audio/core.cljs index 55b1950..5a95653 100644 --- a/src/cljs/airsonic_ui/audio/core.cljs +++ b/src/cljs/airsonic_ui/audio/core.cljs @@ -99,14 +99,23 @@ (rf/reg-sub :audio/summary summary) -(defn current-queue +(defn current-playlist "Lists the complete current-queue" [summary _] - (:current-queue summary)) + (:current-playlist summary)) + +(rf/reg-sub + :audio/current-playlist + :<- [:audio/summary] + current-playlist) + +(defn current-queue + [playlist _] + (vals (:items playlist))) (rf/reg-sub :audio/current-queue - :<- [:audio/summary] + :<- [:audio/current-playlist] current-queue) (defn current-song @@ -116,10 +125,9 @@ (when-not (empty? playlist) (playlist/current-song playlist))) - (rf/reg-sub :audio/current-song - :<- [:audio/current-queue] + :<- [:audio/current-playlist] current-song) (defn playback-status diff --git a/src/cljs/airsonic_ui/components/audio_player/events.cljs b/src/cljs/airsonic_ui/components/audio_player/events.cljs index e74856e..3fe5e44 100644 --- a/src/cljs/airsonic_ui/components/audio_player/events.cljs +++ b/src/cljs/airsonic_ui/components/audio_player/events.cljs @@ -10,43 +10,43 @@ (let [playlist (-> (playlist/->playlist songs :playback-mode :linear :repeat-mode :repeat-all) (playlist/set-current-song start-idx))] {:audio/play (api/stream-url (:credentials db) (playlist/current-song playlist)) - :db (assoc-in db [:audio :current-queue] playlist)}))) + :db (assoc-in db [:audio :current-playlist] playlist)}))) (rf/reg-event-db :audio-player/set-playback-mode (fn [db [_ playback-mode]] - (update-in db [:audio :current-queue] #(playlist/set-playback-mode % playback-mode)))) + (update-in db [:audio :current-playlist] #(playlist/set-playback-mode % playback-mode)))) (rf/reg-event-db :audio-player/set-repeat-mode (fn [db [_ repeat-mode]] - (update-in db [:audio :current-queue] #(playlist/set-repeat-mode % repeat-mode)))) + (update-in db [:audio :current-playlist] #(playlist/set-repeat-mode % repeat-mode)))) (rf/reg-event-fx :audio-player/next-song (fn [{:keys [db]} _] - (let [db (update-in db [:audio :current-queue] playlist/next-song) - next (playlist/current-song (get-in db [:audio :current-queue]))] + (let [db (update-in db [:audio :current-playlist] playlist/next-song) + next (playlist/current-song (get-in db [:audio :current-playlist]))] {:db db :audio/play (api/stream-url (:credentials db) next)}))) (rf/reg-event-fx :audio-player/previous-song (fn [{:keys [db]} _] - (let [db (update-in db [:audio :current-queue] playlist/previous-song) - prev (playlist/current-song (get-in db [:audio :current-queue]))] + (let [db (update-in db [:audio :current-playlist] playlist/previous-song) + prev (playlist/current-song (get-in db [:audio :current-playlist]))] {:db db :audio/play (api/stream-url (:credentials db) prev)}))) (rf/reg-event-db :audio-player/enqueue-next (fn [db [_ song]] - (update-in db [:audio :current-queue] #(playlist/enqueue-next % song)))) + (update-in db [:audio :current-playlist] #(playlist/enqueue-next % song)))) (rf/reg-event-db :audio-player/enqueue-last (fn [db [_ song]] - (update-in db [:audio :current-queue] #(playlist/enqueue-last % song)))) + (update-in db [:audio :current-playlist] #(playlist/enqueue-last % song)))) (rf/reg-event-fx :audio-player/toggle-play-pause @@ -65,7 +65,7 @@ (rf/reg-event-fx :audio-player/seek (fn [{:keys [db]} [_ percentage]] - (let [duration (:duration (playlist/current-song (get-in db [:audio :current-queue])))] + (let [duration (:duration (playlist/current-song (get-in db [:audio :current-playlist])))] {:audio/seek [percentage duration]}))) (rf/reg-event-fx diff --git a/src/cljs/airsonic_ui/components/audio_player/views.cljs b/src/cljs/airsonic_ui/components/audio_player/views.cljs index 10605f8..bb893c7 100644 --- a/src/cljs/airsonic_ui/components/audio_player/views.cljs +++ b/src/cljs/airsonic_ui/components/audio_player/views.cljs @@ -121,9 +121,8 @@ {:on-click toggle-volume-slider} [icon volume-icon]]])) -(defn playback-mode-controls [playlist] - (let [{:keys [repeat-mode playback-mode]} playlist - button :p.control>button.button.is-light +(defn playback-mode-controls [{:keys [repeat-mode playback-mode]}] + (let [button :p.control>button.button.is-light shuffle-button (h/add-classes button (when (= playback-mode :shuffled) :is-primary)) repeat-button (h/add-classes button (case repeat-mode :repeat-single :is-info @@ -142,7 +141,7 @@ (defn audio-player [] (let [current-song @(subscribe [:audio/current-song]) - current-queue @(subscribe [:audio/current-queue]) + current-playlist @(subscribe [:audio/current-playlist]) playback-status @(subscribe [:audio/playback-status]) is-playing? @(subscribe [:audio/is-playing?])] [:nav.audio-player @@ -153,6 +152,6 @@ [progress-indicators current-song playback-status] [playback-controls is-playing?] [volume-controls playback-status] - [playback-mode-controls current-queue]] + [playback-mode-controls current-playlist]] ;; not playing anything [:p.navbar-item.idle-notification "No audio playing"])])) diff --git a/src/cljs/airsonic_ui/components/current_queue/views.cljs b/src/cljs/airsonic_ui/components/current_queue/views.cljs index 383933e..7bc4ab6 100644 --- a/src/cljs/airsonic_ui/components/current_queue/views.cljs +++ b/src/cljs/airsonic_ui/components/current_queue/views.cljs @@ -1,13 +1,12 @@ (ns airsonic-ui.components.current-queue.views - (:require [re-frame.core :refer [subscribe]] - [reagent.core :as reagent] + (:require [re-frame.core :refer [subscribe dispatch]] + [reagent.core :as r] ["react-sortable-hoc" :refer [SortableHandle]] [airsonic-ui.helpers :as helpers] [airsonic-ui.views.song :as song] + [airsonic-ui.views.icon :refer [icon]] [airsonic-ui.components.sortable.views :as sortable] - [airsonic-ui.routes :as r])) - -(defonce items (reagent/atom [1 2 3 4 5 6 7])) + [airsonic-ui.routes :as routes])) (def SortHandle (SortableHandle. @@ -15,39 +14,57 @@ ;; is to just provide fn as component and use as-element or create-element ;; to return React elements from the component. (fn [] - (reagent/as-element [:span {:style {:WebkitTouchCallout "none" - :WebkitUserSelect "none" - :KhtmlUserSelect "none" - :MozUserSelect "none" - ;; NOTE: lowercase "ms" prefix - ;; https://www.andismith.com/blogs/2012/02/modernizr-prefixed/ - :msUserSelect "none" - :userSelect "none"}} - "::"])))) + (r/as-element [:span.is-size-7.has-text-grey-lighter + [icon :elevator]])))) + +(defn song-actions [] + (let [controls-id (str "song-actions-" (random-uuid)) + is-active? (r/atom false)] + (fn [] + [(if @is-active? :div.dropdown.is-right.is-active :div.dropdown.is-right) + [:div.dropdown-trigger + [:span.is-small.button {:aria-haspopup "true" + :aria-controls controls-id + :on-click #(swap! is-active? not)} + [icon :ellipses]]] + [:div.dropdown-menu {:id controls-id, :role "menu"} + [:div.dropdown-content + ;; TODO: Implement removal + [:a.dropdown-item {:href "#"} "Remove from queue"] + ;; TODO: Implement "Go to source" + [:a.dropdown-item {:href "#"} "Go to source"]]]]))) + +(defn artist-link [{id :artistId, artist :artist}] + (if id + [:a {:href (routes/url-for ::routes/artist.detail {:id id})} artist] + artist)) + +(defn song-table [{:keys [songs current-song]}] + [:table.song-listing-table.table.is-fullwidth + [sortable/sortable-component + {:container [:tbody] + :items songs + + :render-item + (fn [{song :value}] + [(if (= (:id song) (:id current-song)) :tr.is-playing :tr) + [:td.sort-handle.is-narrow [:> SortHandle]] + [:td.song-artist [artist-link song]] + [:td.song-title (:title song)] + [:td.song-duration (helpers/format-duration (:duration song) :brief? true)] + [:td.song-actions.is-narrow [song-actions]]]) + + :on-sort-end + (fn [{:keys [old-idx new-idx]}] + )}]]) (defn current-queue [] - (let [is-sortable? (reagent/atom true)] - (fn [] - [:section.section>div.container - [:h1.title "Current Queue"] - [sortable/sortable-component {:container [:table.table.is-fullwidth>tbody] - :items @items - - :render-item - (fn [{:keys [value]}] - [:tr - [:td "Some table cell"] - [:td (str "Value: " value)] - [:td [:a {:on-click #(swap! is-sortable? not)} (str "Is sortable: " @is-sortable?)]] - [:td (when @is-sortable? - [:> SortHandle])]]) - - :on-sort-end - (fn [{:keys [old-idx new-idx]}] - (swap! items helpers/vector-move old-idx new-idx))}] - (let [current-queue @(subscribe [:audio/current-queue]) - #_#_ current-song @(subscribe [:audio/current-song])] - (if (some? current-queue) - [song/listing (:items current-queue)] - [:p "You are currently not playing anything. Use the search or go to your " - [:a {:href (r/url-for ::r/library)} "Library"] " to start playing some music."]))]))) + [:section.section>div.container + [:h1.title "Current Queue"] + (let [current-queue @(subscribe [:audio/current-queue]) + current-song @(subscribe [:audio/current-song])] + (if (some? current-queue) + [song-table {:songs current-queue + :current-song current-song}] + [:p "You are currently not playing anything. Use the search or go to your " + [:a {:href (routes/url-for ::routes/library)} "Library"] " to start playing some music."]))])