diff --git a/docker/nginx/conf.dev b/docker/nginx/conf.dev index 5cd43b1e5..28964a529 100644 --- a/docker/nginx/conf.dev +++ b/docker/nginx/conf.dev @@ -69,12 +69,12 @@ http { text/x-component text/x-cross-domain-policy; - add_header Content-Security-Policy "default-src 'self' 'unsafe-eval'; connect-src https: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"; + add_header Content-Security-Policy "connect-src https: wss: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"; add_header Referrer-Policy "strict-origin-when-cross-origin"; add_header X-Frame-Options "SAMEORIGIN" always; location /front/ { - add_header Content-Security-Policy "default-src 'self' 'unsafe-eval'; connect-src https: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"; + add_header Content-Security-Policy "connect-src https: wss: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; object-src 'none'; media-src 'self' data:"; add_header Referrer-Policy "strict-origin-when-cross-origin"; add_header Service-Worker-Allowed "/"; # uncomment the following line and comment the proxy-pass one diff --git a/front/package.json b/front/package.json index 3b0b8e075..19cda8790 100644 --- a/front/package.json +++ b/front/package.json @@ -35,6 +35,7 @@ "howler": "2.2.3", "js-logger": "1.6.1", "lodash-es": "4.17.21", + "lru-cache": "^7.13.1", "mavon-editor": "^3.0.0-beta", "moment": "2.29.4", "qs": "6.11.0", @@ -42,6 +43,7 @@ "sanitize-html": "2.7.1", "sass": "1.54.0", "showdown": "2.1.0", + "standardized-audio-context": "^25.3.29", "text-clipper": "2.2.0", "tiptap-markdown": "^0.5.0", "transliteration": "2.3.5", diff --git a/front/src/components/Queue.vue b/front/src/components/Queue.vue index bf6b690bd..6887e9401 100644 --- a/front/src/components/Queue.vue +++ b/front/src/components/Queue.vue @@ -11,7 +11,7 @@ import TrackPlaylistIcon from '~/components/playlists/TrackPlaylistIcon.vue' import { whenever, watchDebounced, useCurrentElement, useScrollLock } from '@vueuse/core' import { useGettext } from 'vue3-gettext' import useQueue from '~/composables/audio/useQueue' -import usePlayer from '~/composables/audio/usePlayer' +import useWebAudioPlayer from '~/composables/audio/useWebAudioPlayer' import VirtualList from '~/components/vui/list/VirtualList.vue' import QueueItem from '~/components/QueueItem.vue' @@ -24,33 +24,33 @@ const scrollLock = useScrollLock(document.body) const store = useStore() const { - playing, - loading: isLoadingAudio, - errored, - duration, - durationFormatted, - currentTimeFormatted, - progress, - bufferProgress, - currentTime, - pause, - resume -} = usePlayer() - -const { - currentTrack, - hasNext, isEmpty: emptyQueue, tracks, reorder, endsIn: timeLeft, - currentIndex, removeTrack, - clear, - next, - previous + clear } = useQueue() +const currentIndex = computed(() => store.state.queue.currentIndex) +const currentTrack = computed(() => store.state.queue.tracks[currentIndex.value]) +const hasNext = computed(() => store.getters['queue/hasNext']) +const durationFormatted = computed(() => time.parse(Math.floor(duration.value))) +const currentTimeFormatted = computed(() => time.parse(Math.floor(currentTime.value))) + +const { + play, + pause, + next, + previous, + playing, + errored, + progress, + duration, + time: currentTime, + loading: isLoadingAudio +} = useWebAudioPlayer() + const labels = computed(() => ({ queue: $pgettext('*/*/*', 'Queue'), duration: $pgettext('*/*/*', 'Duration'), @@ -105,13 +105,12 @@ router.beforeEach(() => store.commit('ui/queueFocused', null)) const progressBar = ref() const touchProgress = (event: MouseEvent) => { - const time = ((event.clientX - (event.target as Element).getBoundingClientRect().left) / progressBar.value.offsetWidth) * duration.value - currentTime.value = time + const percent = (event.clientX - ((event.target as Element).closest('.progress')?.getBoundingClientRect().left ?? 0)) / progressBar.value.offsetWidth + progress.value = percent * 100 } -const play = (index: unknown) => { - store.dispatch('queue/currentIndex', index as number) - resume() +const playIndex = (index: number) => { + store.state.queue.currentIndex = index } const getCover = (track: Track) => { @@ -255,12 +254,8 @@ const reorderTracks = async (from: number, to: number) => {