mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-07 02:33:39 +02:00
Implement set-current-track
This commit is contained in:
parent
b529b2fabe
commit
4043eb48e7
6 changed files with 67 additions and 32 deletions
|
|
@ -48,9 +48,13 @@
|
||||||
|
|
||||||
(defrecord Playlist [items current-idx playback-mode repeat-mode]
|
(defrecord Playlist [items current-idx playback-mode repeat-mode]
|
||||||
cljs.core/ICounted
|
cljs.core/ICounted
|
||||||
(-count [this]
|
(-count [_]
|
||||||
(count items))
|
(count items))
|
||||||
|
|
||||||
|
cljs.core/ISequential
|
||||||
|
cljs.core/ISeqable
|
||||||
|
(-seq [_] items)
|
||||||
|
|
||||||
IPlaylist
|
IPlaylist
|
||||||
(current-song [_]
|
(current-song [_]
|
||||||
(get items current-idx))
|
(get items current-idx))
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,17 @@
|
||||||
:audio-player/previous-song
|
:audio-player/previous-song
|
||||||
(fn [{:keys [db]} _]
|
(fn [{:keys [db]} _]
|
||||||
(let [db (update-in db [:audio :current-playlist] playlist/previous-song)
|
(let [db (update-in db [:audio :current-playlist] playlist/previous-song)
|
||||||
prev (playlist/current-song (get-in db [:audio :current-playlist]))]
|
song (playlist/current-song (get-in db [:audio :current-playlist]))]
|
||||||
{:db db
|
{:db db
|
||||||
:audio/play (api/stream-url (:credentials db) prev)})))
|
:audio/play (api/stream-url (:credentials db) song)})))
|
||||||
|
|
||||||
|
(defn set-current-song [{:keys [db]} [_ idx]]
|
||||||
|
(let [db (update-in db [:audio :current-playlist] playlist/set-current-song idx)
|
||||||
|
song (playlist/current-song (get-in db [:audio :current-playlist]))]
|
||||||
|
{:db db
|
||||||
|
:audio/play (api/stream-url (:credentials db) song)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :audio-player/set-current-song set-current-song)
|
||||||
|
|
||||||
(rf/reg-event-db
|
(rf/reg-event-db
|
||||||
:audio-player/enqueue-next
|
:audio-player/enqueue-next
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
[reagent.core :as r]
|
[reagent.core :as r]
|
||||||
["react-sortable-hoc" :refer [SortableHandle]]
|
["react-sortable-hoc" :refer [SortableHandle]]
|
||||||
[airsonic-ui.helpers :as helpers]
|
[airsonic-ui.helpers :as helpers]
|
||||||
[airsonic-ui.views.song :as song]
|
|
||||||
[airsonic-ui.views.icon :refer [icon]]
|
[airsonic-ui.views.icon :refer [icon]]
|
||||||
[airsonic-ui.components.sortable.views :as sortable]
|
[airsonic-ui.components.sortable.views :as sortable]
|
||||||
[airsonic-ui.routes :as routes]))
|
[airsonic-ui.routes :as routes]))
|
||||||
|
|
@ -39,6 +38,12 @@
|
||||||
[:a {:href (routes/url-for ::routes/artist.detail {:id id})} artist]
|
[:a {:href (routes/url-for ::routes/artist.detail {:id id})} artist]
|
||||||
artist))
|
artist))
|
||||||
|
|
||||||
|
(defn song-link [song idx]
|
||||||
|
[:a
|
||||||
|
{:href "#"
|
||||||
|
:on-click (helpers/muted-dispatch [:audio-player/set-current-song idx])}
|
||||||
|
(:title song)])
|
||||||
|
|
||||||
(defn song-table [{:keys [songs current-song]}]
|
(defn song-table [{:keys [songs current-song]}]
|
||||||
[:table.song-listing-table.table.is-fullwidth
|
[:table.song-listing-table.table.is-fullwidth
|
||||||
[sortable/sortable-component
|
[sortable/sortable-component
|
||||||
|
|
@ -46,12 +51,11 @@
|
||||||
:items songs
|
:items songs
|
||||||
|
|
||||||
:render-item
|
:render-item
|
||||||
(fn [{song :value}]
|
(fn [{[idx song] :value}]
|
||||||
[(if (= (:id song) (:id current-song)) :tr.is-playing :tr)
|
[(if (= (:id song) (:id current-song)) :tr.is-playing :tr)
|
||||||
[:td.sort-handle.is-narrow [:> SortHandle]]
|
[:td.sort-handle.is-narrow [:> SortHandle]]
|
||||||
[:td.song-artist [artist-link song]]
|
[:td.song-artist [artist-link song]]
|
||||||
[:td.song-title (:title song)]
|
[:td.song-title [song-link song idx]]
|
||||||
[:td.meta>code (str (meta song))]
|
|
||||||
[: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]]])
|
||||||
|
|
||||||
|
|
@ -62,10 +66,10 @@
|
||||||
(defn current-queue []
|
(defn current-queue []
|
||||||
[:section.section>div.container
|
[:section.section>div.container
|
||||||
[:h1.title "Current Queue"]
|
[:h1.title "Current Queue"]
|
||||||
(let [current-queue @(subscribe [:audio/current-queue])
|
(let [current-playlist @(subscribe [:audio/current-playlist])
|
||||||
current-song @(subscribe [:audio/current-song])]
|
current-song @(subscribe [:audio/current-song])]
|
||||||
(if (some? current-queue)
|
(if (empty? current-playlist)
|
||||||
[song-table {:songs current-queue
|
|
||||||
:current-song current-song}]
|
|
||||||
[:p "You are currently not playing anything. Use the search or go to your "
|
[:p "You are currently not playing anything. Use the search or go to your "
|
||||||
[:a {:href (routes/url-for ::routes/library)} "Library"] " to start playing some music."]))])
|
[:a {:href (routes/url-for ::routes/library)} "Library"] " to start playing some music."]
|
||||||
|
[song-table {:songs (:items current-playlist)
|
||||||
|
:current-song current-song}]))])
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,11 @@
|
||||||
(:require [cljs.test :refer [deftest testing is]]
|
(:require [cljs.test :refer [deftest testing is]]
|
||||||
[airsonic-ui.audio.playlist :as playlist]
|
[airsonic-ui.audio.playlist :as playlist]
|
||||||
[airsonic-ui.fixtures :as fixtures]
|
[airsonic-ui.fixtures :as fixtures]
|
||||||
[airsonic-ui.test-helpers :as helpers]
|
[airsonic-ui.test-helpers :refer [song song-queue]]
|
||||||
[debux.cs.core :refer-macros [dbg]]))
|
#_[debux.cs.core :refer-macros [dbg]]))
|
||||||
|
|
||||||
(enable-console-print!)
|
(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]
|
|
||||||
(let [r-int (atom 0)]
|
|
||||||
(with-redefs [rand-int #(mod (swap! r-int inc) %1)]
|
|
||||||
(repeatedly n song))))
|
|
||||||
|
|
||||||
(def fixture
|
(def fixture
|
||||||
{:audio {:current-song fixtures/song
|
{:audio {:current-song fixtures/song
|
||||||
:playlist (song-queue 20)
|
:playlist (song-queue 20)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,29 @@
|
||||||
(ns airsonic-ui.components.audio-player.events-test
|
(ns airsonic-ui.components.audio-player.events-test
|
||||||
(:require [cljs.test :refer-macros [deftest testing is]]
|
(:require [cljs.test :refer-macros [deftest testing is]]
|
||||||
[airsonic-ui.test-helpers :refer [dispatches?]]
|
[airsonic-ui.audio.core :as audio]
|
||||||
|
[airsonic-ui.audio.playlist :as playlist]
|
||||||
|
[airsonic-ui.fixtures :as fixtures]
|
||||||
|
[airsonic-ui.test-helpers :refer [dispatches? song-queue]]
|
||||||
[airsonic-ui.components.audio-player.events :as events]))
|
[airsonic-ui.components.audio-player.events :as events]))
|
||||||
|
|
||||||
|
|
||||||
(deftest song-has-ended
|
(deftest song-has-ended
|
||||||
(testing "Should play the next song when current song has ended"
|
(testing "Should play the next song when current song has ended"
|
||||||
(is (not (dispatches? (events/audio-update {} [:audio/update {:ended? false}]) :audio-player/next-song)))
|
(is (not (dispatches? (events/audio-update {} [:audio/update {:ended? false}]) :audio-player/next-song)))
|
||||||
(is (dispatches? (events/audio-update {} [:audio/update {:ended? true}]) :audio-player/next-song))))
|
(is (dispatches? (events/audio-update {} [:audio/update {:ended? true}]) :audio-player/next-song))))
|
||||||
|
|
||||||
|
(deftest changing-current-song
|
||||||
|
(testing "Should correctly set the current song index"
|
||||||
|
(doseq [playback-mode [:linear :shuffled]
|
||||||
|
repeat-mode [:repeat-none :repeat-single :repeat-all]]
|
||||||
|
(let [n-songs 100
|
||||||
|
next-idx (rand-int n-songs)
|
||||||
|
fixture {:db {:credentials fixtures/credentials
|
||||||
|
:audio {:current-playlist (playlist/->playlist (song-queue n-songs) :playback-mode playback-mode :repeat-mode repeat-mode)}}}
|
||||||
|
effects (events/set-current-song fixture [:audio/set-current-song next-idx])]
|
||||||
|
(is (= next-idx
|
||||||
|
(-> (:db effects)
|
||||||
|
(audio/summary [:audio/summary])
|
||||||
|
(audio/current-playlist [:audio/current-playlist])
|
||||||
|
(:current-idx)))
|
||||||
|
(str "for playback-mode " playback-mode " and repeat-mode " repeat-mode))
|
||||||
|
(is (contains? effects :audio/play))))))
|
||||||
|
|
|
||||||
|
|
@ -17,3 +17,19 @@
|
||||||
(from arr #(-> (str 0 (.toString % 16))
|
(from arr #(-> (str 0 (.toString % 16))
|
||||||
(.substr -2)))
|
(.substr -2)))
|
||||||
(join "")))))
|
(join "")))))
|
||||||
|
|
||||||
|
(defn song []
|
||||||
|
(hash-map :id (rand-int 9999)
|
||||||
|
:coverArt (rand-int 9999)
|
||||||
|
:year (+ 1900 (rand-int 118))
|
||||||
|
:artist (rand-str)
|
||||||
|
:artistId (rand-int 100000)
|
||||||
|
:title (rand-str)
|
||||||
|
:album (rand-str)))
|
||||||
|
|
||||||
|
(defn song-queue
|
||||||
|
"Generates a seq of n different songs"
|
||||||
|
[n]
|
||||||
|
(let [r-int (atom 0)]
|
||||||
|
(with-redefs [rand-int #(mod (swap! r-int inc) %1)]
|
||||||
|
(repeatedly n song))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue