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

Implement song-move in playlist

This commit is contained in:
heyarne 2019-03-08 08:30:50 +01:00
commit abfe6f164c
3 changed files with 81 additions and 12 deletions

View file

@ -19,7 +19,10 @@
"Allows you to change how the next and previous song are selected")
(enqueue-last [this song])
(enqueue-next [this song]))
(enqueue-next [this song])
(move-song [this from-idx to-idx]
"Allows you to move a song in a playlist"))
;; helpers to manage creating playlists
@ -117,7 +120,29 @@
(conj (vary-meta song assoc :playlist/linear-order (inc current-idx)))
(concat (subvec songs (inc current-idx))))]
(assoc this :items (->> (map-indexed vector reordered)
(into (sorted-map)))))))
(into (sorted-map))))))
(move-song [this from-idx to-idx]
;; we have to decide whether we move all items in-between
;; one up or one down; this depends on whether we move our
;; item to the front or to the back
(let [shift-fn (cond
(< from-idx to-idx) inc
(> from-idx to-idx) dec)
start (min from-idx to-idx)
end (inc (max from-idx to-idx))
steps (range start end)
result (update this :items
(fn [items]
(-> (reduce (fn [result idx]
(assoc result idx (get items (shift-fn idx))))
items steps)
(assoc to-idx (get items from-idx)))))]
(cond
(= from-idx current-idx) (assoc result :current-idx to-idx)
(<= to-idx current-idx from-idx) (update result :current-idx inc)
(>= to-idx current-idx from-idx) (update result :current-idx dec)
:else result))))
;; constructor wrapper

View file

@ -47,10 +47,3 @@
(if brief?
(brief-duration hours minutes seconds)
(long-duration hours minutes seconds))))
(defn vector-move [coll prev-index new-index]
(let [items (into (subvec coll 0 prev-index)
(subvec coll (inc prev-index)))]
(-> (subvec items 0 new-index)
(conj (get coll prev-index))
(into (subvec items new-index)))))

View file

@ -250,11 +250,62 @@
(deftest enqueue-next
(testing "Should play the song after the currently playing song"
(doseq [playback-mode '(:linear :shuffled)
repeat-mode '(:repeat-none :repeat-all)]
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-all]]
(let [length 5, queue (song-queue length)
playlist (playlist/->playlist queue :playback-mode playback-mode :repeat-mode repeat-mode)
next-song (song)]
(is (same-song? next-song (-> (playlist/enqueue-next playlist next-song)
(playlist/next-song)
(playlist/current-song))))))))
(deftest move-track
(testing "Should correctly set the new order"
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-all :repeat-single]]
(let [n-songs 10
queue (song-queue n-songs)
playlist (playlist/->playlist queue :repeat-mode repeat-mode :playback-mode playback-mode)]
(is (same-song? (-> (playlist/next-song playlist)
(playlist/next-song)
(playlist/current-song))
(-> (playlist/move-song playlist 2 1)
(playlist/next-song)
(playlist/current-song)))))))
(testing "Should update the currently playing track's index"
(testing "when inserting a track before"
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-all :repeat-single]]
(let [n-songs 10
queue (song-queue n-songs)
playlist (playlist/->playlist queue :repeat-mode repeat-mode :playback-mode playback-mode)]
(is (= 4 (-> (playlist/set-current-song playlist 3)
(playlist/move-song 5 3)
:current-idx))))))
(testing "when moving a track behind it"
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-all :repeat-single]]
(let [n-songs 10
queue (song-queue n-songs)
playlist (playlist/->playlist queue :repeat-mode repeat-mode :playback-mode playback-mode)]
(is (= 2 (-> (playlist/set-current-song playlist 3)
(playlist/move-song 2 5)
:current-idx))))))
(testing "when moving it"
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-all :repeat-single]]
(let [n-songs 10
queue (song-queue n-songs)
playlist (playlist/->playlist queue :repeat-mode repeat-mode :playback-mode playback-mode)]
(is (= 7 (-> (playlist/set-current-song playlist 3)
(playlist/move-song 3 7)
:current-idx))))))
(testing "when the current track is outside of the modified range"
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-all :repeat-single]]
(let [n-songs 10
queue (song-queue n-songs)
playlist (playlist/->playlist queue :repeat-mode repeat-mode :playback-mode playback-mode)]
(is (= 3 (-> (playlist/set-current-song playlist 3)
(playlist/move-song 4 7)
:current-idx))))))))