From 34610670c6dadc7e1656e3d9e520d67a73097c59 Mon Sep 17 00:00:00 2001 From: wvffle Date: Thu, 21 Jul 2022 14:55:48 +0000 Subject: [PATCH] Fix #1381 --- front/src/components/Queue.vue | 6 ++-- front/src/components/audio/Player.vue | 6 ++-- front/src/composables/audio/usePlayer.ts | 44 ++++++++++++------------ front/src/composables/audio/useSound.ts | 8 ++--- front/src/style/components/_player.scss | 9 +++-- front/src/style/components/_queue.scss | 15 +++++--- 6 files changed, 47 insertions(+), 41 deletions(-) diff --git a/front/src/components/Queue.vue b/front/src/components/Queue.vue index 8a6f748b7..1f35df1d8 100644 --- a/front/src/components/Queue.vue +++ b/front/src/components/Queue.vue @@ -220,13 +220,11 @@ const touchProgress = (event: MouseEvent) => { >
diff --git a/front/src/components/audio/Player.vue b/front/src/components/audio/Player.vue index 7fca3d0fe..b317dc71c 100644 --- a/front/src/components/audio/Player.vue +++ b/front/src/components/audio/Player.vue @@ -117,13 +117,11 @@ const switchTab = () => { >
diff --git a/front/src/composables/audio/usePlayer.ts b/front/src/composables/audio/usePlayer.ts index 7b3c769d7..3d5fd215c 100644 --- a/front/src/composables/audio/usePlayer.ts +++ b/front/src/composables/audio/usePlayer.ts @@ -2,7 +2,7 @@ import type { Track } from '~/types' import { computed, watchEffect, ref, watch } from 'vue' import { Howler } from 'howler' -import { useIntervalFn, useTimeoutFn } from '@vueuse/core' +import { useRafFn, useTimeoutFn } from '@vueuse/core' import useQueue from '~/composables/audio/useQueue' import useSound from '~/composables/audio/useSound' import toLinearVolumeScale from '~/composables/audio/toLinearVolumeScale' @@ -119,36 +119,36 @@ const progress = computed({ get: () => store.getters['player/progress'], set: (time) => { if (currentSound.value?.state() === 'loaded') { + store.state.player.currentTime = time + const duration = currentSound.value.duration() - - store.dispatch('player/updateProgress', time) - currentSound.value._triggerSoundProgress() - - const toPreload = store.state.queue.tracks[currentIndex.value + 1] - if (!nextTrackPreloaded.value && toPreload && (time > PRELOAD_DELAY || duration - time < 30)) { - loadSound(toPreload) - nextTrackPreloaded.value = true - } - - if (time > duration / 2) { - if (!isListeningSubmitted.value) { - store.dispatch('player/trackListened', currentTrack.value) - isListeningSubmitted.value = true - } - } + currentSound.value.triggerSoundProgress(time, duration) } } }) const bufferProgress = computed(() => store.state.player.bufferProgress) -onSoundProgress((node: HTMLAudioElement) => { +onSoundProgress(({ node, time, duration }) => { + const toPreload = store.state.queue.tracks[currentIndex.value + 1] + if (!nextTrackPreloaded.value && toPreload && (time > PRELOAD_DELAY || duration - time < 30)) { + loadSound(toPreload) + nextTrackPreloaded.value = true + } + + if (time > duration / 2) { + if (!isListeningSubmitted.value) { + store.dispatch('player/trackListened', currentTrack.value) + isListeningSubmitted.value = true + } + } + // from https://github.com/goldfire/howler.js/issues/752#issuecomment-372083163 - const { buffered, currentTime: time } = node + const { buffered, currentTime } = node let range = 0 try { - while (buffered.start(range) >= time || time >= buffered.end(range)) { + while (buffered.start(range) >= currentTime || currentTime >= buffered.end(range)) { range += 1 } } catch (IndexSizeError) { @@ -181,11 +181,11 @@ onSoundProgress((node: HTMLAudioElement) => { }) const observeProgress = ref(false) -useIntervalFn(() => { +useRafFn(() => { if (observeProgress.value && currentSound.value?.state() === 'loaded') { progress.value = currentSound.value.seek() } -}, 1000) +}) watch(playing, async (isPlaying) => { if (currentSound.value) { diff --git a/front/src/composables/audio/useSound.ts b/front/src/composables/audio/useSound.ts index 6d530a8f6..d9f824f0c 100644 --- a/front/src/composables/audio/useSound.ts +++ b/front/src/composables/audio/useSound.ts @@ -6,7 +6,7 @@ import useTrackSources from '~/composables/audio/useTrackSources' import useSoundCache from '~/composables/audio/useSoundCache' import usePlayer from '~/composables/audio/usePlayer' import store from '~/store' -import { createEventHook } from '@vueuse/core' +import { createEventHook, useThrottleFn } from '@vueuse/core' interface Sound { id?: number @@ -18,7 +18,7 @@ interface Sound { seek: (time?: number) => number duration: () => number getSource: () => boolean - _triggerSoundProgress: () => void + triggerSoundProgress: (time: number, duration: number) => void } const soundCache = useSoundCache() @@ -28,7 +28,7 @@ const looping = computed(() => store.state.player.looping) const currentSound = ref() const soundId = ref() -const soundProgress = createEventHook() +const soundProgress = createEventHook<{ node: HTMLAudioElement, time: number, duration: number }>() const createSound = (howl: Howl): Sound => ({ howl, @@ -46,7 +46,7 @@ const createSound = (howl: Howl): Sound => ({ seek: (time?: number) => howl.seek(time), duration: () => howl.duration(), getSource: () => (howl as any)._sounds[0], - _triggerSoundProgress: () => soundProgress.trigger((howl as any)._sounds[0]._node) + triggerSoundProgress: useThrottleFn((time: number, duration: number) => soundProgress.trigger({ node: (howl as any)._sounds[0]._node, time, duration }), 1000) }) const loadSound = (track: Track): Sound => { diff --git a/front/src/style/components/_player.scss b/front/src/style/components/_player.scss index c261bb07f..2663bce49 100644 --- a/front/src/style/components/_player.scss +++ b/front/src/style/components/_player.scss @@ -37,7 +37,11 @@ } .ui.progress .bar { - transition: none; + transition: transform .2s linear; + width: 100%; + transform: scaleX(0); + transform-origin: top left; + will-change: transform; } .ui.progress .buffer.bar { @@ -72,10 +76,9 @@ animation-timing-function: linear; animation-iteration-count: infinite; } - .ui.progress:not([data-percent]):not(.indeterminate) + .ui.progress:not(.indeterminate) .bar.position:not(.buffer) { background: var(--vibrant-color); - min-width: 0; } .track-controls { diff --git a/front/src/style/components/_queue.scss b/front/src/style/components/_queue.scss index b2bcde76b..f7fb4e7f1 100644 --- a/front/src/style/components/_queue.scss +++ b/front/src/style/components/_queue.scss @@ -163,15 +163,25 @@ .progress-area { overflow: hidden; } + .progress-area .progress { + border-radius: 0.28571429rem; + } .progress-wrapper, .warning.message { max-width: 25em; margin: 0 auto; } + .ui.progress .bar { + transition: transform .2s linear; + width: 100%; + transform: scaleX(0); + transform-origin: top left; + will-change: transform; + } .ui.progress .buffer.bar { position: absolute; background-color: rgba(255, 255, 255, 0.15); } - .ui.progress:not([data-percent]):not(.indeterminate) + .ui.progress:not(.indeterminate) .bar.position:not(.buffer) { background: var(--vibrant-color); } @@ -201,9 +211,6 @@ } .progress { cursor: pointer; - .bar { - min-width: 0 !important; - } } .player-controls {