mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-07 02:33:39 +02:00
Make sure current queue is displayed again
This commit is contained in:
parent
644939c618
commit
e142e162a5
4 changed files with 81 additions and 57 deletions
|
|
@ -99,14 +99,23 @@
|
||||||
|
|
||||||
(rf/reg-sub :audio/summary summary)
|
(rf/reg-sub :audio/summary summary)
|
||||||
|
|
||||||
(defn current-queue
|
(defn current-playlist
|
||||||
"Lists the complete current-queue"
|
"Lists the complete current-queue"
|
||||||
[summary _]
|
[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
|
(rf/reg-sub
|
||||||
:audio/current-queue
|
:audio/current-queue
|
||||||
:<- [:audio/summary]
|
:<- [:audio/current-playlist]
|
||||||
current-queue)
|
current-queue)
|
||||||
|
|
||||||
(defn current-song
|
(defn current-song
|
||||||
|
|
@ -116,10 +125,9 @@
|
||||||
(when-not (empty? playlist)
|
(when-not (empty? playlist)
|
||||||
(playlist/current-song playlist)))
|
(playlist/current-song playlist)))
|
||||||
|
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:audio/current-song
|
:audio/current-song
|
||||||
:<- [:audio/current-queue]
|
:<- [:audio/current-playlist]
|
||||||
current-song)
|
current-song)
|
||||||
|
|
||||||
(defn playback-status
|
(defn playback-status
|
||||||
|
|
|
||||||
|
|
@ -10,43 +10,43 @@
|
||||||
(let [playlist (-> (playlist/->playlist songs :playback-mode :linear :repeat-mode :repeat-all)
|
(let [playlist (-> (playlist/->playlist songs :playback-mode :linear :repeat-mode :repeat-all)
|
||||||
(playlist/set-current-song start-idx))]
|
(playlist/set-current-song start-idx))]
|
||||||
{:audio/play (api/stream-url (:credentials db) (playlist/current-song playlist))
|
{: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
|
(rf/reg-event-db
|
||||||
:audio-player/set-playback-mode
|
:audio-player/set-playback-mode
|
||||||
(fn [db [_ 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
|
(rf/reg-event-db
|
||||||
:audio-player/set-repeat-mode
|
:audio-player/set-repeat-mode
|
||||||
(fn [db [_ 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
|
(rf/reg-event-fx
|
||||||
:audio-player/next-song
|
:audio-player/next-song
|
||||||
(fn [{:keys [db]} _]
|
(fn [{:keys [db]} _]
|
||||||
(let [db (update-in db [:audio :current-queue] playlist/next-song)
|
(let [db (update-in db [:audio :current-playlist] playlist/next-song)
|
||||||
next (playlist/current-song (get-in db [:audio :current-queue]))]
|
next (playlist/current-song (get-in db [:audio :current-playlist]))]
|
||||||
{:db db
|
{:db db
|
||||||
:audio/play (api/stream-url (:credentials db) next)})))
|
:audio/play (api/stream-url (:credentials db) next)})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:audio-player/previous-song
|
:audio-player/previous-song
|
||||||
(fn [{:keys [db]} _]
|
(fn [{:keys [db]} _]
|
||||||
(let [db (update-in db [:audio :current-queue] playlist/previous-song)
|
(let [db (update-in db [:audio :current-playlist] playlist/previous-song)
|
||||||
prev (playlist/current-song (get-in db [:audio :current-queue]))]
|
prev (playlist/current-song (get-in db [:audio :current-playlist]))]
|
||||||
{:db db
|
{:db db
|
||||||
:audio/play (api/stream-url (:credentials db) prev)})))
|
:audio/play (api/stream-url (:credentials db) prev)})))
|
||||||
|
|
||||||
(rf/reg-event-db
|
(rf/reg-event-db
|
||||||
:audio-player/enqueue-next
|
:audio-player/enqueue-next
|
||||||
(fn [db [_ song]]
|
(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
|
(rf/reg-event-db
|
||||||
:audio-player/enqueue-last
|
:audio-player/enqueue-last
|
||||||
(fn [db [_ song]]
|
(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
|
(rf/reg-event-fx
|
||||||
:audio-player/toggle-play-pause
|
:audio-player/toggle-play-pause
|
||||||
|
|
@ -65,7 +65,7 @@
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:audio-player/seek
|
:audio-player/seek
|
||||||
(fn [{:keys [db]} [_ percentage]]
|
(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]})))
|
{:audio/seek [percentage duration]})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
|
|
||||||
|
|
@ -121,9 +121,8 @@
|
||||||
{:on-click toggle-volume-slider}
|
{:on-click toggle-volume-slider}
|
||||||
[icon volume-icon]]]))
|
[icon volume-icon]]]))
|
||||||
|
|
||||||
(defn playback-mode-controls [playlist]
|
(defn playback-mode-controls [{:keys [repeat-mode playback-mode]}]
|
||||||
(let [{:keys [repeat-mode playback-mode]} playlist
|
(let [button :p.control>button.button.is-light
|
||||||
button :p.control>button.button.is-light
|
|
||||||
shuffle-button (h/add-classes button (when (= playback-mode :shuffled) :is-primary))
|
shuffle-button (h/add-classes button (when (= playback-mode :shuffled) :is-primary))
|
||||||
repeat-button (h/add-classes button (case repeat-mode
|
repeat-button (h/add-classes button (case repeat-mode
|
||||||
:repeat-single :is-info
|
:repeat-single :is-info
|
||||||
|
|
@ -142,7 +141,7 @@
|
||||||
|
|
||||||
(defn audio-player []
|
(defn audio-player []
|
||||||
(let [current-song @(subscribe [:audio/current-song])
|
(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])
|
playback-status @(subscribe [:audio/playback-status])
|
||||||
is-playing? @(subscribe [:audio/is-playing?])]
|
is-playing? @(subscribe [:audio/is-playing?])]
|
||||||
[:nav.audio-player
|
[:nav.audio-player
|
||||||
|
|
@ -153,6 +152,6 @@
|
||||||
[progress-indicators current-song playback-status]
|
[progress-indicators current-song playback-status]
|
||||||
[playback-controls is-playing?]
|
[playback-controls is-playing?]
|
||||||
[volume-controls playback-status]
|
[volume-controls playback-status]
|
||||||
[playback-mode-controls current-queue]]
|
[playback-mode-controls current-playlist]]
|
||||||
;; not playing anything
|
;; not playing anything
|
||||||
[:p.navbar-item.idle-notification "No audio playing"])]))
|
[:p.navbar-item.idle-notification "No audio playing"])]))
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
(ns airsonic-ui.components.current-queue.views
|
(ns airsonic-ui.components.current-queue.views
|
||||||
(:require [re-frame.core :refer [subscribe]]
|
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as r]
|
||||||
["react-sortable-hoc" :refer [SortableHandle]]
|
["react-sortable-hoc" :refer [SortableHandle]]
|
||||||
[airsonic-ui.helpers :as helpers]
|
[airsonic-ui.helpers :as helpers]
|
||||||
[airsonic-ui.views.song :as song]
|
[airsonic-ui.views.song :as song]
|
||||||
|
[airsonic-ui.views.icon :refer [icon]]
|
||||||
[airsonic-ui.components.sortable.views :as sortable]
|
[airsonic-ui.components.sortable.views :as sortable]
|
||||||
[airsonic-ui.routes :as r]))
|
[airsonic-ui.routes :as routes]))
|
||||||
|
|
||||||
(defonce items (reagent/atom [1 2 3 4 5 6 7]))
|
|
||||||
|
|
||||||
(def SortHandle
|
(def SortHandle
|
||||||
(SortableHandle.
|
(SortableHandle.
|
||||||
|
|
@ -15,39 +14,57 @@
|
||||||
;; is to just provide fn as component and use as-element or create-element
|
;; is to just provide fn as component and use as-element or create-element
|
||||||
;; to return React elements from the component.
|
;; to return React elements from the component.
|
||||||
(fn []
|
(fn []
|
||||||
(reagent/as-element [:span {:style {:WebkitTouchCallout "none"
|
(r/as-element [:span.is-size-7.has-text-grey-lighter
|
||||||
:WebkitUserSelect "none"
|
[icon :elevator]]))))
|
||||||
:KhtmlUserSelect "none"
|
|
||||||
:MozUserSelect "none"
|
(defn song-actions []
|
||||||
;; NOTE: lowercase "ms" prefix
|
(let [controls-id (str "song-actions-" (random-uuid))
|
||||||
;; https://www.andismith.com/blogs/2012/02/modernizr-prefixed/
|
is-active? (r/atom false)]
|
||||||
:msUserSelect "none"
|
(fn []
|
||||||
:userSelect "none"}}
|
[(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 []
|
(defn current-queue []
|
||||||
(let [is-sortable? (reagent/atom true)]
|
[:section.section>div.container
|
||||||
(fn []
|
[:h1.title "Current Queue"]
|
||||||
[:section.section>div.container
|
(let [current-queue @(subscribe [:audio/current-queue])
|
||||||
[:h1.title "Current Queue"]
|
current-song @(subscribe [:audio/current-song])]
|
||||||
[sortable/sortable-component {:container [:table.table.is-fullwidth>tbody]
|
(if (some? current-queue)
|
||||||
:items @items
|
[song-table {:songs current-queue
|
||||||
|
:current-song current-song}]
|
||||||
:render-item
|
[:p "You are currently not playing anything. Use the search or go to your "
|
||||||
(fn [{:keys [value]}]
|
[:a {:href (routes/url-for ::routes/library)} "Library"] " to start playing some music."]))])
|
||||||
[: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."]))])))
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue