mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-07 10:43:39 +02:00
Complete implementation for playlist/next-song
This commit is contained in:
parent
d7b8cbcc4e
commit
f7e4bc58a7
3 changed files with 94 additions and 63 deletions
|
|
@ -11,8 +11,9 @@
|
|||
;; debugging
|
||||
[day8.re-frame/re-frame-10x "0.3.3-react16"]
|
||||
[day8.re-frame/tracing "0.5.1"]
|
||||
[philoskim/debux "0.4.11"]
|
||||
;; for CIDER
|
||||
[cider/cider-nrepl "0.18.0-SNAPSHOT"]]
|
||||
[cider/cider-nrepl "0.18.0"]]
|
||||
|
||||
:nrepl {:port 9000}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,23 +26,25 @@
|
|||
(range (count queue))))]
|
||||
(->Playlist queue playback-mode repeat-mode)))
|
||||
|
||||
(defmethod ->playlist :playback-mode/shuffle
|
||||
(defn- -shuffle-songs [queue]
|
||||
(mapv (fn [song order] (assoc song :order order)) queue (shuffle (range (count queue)))))
|
||||
|
||||
(defmethod ->playlist :playback-mode/shuffled
|
||||
[queue playing-idx playback-mode repeat-mode]
|
||||
(let [queue (->> (playlist-queue queue playing-idx)
|
||||
(mapv (fn [order song] (assoc song :order order))
|
||||
(shuffle (range (count queue)))))]
|
||||
(-shuffle-songs))]
|
||||
(->Playlist queue playback-mode repeat-mode)))
|
||||
|
||||
(defn- current-idx [playlist]
|
||||
(first (keep-indexed (fn [idx item]
|
||||
(when (:currently-playing? item)
|
||||
idx))
|
||||
(defn- -current-song [playlist]
|
||||
(first (keep-indexed (fn [idx song]
|
||||
(when (:currently-playing? song)
|
||||
[idx song]))
|
||||
(:queue playlist))))
|
||||
|
||||
(defn set-playback-mode
|
||||
"Changes the playback mode of a playlist and re-shuffles it if necessary"
|
||||
[playlist playback-mode]
|
||||
(->playlist (:queue playlist) (current-idx playlist)
|
||||
(->playlist (:queue playlist) (first (-current-song playlist))
|
||||
playback-mode (:repeat-mode playlist)))
|
||||
|
||||
(defn set-repeat-mode
|
||||
|
|
@ -57,38 +59,45 @@
|
|||
(filter :currently-playing?)
|
||||
(first)))
|
||||
|
||||
(defn- ?assoc
|
||||
"Like assoc, but returns coll unchanged if (pref coll) is false"
|
||||
[coll pred & assog-args]
|
||||
(if (pred coll) (apply assoc coll assog-args) coll))
|
||||
(defmulti next-song :repeat-mode)
|
||||
|
||||
(defmulti next-song (juxt :playback-mode :repeat-mode))
|
||||
|
||||
(defmethod next-song [:playback-mode/linear :repeat-mode/none]
|
||||
(defmethod next-song :repeat-mode/none
|
||||
[playlist]
|
||||
(let [current-idx (current-idx playlist)
|
||||
;; this is pretty easy; get the next song and stop playing at the at
|
||||
(let [[current-idx _] (-current-song playlist)
|
||||
next-idx (inc current-idx)]
|
||||
(println "next-idx" next-idx "current-idx" current-idx "(< next-idx (count playlist))" (< next-idx (count playlist)))
|
||||
(update playlist :queue
|
||||
(fn [queue] (-> (update queue current-idx dissoc :currently-playing?)
|
||||
(?assoc #(< next-idx (count playlist))
|
||||
next-idx (assoc (get queue next-idx)
|
||||
:currently-playing? true)))))))
|
||||
(fn [queue] (cond-> queue
|
||||
:always (update current-idx dissoc :currently-playing?)
|
||||
(< next-idx (count playlist)) (assoc-in [next-idx :currently-playing?] true))))))
|
||||
|
||||
(defmethod next-song [:playback-mode/linear :repeat-mode/single]
|
||||
(defmethod next-song :repeat-mode/single [playlist] playlist)
|
||||
|
||||
(defmethod next-song :repeat-mode/all
|
||||
[playlist]
|
||||
playlist)
|
||||
(let [[current-idx _] (-current-song playlist)]
|
||||
(-> (update-in playlist [:queue current-idx] dissoc :currently-playing?)
|
||||
(update :queue
|
||||
(fn [queue]
|
||||
;; we need special treatment here if we're playing the last song and
|
||||
;; have a shuffled playlist because we need to re-shuffle
|
||||
(if (and (= current-idx (dec (count playlist)))
|
||||
(= :playback-mode/shuffled (:playback-mode playlist)))
|
||||
(->> (-shuffle-songs queue)
|
||||
(mapv #(if (= (:order %) 0) (assoc % :currently-playing? true) %)))
|
||||
(let [next-idx (mod (inc current-idx) (count playlist))]
|
||||
(assoc-in queue [next-idx :currently-playing?] true))))))))
|
||||
|
||||
(defmethod next-song [:playback-mode/linear :repeat-mode/all]
|
||||
[playlist]
|
||||
(let [current-idx (current-idx playlist)
|
||||
next-idx (mod (inc current-idx) (count playlist))]
|
||||
(update playlist :queue
|
||||
(fn [queue] (-> (update queue current-idx dissoc :currently-playing?)
|
||||
(assoc-in [next-idx :currently-playing?] true))))))
|
||||
(defmulti previous-song :repeat-mode)
|
||||
|
||||
(defmethod next-song [:playback-mode/shuffle :repeat-mode/single]
|
||||
[playlist]
|
||||
playlist)
|
||||
(defn set-current-song [playlist playing-idx]
|
||||
;; TODO: Implementation
|
||||
)
|
||||
|
||||
(defmulti previous-song (juxt :playback-mode :repeat-mode))
|
||||
(defn add-song-to-end [playlist]
|
||||
;; TODO: Implementation
|
||||
)
|
||||
|
||||
(defn add-next-song [playlist]
|
||||
;; TODO: Implementation
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
(testing "should give us the correct current song"
|
||||
(let [queue (playing-queue 10)
|
||||
start-idx (rand-int 10)]
|
||||
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffle]
|
||||
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffled]
|
||||
repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]]
|
||||
(is (same-song? (nth queue start-idx)
|
||||
(-> (playlist/->playlist queue start-idx playback-mode repeat-mode)
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
(testing "should give us a playlist with the correct number of tracks"
|
||||
(let [queue (playing-queue 100)
|
||||
start-idx (rand-int 100)]
|
||||
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffle]
|
||||
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffled]
|
||||
repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]]
|
||||
(is (= (count queue)
|
||||
(count (playlist/->playlist queue start-idx playback-mode repeat-mode)))
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
(let [queue (playing-queue 10)
|
||||
start-idx (rand-int 10)
|
||||
linear (playlist/->playlist queue start-idx :playback-mode/linear :repeat-mode/node)
|
||||
shuffled (playlist/set-playback-mode linear :playback-mode/shuffle)]
|
||||
shuffled (playlist/set-playback-mode linear :playback-mode/shuffled)]
|
||||
(testing "should re-order the tracks"
|
||||
(is (not= (map :order (:queue shuffled)) (map :order (:queue linear)))))
|
||||
(testing "should not change the currently playing track"
|
||||
|
|
@ -61,7 +61,8 @@
|
|||
(testing "from shuffled to linear"
|
||||
(let [queue (playing-queue 10)
|
||||
start-idx (rand-int 10)
|
||||
shuffled (playlist/->playlist queue start-idx :playback-mode/shuffle :repeat-mode/none)
|
||||
shuffled (playlist/->playlist queue start-idx
|
||||
:playback-mode/shuffled :repeat-mode/none)
|
||||
linear (playlist/set-playback-mode shuffled :playback-mode/linear)]
|
||||
(testing "should set the correct order for tracks"
|
||||
(is (every? #(apply same-song? %)
|
||||
|
|
@ -81,10 +82,11 @@
|
|||
(deftest chaging-repeat-mode
|
||||
(testing "Changing the repeat mode"
|
||||
(testing "should not change the playback mode"
|
||||
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffle]
|
||||
(doseq [playback-mode [:playback-mode/linear, :playback-mode/shuffled]
|
||||
repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]
|
||||
next-repeat-mode [:repeat-mode/none, :repeat-mode/single, :repeat-mode/all]]
|
||||
(let [playlist (-> (playlist/->playlist (playing-queue 1) 0 playback-mode repeat-mode)
|
||||
(let [playlist (-> (playlist/->playlist (playing-queue 1) 0
|
||||
playback-mode repeat-mode)
|
||||
(playlist/set-repeat-mode next-repeat-mode))]
|
||||
(is (= playback-mode (:playback-mode playlist)))
|
||||
(is (= next-repeat-mode (:repeat-mode playlist))
|
||||
|
|
@ -106,32 +108,51 @@
|
|||
(testing "Should always give the same track when repeat-mode is single"
|
||||
(let [queue (playing-queue 3)
|
||||
playing-idx (rand-int 3)
|
||||
playlist (playlist/->playlist queue playing-idx :playback-mode/linear :repeat-mode/single)]
|
||||
(is (same-song? (nth queue playing-idx) (playlist/peek playlist)))
|
||||
(is (same-song? (nth queue playing-idx)
|
||||
(-> (playlist/next-song playlist)
|
||||
(playlist/peek))))
|
||||
(is (same-song? (nth queue playing-idx)
|
||||
(-> (playlist/next-song playlist)
|
||||
(playlist/next-song)
|
||||
(playlist/peek))))
|
||||
(is (same-song? (nth queue playing-idx)
|
||||
(-> (playlist/next-song playlist)
|
||||
(playlist/next-song)
|
||||
(playlist/next-song)
|
||||
(playlist/peek)))
|
||||
"wrapping around")))
|
||||
playlist (playlist/->playlist queue playing-idx
|
||||
:playback-mode/linear :repeat-mode/single)
|
||||
played-back (map playlist/peek (iterate playlist/next-song playlist))]
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 0)))
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 1)))
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 2)))
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 3)) "wrapping around")))
|
||||
(testing "Should stop playing at the end of the queue when repeat-mode is none"
|
||||
(is (nil? (-> (playing-queue 1)
|
||||
(playlist/->playlist 0 :playback-mode/linear :repeat-mode/none)
|
||||
(playlist/next-song)
|
||||
(playlist/peek))))))
|
||||
|
||||
#_(deftest shuffled-next-song
|
||||
(testing "Should play every track once when called for the entire queue")
|
||||
(testing "Should re-shuffle the playlist when wrapping around and repeat-mode is all")
|
||||
(testing "Should always give the same track when repeat-mode is single")
|
||||
(testing "Should stop playing at the end of the queue when repeat-mode is none"))
|
||||
(deftest shuffled-next-song
|
||||
(testing "Should play every track once when called for the entire queue"
|
||||
(doseq [repeat-mode '(:repeat-mode/none :repeat-mode/all)]
|
||||
(let [length 10
|
||||
playlist (playlist/->playlist (playing-queue length) 0
|
||||
:playback-mode/shuffled repeat-mode)
|
||||
played-tracks (->> (iterate playlist/next-song playlist)
|
||||
(map playlist/peek)
|
||||
(take length))]
|
||||
(is (= (count played-tracks) (count (set played-tracks)))
|
||||
(str repeat-mode)))))
|
||||
(testing "Should re-shuffle the playlist when wrapping around and repeat-mode is all"
|
||||
(let [length 100
|
||||
playlist (playlist/->playlist (playing-queue length) (dec length)
|
||||
:playback-mode/shuffled :repeat-mode/all)]
|
||||
(is (not= (map :order (:queue playlist))
|
||||
(map :order (:queue (playlist/next-song playlist)))))))
|
||||
(testing "Should always give the same track when repeat-mode is single"
|
||||
(let [queue (playing-queue 3)
|
||||
playing-idx (rand-int 3)
|
||||
playlist (playlist/->playlist queue playing-idx
|
||||
:playback-mode/shuffled :repeat-mode/single)
|
||||
played-back (map playlist/peek (iterate playlist/next-song playlist))]
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 0)))
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 1)))
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 2)))
|
||||
(is (same-song? (nth queue playing-idx) (nth played-back 3)) "wrapping around")))
|
||||
(testing "Should stop playing at the end of the queue when repeat-mode is none"
|
||||
(is (nil? (-> (playing-queue 1)
|
||||
(playlist/->playlist 0 :playback-mode/linear :repeat-mode/none)
|
||||
(playlist/next-song)
|
||||
(playlist/peek))))))
|
||||
|
||||
#_(deftest linear-previous-song)
|
||||
#_(deftest shuffled-previous-song)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue