From 8c3b96c741ce99326d86afebe74787266884eb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20Schl=C3=BCter?= Date: Mon, 20 Aug 2018 11:26:26 +0200 Subject: [PATCH] Add functions to enqueue songs --- src/cljs/airsonic_ui/audio/playlist.cljs | 14 ++-- .../cljs/airsonic_ui/audio/playlist_test.cljs | 66 +++++++++++++++++-- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/cljs/airsonic_ui/audio/playlist.cljs b/src/cljs/airsonic_ui/audio/playlist.cljs index c9ed4fc..18f19a1 100644 --- a/src/cljs/airsonic_ui/audio/playlist.cljs +++ b/src/cljs/airsonic_ui/audio/playlist.cljs @@ -2,7 +2,8 @@ "Implements playlist queues that support different kinds of repetition and song ordering." (:refer-clojure :exclude [peek]) - (:require [airsonic-ui.utils.helpers :refer [find-where]])) + (:require [airsonic-ui.utils.helpers :refer [find-where]] + [debux.cs.core :refer-macros [dbg]])) (defrecord Playlist [queue playback-mode repeat-mode] cljs.core/ICounted @@ -114,9 +115,12 @@ (set-current-song playlist (mod (dec (:order current-song)) (count playlist))))))) (defn enqueue-last [playlist song] - ;; TODO: Implementation - ) + (let [highest-order (last (sort (map :order (:queue playlist))))] + (update playlist :queue conj (assoc song :order (inc highest-order))))) (defn enqueue-next [playlist song] - ;; TODO: Implementation - ) + (let [[_ current-song] (find-where :currently-playing? (:queue playlist))] + (update playlist :queue + (fn [queue] + (-> (mapv #(if (> (:order %) (:order current-song)) (update % :order inc) %) queue) + (conj (assoc song :order (inc (:order current-song))))))))) diff --git a/test/cljs/airsonic_ui/audio/playlist_test.cljs b/test/cljs/airsonic_ui/audio/playlist_test.cljs index f168f7c..f7778f2 100644 --- a/test/cljs/airsonic_ui/audio/playlist_test.cljs +++ b/test/cljs/airsonic_ui/audio/playlist_test.cljs @@ -8,16 +8,21 @@ (enable-console-print!) +(defn- song [] + (hash-map :id (rand-int 9999) + :coverArt (rand-int 9999) + :year (+ 1900 (rand-int 118)) + :artist (helpers/rand-str) + :artistId (rand-int 100000) + :title (helpers/rand-str) + :album (helpers/rand-str))) + (defn- song-queue "Generates a seq of n different songs" [n] - (repeatedly n #(hash-map :id (rand-int 9999) - :coverArt (rand-int 9999) - :year (+ 1900 (rand-int 118)) - :artist (helpers/rand-str) - :artistId (rand-int 100000) - :title (helpers/rand-str) - :album (helpers/rand-str)))) + (let [r-int (atom 0)] + (with-redefs [rand-int #(mod (swap! r-int inc) %1)] + (repeatedly n song)))) (def fixture {:audio {:current-song fixtures/song @@ -233,3 +238,50 @@ (playlist/peek))] (is (not (nil? next-track))) (is (not (same-song? current-track next-track)))))) + +(deftest enqueue-last + (testing "Should make sure the song is played last" + (doseq [playback-mode '(:playback-mode/linear :playback-mode/shuffled) + repeat-mode '(:repeat-mode/none :repeat-mode/all)] + (let [length 5, queue (song-queue length) + playlist (with-redefs [shuffle identity] + (playlist/->playlist queue 0 playback-mode repeat-mode)) + played-back (->> (iterate playlist/next-song playlist) + (take (dec length)) + (map #(:id (playlist/peek %))) + (set)) + to-enqueue (song) + playlist' (playlist/enqueue-last playlist to-enqueue)] + (is (nil? (played-back (-> (->> (iterate playlist/next-song playlist') + (map playlist/peek)) + (nth length) + (:id)))) + (str "for " playback-mode ", " repeat-mode))))) + (testing "Should not change the order of the songs already in queue" + (doseq [playback-mode '(:playback-mode/linear :playback-mode/shuffled) + repeat-mode '(:repeat-mode/none :repeat-mode/all)] + (let [length 5, queue (song-queue length) + playlist (playlist/->playlist queue 0 playback-mode repeat-mode) + ;; FIXME: Playlists should just start with order 0, basta + [first-song-idx _] (find-where #(= 0 (:order %)) (:queue playlist)) + playlist (playlist/set-current-song playlist first-song-idx) + played-back-songs (fn played-back-songs [playlist] + (->> (iterate playlist/next-song playlist) + (take length) + (map playlist/peek) + (map :order))) + played-back (played-back-songs playlist) + played-back' (played-back-songs (playlist/enqueue-last playlist (song)))] + (is (= played-back played-back') + (str "for " playback-mode ", " repeat-mode)))))) + +(deftest enqueue-next + (testing "Should play the song after the currently playing song" + (doseq [playback-mode '(:playback-mode/linear :playback-mode/shuffled) + repeat-mode '(:repeat-mode/none :repeat-mode/all)] + (let [length 5, queue (song-queue length) + playlist (playlist/->playlist queue 0 playback-mode repeat-mode) + next-song (song)] + (is (same-song? next-song (-> (playlist/enqueue-next playlist next-song) + (playlist/next-song) + (playlist/peek))))))))