aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Ángel Moreno <mail@migalmoreno.com>2023-10-30 00:55:27 +0100
committerMiguel Ángel Moreno <mail@migalmoreno.com>2023-10-30 00:55:27 +0100
commite9b089fce0394ce2e9ab7997a079bc22374e235a (patch)
tree494ae752f9a9164a2ed218563c6927d8dc60ea7f /src
parentbcd3d52bf9f5da7bdd5f449515334816feff542f (diff)
feat(frontend): add stream playback events
Diffstat (limited to 'src')
-rw-r--r--src/frontend/tubo/components/audio_player.cljs29
-rw-r--r--src/frontend/tubo/events.cljs45
-rw-r--r--src/frontend/tubo/subs.cljs14
3 files changed, 69 insertions, 19 deletions
diff --git a/src/frontend/tubo/components/audio_player.cljs b/src/frontend/tubo/components/audio_player.cljs
index f4945c8..7cc5fb1 100644
--- a/src/frontend/tubo/components/audio_player.cljs
+++ b/src/frontend/tubo/components/audio_player.cljs
@@ -9,8 +9,7 @@
(defn player
[]
- (let [!autoplay? (r/atom true)
- !volume-level (r/atom 100)]
+ (let [!autoplay? (r/atom true)]
(fn []
(let [media-queue @(rf/subscribe [:media-queue])
media-queue-pos @(rf/subscribe [:media-queue-pos])
@@ -22,16 +21,18 @@
is-window-visible @(rf/subscribe [:is-window-visible])
loop-file? @(rf/subscribe [:loop-file])
loop-playlist? @(rf/subscribe [:loop-playlist])
+ volume-level @(rf/subscribe [:volume-level])
+ muted? @(rf/subscribe [:muted])
!elapsed-time @(rf/subscribe [:elapsed-time])
!player @(rf/subscribe [:player])]
(when show-audio-player?
- [:div.sticky.bottom-0.z-40.bg-white.dark:bg-neutral-900.px-3.py-5.sm:p-5.absolute.box-border.m-0
+ [:div.sticky.bottom-0.z-40.bg-white.dark:bg-neutral-900.p-3.sm:p-5.absolute.box-border.m-0
{:style {:borderTop (str "2px solid " service-color) :display (when show-media-queue? "none")}}
[:div.flex.items-center.justify-between
[:div.flex.items-center
[:div {:style {:height "40px" :width "70px" :maxWidth "70px" :minWidth "70px"}}
[:img.min-h-full.max-h-full.object-cover.min-w-full.max-w-full.w-full {:src thumbnail-url}]]
- [:div.flex.flex-col.px-4
+ [:div.flex.flex-col.px-2
[:a.text-xs.line-clamp-1
{:href (rfe/href :tubo.routes/stream nil {:url url})} name]
[:a.text-xs.pt-2.text-neutral-600.dark:text-neutral-300.line-clamp-1
@@ -43,7 +44,7 @@
:on-time-update #(when (and @!player (> (.-readyState @!player) 0))
(reset! !elapsed-time (.-currentTime @!player)))
:on-loaded-data #(when (and @!player (> (.-readyState @!player) 0))
- (.play @!player)
+ (rf/dispatch [::events/start-playback @!player])
(set! (.-currentTime @!player) @!elapsed-time))
:on-ended #(when (and @!player (> (.-readyState @!player) 0))
(let [idx (if (< (+ media-queue-pos 1) (count media-queue))
@@ -53,7 +54,7 @@
(reset! !elapsed-time 0)
(when (and (not is-window-visible) loop-playlist?)
(set! (.-src @!player) (:stream (nth media-queue idx)))
- (.play @!player))))}]]
+ (rf/dispatch [::events/start-playback @!player]))))}]]
[:div.flex
[:button:focus:ring-transparent.mx-2.cursor-pointer
{:on-click #(rf/dispatch [::events/toggle-media-queue])}
@@ -71,10 +72,7 @@
{:on-click #(set! (.-currentTime @!player) (- @!elapsed-time 5))}
[:i.fa-solid.fa-backward]]
[:button.focus:outline-none.mx-2
- {:on-click #(when-let [player @!player]
- (if (.-paused player)
- (.play player)
- (.pause player)))}
+ {:on-click #(rf/dispatch [::events/start-playback @!player])}
(if @!player
(if show-audio-player-loading?
[loading/loading-icon service-color "text-1xl"]
@@ -119,19 +117,16 @@
{:style {:color (when loop-playlist? service-color)}}]]
[:div.hidden.ml:flex.items-center
[:button.focus:outline-none.mx-2
- {:on-click #(when-let [player @!player]
- (set! (.-muted player) (not (.-muted player))))}
- (if (and @!player (.-muted @!player))
+ {:on-click #(rf/dispatch [::events/toggle-mute @!player])}
+ (if (or (and @!player muted?))
[:i.fa-solid.fa-volume-xmark]
[:i.fa-solid.fa-volume-low])]
[:input.w-20.bg-gray-200.rounded-lg.cursor-pointer.focus:outline-none.h-1.range-sm.mx-2
{:type "range"
- :on-input #(do (reset! !volume-level (.. % -target -value))
- (and @!player (> (.-readyState @!player) 0)
- (set! (.-volume @!player) (/ @!volume-level 100))))
+ :on-input #(rf/dispatch [::events/change-volume-level (.. % -target -value) @!player])
:style {:accentColor service-color}
:max 100
- :value (if (and @!player (.-muted @!player)) 0 @!volume-level)}]]]
+ :value volume-level}]]]
[:div.mx-2
[:i.fa-solid.fa-close.cursor-pointer
{:on-click (fn []
diff --git a/src/frontend/tubo/events.cljs b/src/frontend/tubo/events.cljs
index 157c509..cebd707 100644
--- a/src/frontend/tubo/events.cljs
+++ b/src/frontend/tubo/events.cljs
@@ -26,6 +26,8 @@
:loop-playlist (if (nil? loop-playlist) true loop-playlist)
:media-queue (if (nil? media-queue) [] media-queue)
:media-queue-pos (if (nil? media-queue-pos) 0 media-queue-pos)
+ :volume-level (if (nil? volume-level) 100 volume-level)
+ :muted (if (nil? muted) false muted)
:current-match nil
:show-audio-player (if (nil? show-audio-player) false show-audio-player)
:settings
@@ -55,6 +57,26 @@
(fn [_ _]
{::history-back! nil}))
+(rf/reg-fx
+ ::player-volume
+ (fn [{:keys [player volume]}]
+ (when (and player (> (.-readyState player) 0))
+ (set! (.-volume player) (/ volume 100)))))
+
+(rf/reg-fx
+ ::player-mute
+ (fn [{:keys [player muted?]}]
+ (when (and player (> (.-readyState player) 0))
+ (set! (.-muted player) muted?))))
+
+(rf/reg-fx
+ ::player-playback
+ (fn [{:keys [player]}]
+ (when (and player (> (.-readyState player) 0))
+ (if (.-paused player)
+ (.play player)
+ (.pause player)))))
+
(rf/reg-event-fx
::toggle-mobile-nav
(fn [{:keys [db]} _]
@@ -75,6 +97,29 @@
:store (assoc store :loop-file (not (:loop-file store)))}))
(rf/reg-event-fx
+ ::change-volume-level
+ [(rf/inject-cofx :store)]
+ (fn [{:keys [db store]} [_ value player]]
+ {:db (assoc db :volume-level value)
+ :store (assoc store :volume-level value)
+ ::player-volume {:player player :volume value}}))
+
+(rf/reg-event-fx
+ ::start-playback
+ (fn [{:keys [db]} [_ player]]
+ {::player-playback {:player player}
+ ::player-volume {:player player :volume (:volume-level db)}
+ ::player-mute {:player player :muted? (:muted db)}}))
+
+(rf/reg-event-fx
+ ::toggle-mute
+ [(rf/inject-cofx :store)]
+ (fn [{:keys [db store]} [_ player]]
+ {:db (assoc db :muted (not (:muted db)))
+ :store (assoc store :muted (not (:muted store)))
+ ::player-mute {:player player :muted? (not (:muted db))}}))
+
+(rf/reg-event-fx
::toggle-loop-playlist
[(rf/inject-cofx :store)]
(fn [{:keys [db store]} _]
diff --git a/src/frontend/tubo/subs.cljs b/src/frontend/tubo/subs.cljs
index ed51d60..9f684e1 100644
--- a/src/frontend/tubo/subs.cljs
+++ b/src/frontend/tubo/subs.cljs
@@ -17,8 +17,8 @@
(.addEventListener js/window "touchmove" compute-scroll-distance)
a))
-(def !elapsed-time (r/atom 0))
-(def !player (r/atom nil))
+(defonce !elapsed-time (r/atom 0))
+(defonce !player (r/atom nil))
(rf/reg-sub
:is-window-visible
@@ -41,6 +41,16 @@
!player))
(rf/reg-sub
+ :volume-level
+ (fn [db _]
+ (:volume-level db)))
+
+(rf/reg-sub
+ :muted
+ (fn [db _]
+ (:muted db)))
+
+(rf/reg-sub
:http-response
(fn [db _]
(:http-response db)))