From 2384c096e1dc7e31c8e2d2fc9dff4f663d19526b Mon Sep 17 00:00:00 2001 From: nokhnaton Date: Mon, 28 Oct 2024 16:49:12 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E9=9F=B3=E5=A3=B0=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=AE=E9=9F=B3=E9=87=8F=E3=82=92=E3=83=87?= =?UTF-8?q?=E3=83=90=E3=82=A4=E3=82=B9=E9=96=93=E3=81=A7=E5=90=8C=E6=9C=9F?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/composables/media/useAudio.ts | 29 +++++++++++++++++++---- src/store/app/mediaSettings.ts | 39 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 src/store/app/mediaSettings.ts diff --git a/src/composables/media/useAudio.ts b/src/composables/media/useAudio.ts index fe584b15e..a1db523df 100644 --- a/src/composables/media/useAudio.ts +++ b/src/composables/media/useAudio.ts @@ -1,8 +1,17 @@ import type { Ref } from 'vue' -import { ref, computed, watch, readonly, shallowRef, onUnmounted } from 'vue' +import { + ref, + computed, + watch, + readonly, + shallowRef, + onUnmounted, + onMounted +} from 'vue' import usePictureInPicture from './usePictureInPicture' import type { FileInfo } from '@traptitech/traq' import { useAudioController } from '/@/store/ui/audioController' +import { useMediaSettingsStore } from '/@/store/app/mediaSettings' const toFinite = (n: number | undefined, def: number) => Number.isFinite(n) ? (n as number) : def @@ -135,11 +144,21 @@ export const useDuration = (audio: Ref) => { } const useVolume = (audio: Ref) => { - const nativeVolume = ref(toFinite(audio.value?.volume, 1)) + const { audioVolume, restoringPromise } = useMediaSettingsStore() + + onMounted(async () => { + await restoringPromise.value + setVolume(toFinite(audioVolume.value, 1)) + }) + + const setVolume = (v: number) => { + if (audio.value) audio.value.volume = v + audioVolume.value = v + } const onVolumeChange = () => { if (!audio.value) return - nativeVolume.value = toFinite(audio.value.volume, 1) + setVolume(toFinite(audio.value.volume, audioVolume.value ?? 1)) } watch( @@ -149,7 +168,7 @@ const useVolume = (audio: Ref) => { oldAudio.removeEventListener('volumechange', onVolumeChange) } if (newAudio) { - nativeVolume.value = toFinite(newAudio.volume, 1) + setVolume(toFinite(audioVolume.value, 1)) newAudio.addEventListener('volumechange', onVolumeChange) } }, @@ -158,7 +177,7 @@ const useVolume = (audio: Ref) => { const volume = computed({ get() { - return nativeVolume.value + return audioVolume.value ?? 1 }, set(v) { if (!audio.value) return diff --git a/src/store/app/mediaSettings.ts b/src/store/app/mediaSettings.ts new file mode 100644 index 000000000..2ccde40ad --- /dev/null +++ b/src/store/app/mediaSettings.ts @@ -0,0 +1,39 @@ +import { defineStore, acceptHMRUpdate } from 'pinia' +import { toRefs } from 'vue' +import { convertToRefsStore } from '/@/store/utils/convertToRefsStore' +import useIndexedDbValue from '/@/composables/utils/useIndexedDbValue' + +export type IDBState = { + audioVolume: Readonly | undefined + videoVolume: Readonly | undefined +} + +const useMediaSettingsStorePinia = defineStore('app/mediaSettings', () => { + const initialValue: IDBState = { + audioVolume: 1, + videoVolume: 1 + } + + const [state, restoring, restoringPromise] = useIndexedDbValue( + 'store/app/mediaSettings', + 1, + {}, + initialValue + ) + + return { + ...toRefs(state), + restoring, + restoringPromise + } +}) + +export const useMediaSettingsStore = convertToRefsStore( + useMediaSettingsStorePinia +) + +if (import.meta.hot) { + import.meta.hot.accept( + acceptHMRUpdate(useMediaSettingsStorePinia, import.meta.hot) + ) +} From a2528abccf5f502d50e405330f068fec3b09662b Mon Sep 17 00:00:00 2001 From: nokhnaton Date: Mon, 28 Oct 2024 17:30:12 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E3=83=9F=E3=83=A5=E3=83=BC=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=A7=A3=E9=99=A4=E3=81=97=E3=81=9F=E3=81=A8=E3=81=8D?= =?UTF-8?q?=E3=81=AB=E9=9F=B3=E9=87=8F=E3=81=8CMAX=E3=81=AB=E3=81=AA?= =?UTF-8?q?=E3=82=89=E3=81=AA=E3=81=84=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MessageElement/MessageFileListAudio.vue | 4 +++- .../AudioControllerDetailPanel.vue | 14 +++++++---- .../AudioPlayer/AudioPlayerVolumeSlider.vue | 9 ++++--- src/components/UI/ChromeAudio.vue | 4 +++- src/composables/media/useAudio.ts | 24 +++++++++++++++---- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/components/Main/MainView/MessageElement/MessageFileListAudio.vue b/src/components/Main/MainView/MessageElement/MessageFileListAudio.vue index 8c77ff655..ee3432980 100644 --- a/src/components/Main/MainView/MessageElement/MessageFileListAudio.vue +++ b/src/components/Main/MainView/MessageElement/MessageFileListAudio.vue @@ -16,9 +16,11 @@ /> @@ -52,11 +54,13 @@ const { fileMeta, fileRawPath } = useFileMeta( reactive({ fileId: computed(() => fileId.value ?? '') }) ) const name = computed(() => fileMeta.value?.name ?? '') -const { isPlaying, currentTime, duration, volume, loop } = useAudio( - fileMeta, - fileRawPath, - audio -) +const { + isPlaying, + currentTime, + duration, + volume: { volume, toggleMute, isMute }, + loop +} = useAudio(fileMeta, fileRawPath, audio)