1
0
Fork 0
mirror of https://github.com/heyarne/airsonic-ui.git synced 2026-05-07 02:33:39 +02:00

Implement go to source in current queue

This commit is contained in:
heyarne 2019-03-10 12:43:09 +01:00
commit ef1690084d
3 changed files with 58 additions and 24 deletions

View file

@ -18,8 +18,14 @@
(set-repeat-mode [this repeat-mode] (set-repeat-mode [this repeat-mode]
"Allows you to change how the next and previous song are selected") "Allows you to change how the next and previous song are selected")
(enqueue-last [this song]) (enqueue-last
(enqueue-next [this song]) [this song source]
[this song]
"Registers a song to be played last, optionally remembering the source route")
(enqueue-next
[this song source]
[this song]
"Registers a song to be played next, optionally remembering the source route")
(move-song [this from-idx to-idx] (move-song [this from-idx to-idx]
"Allows you to move a song in a playlist") "Allows you to move a song in a playlist")
@ -107,22 +113,28 @@
(set-repeat-mode [playlist repeat-mode] (set-repeat-mode [playlist repeat-mode]
(assoc playlist :repeat-mode repeat-mode)) (assoc playlist :repeat-mode repeat-mode))
(enqueue-last [this song] (enqueue-last [this song source]
(let [order (inc (key (last items)))] (let [order (inc (key (last items)))]
;; Arguably this is a bit weird; but if you want to play something last in ;; Arguably this is a bit weird; but if you want to play something last in
;; a shuffled playlist, you want to play it last I guess. ;; a shuffled playlist, you want to play it last I guess.
(assoc-in this [:items order] (assoc-in this [:items order]
(vary-meta song assoc :playlist/linear-order order)))) (vary-meta song assoc
:playlist/linear-order order
:playlist/source source))))
(enqueue-last [this song] (enqueue-last this song nil))
(enqueue-next [this song] (enqueue-next [this song source]
;; we slice the songs up until the currently playing one and increase the ;; we slice the songs up until the currently playing one and increase the
;; order for all the songs after ;; order for all the songs after
(let [songs (vec (vals items)) (let [songs (vec (vals items))
reordered (-> (subvec songs 0 (inc current-idx)) reordered (-> (subvec songs 0 (inc current-idx))
(conj (vary-meta song assoc :playlist/linear-order (inc current-idx))) (conj (vary-meta song assoc
:playlist/linear-order (inc current-idx)
:playlist/source source))
(concat (subvec songs (inc current-idx))))] (concat (subvec songs (inc current-idx))))]
(assoc this :items (->> (map-indexed vector reordered) (assoc this :items (->> (map-indexed vector reordered)
(into (sorted-map)))))) (into (sorted-map))))))
(enqueue-next [this song] (enqueue-next this song nil))
(move-song [this from-idx to-idx] (move-song [this from-idx to-idx]
;; we have to decide whether we move all items in-between ;; we have to decide whether we move all items in-between
@ -156,15 +168,29 @@
;; constructor wrapper ;; constructor wrapper
(defn set-item-source
"Can be used to attach a source route to an item"
[item source]
(vary-meta item assoc :playlist/source source))
(defn item-source
"Retrieve the source of an item in the playlist"
[item]
(:playlist/source (meta item)))
(defmulti ->playlist (defmulti ->playlist
"Creates a new playlist that behaves according to the given playback- and "Creates a new playlist that behaves according to the given playback- and
repeat-mode parameters." repeat-mode parameters."
(fn [_ & {:keys [playback-mode]}] playback-mode)) (fn [_ & {:keys [playback-mode]}] playback-mode))
(defmethod ->playlist :linear (defmethod ->playlist :linear
[items & {:keys [playback-mode repeat-mode]}] [items & {:keys [playback-mode repeat-mode source]}]
(->Playlist (linear-queue items) 0 playback-mode repeat-mode)) (->Playlist (->> (map #(set-item-source % source) items)
(linear-queue))
0 playback-mode repeat-mode))
(defmethod ->playlist :shuffled (defmethod ->playlist :shuffled
[items & {:keys [playback-mode repeat-mode]}] [items & {:keys [playback-mode repeat-mode source]}]
(->Playlist (shuffled-queue items) 0 playback-mode repeat-mode)) (->Playlist (->> (map #(set-item-source % source) items)
(shuffled-queue))
0 playback-mode repeat-mode))

View file

@ -3,14 +3,18 @@
[airsonic-ui.audio.playlist :as playlist] [airsonic-ui.audio.playlist :as playlist]
[airsonic-ui.api.helpers :as api])) [airsonic-ui.api.helpers :as api]))
; sets up the db, starts to play a song and adds the rest to a playlist
(defn play-all-songs [{:keys [db]
:routes/keys [current-route]} [_ songs start-idx]]
(let [playlist (-> (playlist/->playlist songs :playback-mode :linear :repeat-mode :repeat-all :source current-route)
(playlist/set-current-song start-idx))]
{:audio/play (api/stream-url (:credentials db) (playlist/current-song playlist))
:db (assoc-in db [:audio :current-playlist] playlist)}))
(rf/reg-event-fx (rf/reg-event-fx
; sets up the db, starts to play a song and adds the rest to a playlist
:audio-player/play-all :audio-player/play-all
(fn [{:keys [db]} [_ songs start-idx]] [(rf/inject-cofx :routes/current-route)]
(let [playlist (-> (playlist/->playlist songs :playback-mode :linear :repeat-mode :repeat-all) play-all-songs)
(playlist/set-current-song start-idx))]
{:audio/play (api/stream-url (:credentials db) (playlist/current-song 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
@ -46,15 +50,19 @@
(rf/reg-event-fx :audio-player/set-current-song set-current-song) (rf/reg-event-fx :audio-player/set-current-song set-current-song)
(rf/reg-event-db (rf/reg-event-fx
:audio-player/enqueue-next :audio-player/enqueue-next
(fn [db [_ song]] [(rf/inject-cofx :routes/current-route)]
(update-in db [:audio :current-playlist] #(playlist/enqueue-next % song)))) (fn [{:keys [db]
:routes/keys [current-route]} [_ song]]
{:db (update-in db [:audio :current-playlist] #(playlist/enqueue-next % song current-route))}))
(rf/reg-event-db (rf/reg-event-fx
:audio-player/enqueue-last :audio-player/enqueue-last
(fn [db [_ song]] [(rf/inject-cofx :routes/current-route)]
(update-in db [:audio :current-playlist] #(playlist/enqueue-last % song)))) (fn [{:keys [db]
:routes/keys [current-route]} [_ song]]
{:db (update-in db [:audio :current-playlist] #(playlist/enqueue-last % song current-route))}))
(rf/reg-event-db (rf/reg-event-db
:audio-player/move-song :audio-player/move-song

View file

@ -5,6 +5,7 @@
[bulma.icon :refer [icon]] [bulma.icon :refer [icon]]
[bulma.dropdown.views :refer [dropdown]] [bulma.dropdown.views :refer [dropdown]]
[airsonic-ui.helpers :as helpers] [airsonic-ui.helpers :as helpers]
[airsonic-ui.audio.playlist :as playlist]
[airsonic-ui.components.collection.views :as collection] [airsonic-ui.components.collection.views :as collection]
[airsonic-ui.components.sortable.views :as sortable] [airsonic-ui.components.sortable.views :as sortable]
[airsonic-ui.routes :as routes] [airsonic-ui.routes :as routes]
@ -22,11 +23,10 @@
[icon :elevator]])))) [icon :elevator]]))))
(defn song-actions [{:keys [song idx]}] (defn song-actions [{:keys [song idx]}]
;; TODO: Implement both of these
[dropdown {:items [{:label "Remove from queue" [dropdown {:items [{:label "Remove from queue"
:event [:audio-player/remove-song idx]} :event [:audio-player/remove-song idx]}
{:label "Go to source" {:label "Go to source"
:event []}]}]) :event [:routes/do-navigation (playlist/item-source song)]}]}])
(defn artist-link [{id :artistId, artist :artist}] (defn artist-link [{id :artistId, artist :artist}]
(if id (if id