mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-06 18:33:38 +02:00
Start restructuring audio playback, add some tests for audio
Fixes #15 where audio was not stopped on logout
This commit is contained in:
parent
727d454871
commit
80225d46b1
10 changed files with 187 additions and 69 deletions
|
|
@ -20,8 +20,10 @@
|
|||
(doseq [event ["loadstart" "progress" "play" "timeupdate" "pause"]]
|
||||
(.addEventListener el event #(re-frame/dispatch [:audio/update (->status el)]))))
|
||||
|
||||
;; effects to be fired from event handlers
|
||||
|
||||
(re-frame/reg-fx
|
||||
:play-song
|
||||
:audio/play
|
||||
(fn [song-url]
|
||||
(when-not @audio
|
||||
(reset! audio (js/Audio.))
|
||||
|
|
@ -31,9 +33,74 @@
|
|||
(.play @audio)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:toggle-play-pause
|
||||
:audio/pause
|
||||
(fn [_]
|
||||
(let [a @audio]
|
||||
(some-> @audio .pause)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:audio/stop
|
||||
(fn [_]
|
||||
(when-let [audio @audio]
|
||||
(.pause audio)
|
||||
(set! (.-currentTime audio) 0))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:audio/toggle-play-pause
|
||||
(fn [_]
|
||||
(if-let [a @audio]
|
||||
(if (.-paused a)
|
||||
(.play a)
|
||||
(.pause a)))))
|
||||
|
||||
;; subscriptions
|
||||
|
||||
(defn summary
|
||||
"Returns all information about audio that we have"
|
||||
[db _]
|
||||
(:audio db))
|
||||
|
||||
(re-frame/reg-sub :audio/summary summary)
|
||||
|
||||
(defn current-song
|
||||
"Gives us information about the currently played song as presented by
|
||||
the airsonic api"
|
||||
[summary _]
|
||||
(:current-song summary))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:audio/current-song
|
||||
(fn [_ _] (re-frame/subscribe [:audio/summary]))
|
||||
current-song)
|
||||
|
||||
(defn playback-status
|
||||
"Gives us information about the most recently fired html 5 audio event"
|
||||
[summary _]
|
||||
(:playback-status summary))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:audio/playback-status
|
||||
(fn [_ _] (re-frame/subscribe [:audio/summary]))
|
||||
playback-status)
|
||||
|
||||
(defn is-playing?
|
||||
"Predicate to tell us whether we currently have audio output or not"
|
||||
[playback-status _]
|
||||
(and (not (:paused? playback-status))
|
||||
(not (:ended? playback-status))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:audio/is-playing?
|
||||
(fn [_ _] (re-frame/subscribe [:audio/current-playback-status]))
|
||||
is-playing?)
|
||||
|
||||
(comment
|
||||
;; NOTE: Not in use currently
|
||||
(defn current-playlist
|
||||
"Lists the complete playlist"
|
||||
[summary _]
|
||||
(:playlist summary))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:audio/current-playlist
|
||||
(fn [_ _] (re-frame/subscribe [:audio/summary]))
|
||||
current-playlist))
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@
|
|||
[::routes/login {} {:redirect (routes/encode-route redirect)}]
|
||||
[::routes/login])]
|
||||
:store nil
|
||||
:db (-> (merge (:db cofx) db/default-db)
|
||||
(dissoc :credentials))}))
|
||||
:db db/default-db
|
||||
:audio/stop nil}))
|
||||
|
||||
(re-frame/reg-event-fx ::logout logout)
|
||||
|
||||
|
|
@ -180,41 +180,40 @@
|
|||
; sets up the db, starts to play a song and adds the rest to a playlist
|
||||
::play-songs
|
||||
(fn [{:keys [db]} [_ songs song]]
|
||||
{:play-song (song-url db song)
|
||||
:db (-> db
|
||||
(assoc-in [:currently-playing :item] song)
|
||||
(assoc-in [:currently-playing :playlist] songs))}))
|
||||
{:audio/play (song-url db song)
|
||||
:db (-> (assoc-in db [:audio :current-song] song)
|
||||
(assoc-in [:audio :playlist] songs))}))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::next-song
|
||||
(fn [{:keys [db]} _]
|
||||
(let [playlist (-> db :currently-playing :playlist)
|
||||
current (-> db :currently-playing :item)
|
||||
next (first (rest (drop-while #(not= % current) playlist)))]
|
||||
(let [playlist (get-in db [:audio :playlist])
|
||||
current-song (get-in db [:audio :current-song])
|
||||
next (first (rest (drop-while #(not= % current-song) playlist)))]
|
||||
(when next
|
||||
{:play-song (song-url db next)
|
||||
:db (assoc-in db [:currently-playing :item] next)}))))
|
||||
{:audio/play (song-url db next)
|
||||
:db (assoc-in db [:audio :current-song] next)}))))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::previous-song
|
||||
(fn [{:keys [db]} _]
|
||||
(let [playlist (-> db :currently-playing :playlist)
|
||||
current (-> db :currently-playing :item)
|
||||
previous (last (take-while #(not= % current) playlist))]
|
||||
(let [playlist (get-in db [:audio :playlist])
|
||||
current-song (get-in db [:audio :current-song])
|
||||
previous (last (take-while #(not= % current-song) playlist))]
|
||||
(when previous
|
||||
{:play-song (song-url db previous)
|
||||
:db (assoc-in db [:currently-playing :item] previous)}))))
|
||||
{:audio/play (song-url db previous)
|
||||
:db (assoc-in db [:audio :current-song] previous)}))))
|
||||
|
||||
(re-frame/reg-event-fx
|
||||
::toggle-play-pause
|
||||
(fn [_ _]
|
||||
{:toggle-play-pause nil}))
|
||||
{:audio/toggle-play-pause 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)))
|
||||
; this is coming from HTML5 Audio events
|
||||
(assoc-in db [:audio :playback-status] status)))
|
||||
|
||||
;; ---
|
||||
;; routing
|
||||
|
|
|
|||
|
|
@ -47,21 +47,6 @@
|
|||
(fn [db _]
|
||||
(:response db)))
|
||||
|
||||
(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 _]
|
||||
(:currently-playing db)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
::is-playing?
|
||||
(fn [query-v _]
|
||||
[(re-frame/subscribe [::currently-playing])])
|
||||
(fn [[currently-playing] _]
|
||||
(let [status (:status currently-playing)]
|
||||
(and (not (:paused? status))
|
||||
(not (:ended? status))))))
|
||||
|
||||
;; user notifications
|
||||
|
||||
(defn notifications [db _] (:notifications db))
|
||||
|
|
|
|||
|
|
@ -67,9 +67,6 @@
|
|||
(let [notifications @(subscribe [::subs/notifications])
|
||||
is-booting? @(subscribe [::subs/is-booting?])
|
||||
[route-id params query] @(subscribe [::subs/current-route])]
|
||||
(println "route-id" route-id (case route-id
|
||||
::routes/login "::routes/login"
|
||||
"something else"))
|
||||
[:div
|
||||
[notification-list notifications]
|
||||
(if is-booting?
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
(ns airsonic-ui.views.bottom-bar
|
||||
(:require [re-frame.core :refer [dispatch subscribe]]
|
||||
[airsonic-ui.events :as events]
|
||||
[airsonic-ui.subs :as subs]
|
||||
[airsonic-ui.views.cover :refer [cover]]
|
||||
[airsonic-ui.views.icon :refer [icon]]))
|
||||
|
||||
;; currently playing / coming next / audio controls...
|
||||
|
||||
(defn current-song-info [{:keys [item status]}]
|
||||
(defn current-song-info [song status]
|
||||
[:article
|
||||
[:div (:artist item) " - " (:title item)]
|
||||
[:div (:artist song) " - " (:title song)]
|
||||
;; FIXME: Sometimes items don't have a duration
|
||||
[:progress.progress.is-tiny {:value (:current-time status)
|
||||
:max (:duration item)}]])
|
||||
:max (:duration song)}]])
|
||||
|
||||
(defn playback-controls [is-playing?]
|
||||
[:div.field.has-addons
|
||||
|
|
@ -25,22 +24,23 @@
|
|||
[icon icon-glyph]])
|
||||
buttons))])
|
||||
|
||||
(def logo-url "https://airsonic.github.io/airsonic-ui/assets/images/logo/airsonic-light-350x100.png")
|
||||
(def logo-url "https://airsonic.github.io/airsonic-ui/assets/images/logo/airsonic-light-350x100.png")
|
||||
|
||||
(defn bottom-bar []
|
||||
(let [currently-playing @(subscribe [::subs/currently-playing])
|
||||
is-playing? @(subscribe [::subs/is-playing?])]
|
||||
(let [current-song @(subscribe [:audio/current-song])
|
||||
playback-status @(subscribe [:audio/playback-status])
|
||||
is-playing? @(subscribe [:audio/is-playing?])]
|
||||
[:nav.navbar.is-fixed-bottom.playback-area
|
||||
[:div.navbar-brand
|
||||
[:div.navbar-item
|
||||
[:img {:src logo-url}]]]
|
||||
[:div.navbar-menu.is-active
|
||||
(if currently-playing
|
||||
(if current-song
|
||||
;; show song info
|
||||
[:section.level.audio-interaction
|
||||
[:div.level-left>article.media
|
||||
[:div.media-left [cover (:item currently-playing) 48]]
|
||||
[:div.media-content [current-song-info currently-playing]]]
|
||||
[:div.media-left [cover current-song 48]]
|
||||
[:div.media-content [current-song-info current-song playback-status]]]
|
||||
[:div.level-right [playback-controls is-playing?]]]
|
||||
;; not playing anything
|
||||
[:p.idle-notification "Currently no song selected"])]]))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue