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

Remove current song

This commit is contained in:
heyarne 2019-03-10 12:09:17 +01:00
commit 065b3a6647
7 changed files with 72 additions and 7 deletions

View file

@ -1,7 +1,12 @@
module.exports = function (config) { module.exports = function (config) {
const configuration = { const configuration = {
browsers: ['ChromeHeadless'], browsers: ['ChromeHeadless'],
autoWatchBatchDelay: 1000, // The tests are sometimes run before the tests were completely written
// to disc; this is a known problem unfortunately. This is a hack to at
// least keep the browsers connected so the tests are compiled and run
// again even if a developer isn't aware of this
autoWatchBatchDelay: 100,
browserNoActivityTimeout: 60 * 1000 * 10,
// The directory where the output file lives // The directory where the output file lives
basePath: 'public/test', basePath: 'public/test',
// The file itself // The file itself

View file

@ -53,7 +53,8 @@
(fn [_] (fn [_]
(when-let [audio @audio] (when-let [audio @audio]
(.pause audio) (.pause audio)
(set! (.-currentTime audio) 0)))) (set! (.-currentTime audio) 0)
(set! (.-src audio) ""))))
(rf/reg-fx (rf/reg-fx
:audio/toggle-play-pause :audio/toggle-play-pause

View file

@ -22,7 +22,9 @@
(enqueue-next [this song]) (enqueue-next [this song])
(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")
(remove-song [this song-idx]
"Removes a song from the playlist"))
;; helpers to manage creating playlists ;; helpers to manage creating playlists
@ -142,7 +144,15 @@
(= from-idx current-idx) (assoc result :current-idx to-idx) (= 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 inc)
(>= to-idx current-idx from-idx) (update result :current-idx dec) (>= to-idx current-idx from-idx) (update result :current-idx dec)
:else result)))) :else result)))
(remove-song [this song-idx]
(cond-> (update this :items #(let [n-items (count %)]
(-> (reduce (fn [items idx]
(assoc items idx (get items (inc idx))))
% (range song-idx n-items))
(dissoc (dec n-items)))))
(= song-idx current-idx) (assoc :current-idx -1))))
;; constructor wrapper ;; constructor wrapper

View file

@ -66,6 +66,14 @@
(fn [_ _] (fn [_ _]
{:audio/toggle-play-pause nil})) {:audio/toggle-play-pause nil}))
(defn remove-song [{:keys [db]} [_ song-idx]]
(let [song-removed (update-in db [:audio :current-playlist] #(playlist/remove-song % song-idx))]
(cond-> {:db song-removed}
(nil? (playlist/current-song (get-in song-removed [:audio :current-playlist])))
(assoc :audio/stop nil))))
(rf/reg-event-fx :audio-player/remove-song remove-song)
(defn audio-update (defn audio-update
"Reacts to audio events fired by the HTML5 audio player and plays the next "Reacts to audio events fired by the HTML5 audio player and plays the next
track if necessary." track if necessary."

View file

@ -21,10 +21,10 @@
(r/as-element [:span.is-size-7.has-text-grey-lighter (r/as-element [:span.is-size-7.has-text-grey-lighter
[icon :elevator]])))) [icon :elevator]]))))
(defn song-actions [] (defn song-actions [{:keys [song idx]}]
;; TODO: Implement both of these ;; TODO: Implement both of these
[dropdown {:items [{:label "Remove from queue" [dropdown {:items [{:label "Remove from queue"
:event []} :event [:audio-player/remove-song idx]}
{:label "Go to source" {:label "Go to source"
:event []}]}]) :event []}]}])
@ -62,7 +62,8 @@
[:td.song-artist [artist-link song]] [:td.song-artist [artist-link song]]
[:td.song-title [song-link song idx]] [:td.song-title [song-link song idx]]
[:td.song-duration (helpers/format-duration (:duration song) :brief? true)] [:td.song-duration (helpers/format-duration (:duration song) :brief? true)]
[:td.song-actions.is-narrow [song-actions]]]) [:td.song-actions.is-narrow [song-actions {:song song
:idx idx}]]])
:on-sort-end :on-sort-end
(fn [{:keys [old-idx new-idx]}] (fn [{:keys [old-idx new-idx]}]

View file

@ -309,3 +309,33 @@
(is (= 3 (-> (playlist/set-current-song playlist 3) (is (= 3 (-> (playlist/set-current-song playlist 3)
(playlist/move-song 4 7) (playlist/move-song 4 7)
:current-idx)))))))) :current-idx))))))))
(deftest remove-song
(with-redefs [shuffle identity]
(testing "Should remove a single song from the playlist"
(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)
first-removed (playlist/remove-song playlist 0)
middle-removed (playlist/remove-song playlist 5)
last-removed (playlist/remove-song playlist 9)
song-not-in-list? (fn [song playlist]
(every? #(not (same-song? % song))
(vals (:items playlist))))]
(is (= 9 (count first-removed) (count middle-removed) (count last-removed)))
(is (song-not-in-list? (first queue) first-removed))
(is (same-song? (second queue) (get (:items first-removed) 0)))
(is (song-not-in-list? (nth queue 5) middle-removed))
(is (same-song? (nth queue 6) (get (:items middle-removed) 5)))
(is (song-not-in-list? (last queue) last-removed)))))
(testing "Should pause if the currently playing song is removed"
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-all :repeat-single]]
(let [n-songs 10
queue (song-queue n-songs)]
(is (nil? (-> (playlist/->playlist queue :repeat-mode repeat-mode :playback-mode playback-mode)
(playlist/set-current-song 5)
(playlist/remove-song 5)
(playlist/current-song)))))))))

View file

@ -27,3 +27,13 @@
(:current-idx))) (:current-idx)))
(str "for playback-mode " playback-mode " and repeat-mode " repeat-mode)) (str "for playback-mode " playback-mode " and repeat-mode " repeat-mode))
(is (contains? effects :audio/play)))))) (is (contains? effects :audio/play))))))
(deftest removing-currently-playing-song
(testing "Should stop all audio when removing the currently playing song"
(doseq [playback-mode [:linear :shuffled]
repeat-mode [:repeat-none :repeat-single :repeat-all]]
(let [n-songs 100
fixture {:db {:credentials fixtures/credentials
:audio {:current-playlist (playlist/->playlist (song-queue n-songs) :playback-mode playback-mode :repeat-mode repeat-mode)}}}]
(is (contains? (events/remove-song fixture [:audio/remove-song 0]) :audio/stop))
(is (not (contains? (events/remove-song fixture [:audio/remove-song 99]) :audio/stop)))))))