mirror of
https://github.com/heyarne/airsonic-ui.git
synced 2026-05-07 02:33:39 +02:00
Implement always-visible volume controls
This commit is contained in:
parent
058b8377a8
commit
054e55f8b6
4 changed files with 91 additions and 10 deletions
|
|
@ -23,7 +23,8 @@
|
|||
:current-src (.-currentSrc elem)
|
||||
:current-time (.-currentTime elem)
|
||||
:seekable (normalize-time-ranges (.-seekable elem))
|
||||
:buffered (normalize-time-ranges (.-buffered elem))})
|
||||
:buffered (normalize-time-ranges (.-buffered elem))
|
||||
:volume (.-volume elem)})
|
||||
|
||||
; explanation of these events: https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery/Cross-browser_audio_basics
|
||||
|
||||
|
|
@ -71,6 +72,11 @@
|
|||
(set! (. @audio -currentTime)
|
||||
(* percentage duration))))
|
||||
|
||||
(rf/reg-fx
|
||||
:audio/set-volume
|
||||
(fn [percentage]
|
||||
(set! (. @audio -volume) percentage)))
|
||||
|
||||
;; subscriptions
|
||||
|
||||
(defn summary
|
||||
|
|
|
|||
|
|
@ -67,3 +67,9 @@
|
|||
(fn [{:keys [db]} [_ percentage]]
|
||||
(let [duration (:duration (playlist/peek (get-in db [:audio :playlist])))]
|
||||
{:audio/seek [percentage duration]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:audio-player/set-volume
|
||||
(fn [{:keys [db]} [_ percentage]]
|
||||
{:db (assoc-in db [:audio :playback-status :volume] percentage)
|
||||
:audio/set-volume percentage}))
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
[:span.song-title (:title song)]]]])
|
||||
|
||||
(defn playback-controls [is-playing?]
|
||||
[:div.playback-controls
|
||||
[:div.button-controls.playback-controls
|
||||
[:div.field.has-addons
|
||||
(let [buttons [[:media-step-backward :audio-player/previous-song]
|
||||
[(if is-playing? :media-pause :media-play) :audio-player/toggle-play-pause]
|
||||
|
|
@ -78,19 +78,46 @@
|
|||
(second))]
|
||||
(h/muted-dispatch [:audio-player/set-repeat-mode next-mode])))
|
||||
|
||||
(defn set-volume [ev]
|
||||
(let [y-ratio (/ (.. ev -nativeEvent -offsetY)
|
||||
(.. ev -target getBoundingClientRect -height))]
|
||||
(dispatch [:audio-player/set-volume (- 1 y-ratio)])))
|
||||
|
||||
(defn volume-controls [playback-status]
|
||||
(let [y-pos (* (- 1 (:volume playback-status)) 100)]
|
||||
[:div.button-controls.volume-controls
|
||||
[:div.button-menu
|
||||
[:svg.volume-bar {:width "100%", :height "100%"}
|
||||
;; the translate(...) makes the 1px rects look smoother
|
||||
[:g {:transform "translate(-0.5,0)"}
|
||||
;; background line
|
||||
[:rect.inactive {:x "50%", :y 0, :width 1, :height "100%"}]
|
||||
;; below are the line and circle that show the current volume
|
||||
[:rect.active {:x "50%", :y (str y-pos "%"),
|
||||
:width 1, :height (str (- 100 y-pos) "%")}]]
|
||||
[:circle.active {:cx "50%", :cy (str y-pos "%"), :r 3}]
|
||||
[:rect.click-dummy {:x 0, :y 0, :width "100%", :height "100%"
|
||||
:on-mouse-down set-volume
|
||||
:on-mouse-up set-volume
|
||||
;; fire the on-mouse-move only when left mouse button is pressed
|
||||
:on-mouse-move #(when (= 1 (.-buttons %))
|
||||
(set-volume %))}]]]
|
||||
[:p.control>button.button.is-light
|
||||
[icon :volume-high]]]))
|
||||
|
||||
(defn playback-mode-controls [playlist]
|
||||
(let [{:keys [repeat-mode playback-mode]} playlist
|
||||
button :p.control>button.button.is-light
|
||||
shuffle-button (h/add-classes button (when (= playback-mode :shuffled) :is-primary))
|
||||
repeat-button (h/add-classes button (case repeat-mode
|
||||
:repeat-single :is-info
|
||||
:repeat-all :is-primary
|
||||
nil))
|
||||
:repeat-single :is-info
|
||||
:repeat-all :is-primary
|
||||
nil))
|
||||
repeat-title (case repeat-mode
|
||||
:repeat-all "Repeating current queue, click to repeat current track"
|
||||
:repeat-single "Repeating current track, click to repeat none"
|
||||
"Click to repeat current queue")]
|
||||
[:div.playback-mode-controls
|
||||
[:div.button-controls.playback-mode-controls
|
||||
[:div.button-group>div.field.has-addons
|
||||
^{:key :shuffle-button} [shuffle-button {:on-click (toggle-shuffle playback-mode)
|
||||
:title "Shuffle"} [icon :random]]
|
||||
|
|
@ -109,6 +136,7 @@
|
|||
[playback-info current-song playback-status]
|
||||
[progress-indicators current-song playback-status]
|
||||
[playback-controls is-playing?]
|
||||
[volume-controls playback-status]
|
||||
[playback-mode-controls playlist]]
|
||||
;; not playing anything
|
||||
[:p.navbar-item.idle-notification "No audio playing"])]))
|
||||
|
|
|
|||
|
|
@ -122,13 +122,54 @@
|
|||
fill: $dark-invert
|
||||
|
||||
// buttons to control current playback and playlist behavior
|
||||
.playback-controls,
|
||||
.playback-mode-controls
|
||||
.button-controls
|
||||
position: relative
|
||||
flex-shrink: 0
|
||||
padding-right: .6rem
|
||||
|
||||
.playback-controls
|
||||
padding-left: .6rem
|
||||
&:first-of-type
|
||||
padding-left: .6rem
|
||||
|
||||
.button-menu
|
||||
svg.volume-bar
|
||||
overflow: visible
|
||||
|
||||
.inactive
|
||||
fill: $background
|
||||
|
||||
.active
|
||||
fill: $link
|
||||
|
||||
.click-dummy
|
||||
cursor: pointer
|
||||
fill: transparent
|
||||
|
||||
.button-menu
|
||||
position: absolute
|
||||
z-index: 100
|
||||
width: 36px
|
||||
bottom: calc(100% + .3em)
|
||||
padding: $button-padding-horizontal $button-padding-horizontal / 2
|
||||
|
||||
border-radius: $radius
|
||||
background: $white
|
||||
color: $dark
|
||||
box-shadow: 0 0 2px rgba(0,0,0,.1), 0 0 4px rgba(0,0,0,.1)
|
||||
|
||||
// little arrow at the bottom
|
||||
&::after
|
||||
position: absolute
|
||||
content: ''
|
||||
display: block
|
||||
width: 6px
|
||||
height: 6px
|
||||
background: inherit
|
||||
top: 100%
|
||||
left: 50%
|
||||
margin-left: -3px
|
||||
margin-top: -3px
|
||||
transform: rotate(45deg)
|
||||
box-shadow: 2px 2px 1px rgba(0,0,0,.1)
|
||||
|
||||
// preview card for album or artist listings
|
||||
.preview-card
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue