mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-06 18:33:38 +02:00
Add currently playing bar
This commit is contained in:
parent
54757930d7
commit
19aa7038b3
4 changed files with 70 additions and 6 deletions
|
|
@ -3,11 +3,33 @@
|
||||||
|
|
||||||
;; TODO: Manage multiple songs, buffering, stopping, progress notification...
|
;; TODO: Manage multiple songs, buffering, stopping, progress notification...
|
||||||
|
|
||||||
(def current-audio (atom nil))
|
(defonce current-audio (atom nil))
|
||||||
|
|
||||||
|
(defn ->status
|
||||||
|
"Takes an audio object and returns a map describing its current status"
|
||||||
|
[elem]
|
||||||
|
{:ended? (.-ended elem)
|
||||||
|
:loop? (.-loop elem)
|
||||||
|
:muted? (.-muted elem)
|
||||||
|
:paused? (.-paused elem)
|
||||||
|
:current-src (.-currentSrc elem)
|
||||||
|
:current-time (.-currentTime elem)})
|
||||||
|
|
||||||
|
; explanation of these events: https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics
|
||||||
|
(defn attach-listeners! [el]
|
||||||
|
(doseq [event ["loadstart" "progress" "play" "timeupdate" "pause"]]
|
||||||
|
(.addEventListener el event #(re-frame/dispatch [:audio-update (->status el)]))))
|
||||||
|
|
||||||
|
|
||||||
(re-frame/reg-fx
|
(re-frame/reg-fx
|
||||||
:play-song
|
:play-song
|
||||||
(fn [song-url]
|
(fn [song-url]
|
||||||
(let [audio (js/Audio. song-url)]
|
(let [audio (js/Audio. song-url)]
|
||||||
(reset! current-audio audio)
|
(reset! current-audio audio)
|
||||||
|
(attach-listeners! audio)
|
||||||
(.play audio))))
|
(.play audio))))
|
||||||
|
|
||||||
|
(re-frame/reg-fx
|
||||||
|
:pause-song
|
||||||
|
(fn [_]
|
||||||
|
(some-> @current-audio .pause)))
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,7 @@
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
::api-success
|
::api-success
|
||||||
(fn [db [_ k response]]
|
(fn [db [_ k response]]
|
||||||
(println "api response" response)
|
; we "unwrap" the responses
|
||||||
;; we "unwrap" the responses
|
|
||||||
(assoc db :response (-> response :subsonic-response k))))
|
(assoc db :response (-> response :subsonic-response k))))
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db
|
||||||
|
|
@ -67,10 +66,23 @@
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx
|
||||||
::play-song
|
::play-song
|
||||||
(fn [{:keys [db]} [_ song]]
|
(fn [{:keys [db]} [_ song]]
|
||||||
|
; sets up the db and starts to play a song
|
||||||
(let [song-url (api/url "stream" (merge {:id (:id song)}
|
(let [song-url (api/url "stream" (merge {:id (:id song)}
|
||||||
(:login db)))]
|
(:login db)))]
|
||||||
(println "Requesting to stream song at" song-url)
|
{:play-song song-url
|
||||||
{:play-song song-url})))
|
:db (assoc-in db [:currently-playing :item] song)})))
|
||||||
|
|
||||||
|
(re-frame/reg-event-fx
|
||||||
|
::pause-song
|
||||||
|
(fn [_ _]
|
||||||
|
; pauses the current song
|
||||||
|
{:pause-song nil}))
|
||||||
|
|
||||||
|
(re-frame/reg-event-db
|
||||||
|
:audio-update
|
||||||
|
(fn [db [_ status]]
|
||||||
|
; we receive this from the player once it's playing
|
||||||
|
(assoc-in db [:currently-playing :status] status)))
|
||||||
|
|
||||||
;; routing
|
;; routing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,3 +23,9 @@
|
||||||
::current-content
|
::current-content
|
||||||
(fn [db]
|
(fn [db]
|
||||||
(-> db :response)))
|
(-> db :response)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
; returns info on the current song as is (basically the metadata you can read from the file system)
|
||||||
|
::currently-playing
|
||||||
|
(fn [db]
|
||||||
|
(-> db :currently-playing)))
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,29 @@
|
||||||
[:h2 (str (:artist content) " - " (:name content))]
|
[:h2 (str (:artist content) " - " (:name content))]
|
||||||
[song-list (:song content)]])
|
[song-list (:song content)]])
|
||||||
|
|
||||||
|
;; currently playing / coming next / audio controls...
|
||||||
|
|
||||||
|
(defn current-song-info [{:keys [item status]}]
|
||||||
|
[:div
|
||||||
|
[:b "Currently playing: "]
|
||||||
|
[:div (:artist item) " - " (:title item)]
|
||||||
|
[:div (:current-time status) "s / " (:duration item) "s"]])
|
||||||
|
|
||||||
|
(defn playback-controls []
|
||||||
|
[:div
|
||||||
|
[:button "previous"]
|
||||||
|
[:button "play / pause"]
|
||||||
|
[:button "next"]
|
||||||
|
[:label [:input {:type "checkbox"}] "shuffle"]
|
||||||
|
[:label [:input {:type "checkbox"}] "repeat"]])
|
||||||
|
|
||||||
|
(defn bottom-bar []
|
||||||
|
[:div
|
||||||
|
(if-let [currently-playing @(re-frame/subscribe [::subs/currently-playing])]
|
||||||
|
[current-song-info currently-playing]
|
||||||
|
[:span "Currently no song selected"])
|
||||||
|
[playback-controls]])
|
||||||
|
|
||||||
;; putting everything together
|
;; putting everything together
|
||||||
|
|
||||||
(defn app [route params query]
|
(defn app [route params query]
|
||||||
|
|
@ -73,7 +96,8 @@
|
||||||
(case route
|
(case route
|
||||||
::routes/main [album-list content]
|
::routes/main [album-list content]
|
||||||
::routes/album-view [album-detail content])
|
::routes/album-view [album-detail content])
|
||||||
[:a {:on-click #(re-frame/dispatch [::events/initialize-db]) :href "#"} "Logout"]]))
|
[:a {:on-click #(re-frame/dispatch [::events/initialize-db]) :href "#"} "Logout"]
|
||||||
|
[bottom-bar]]))
|
||||||
|
|
||||||
(defn main-panel []
|
(defn main-panel []
|
||||||
(let [[route params query] @(re-frame/subscribe [::subs/current-route])]
|
(let [[route params query] @(re-frame/subscribe [::subs/current-route])]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue