refactor(stage-ui,stage-pages): no more resettable ref

This commit is contained in:
Neko Ayaka
2026-01-15 17:31:45 +08:00
parent 4ffc2a5f45
commit cf5d34bc7c
11 changed files with 127 additions and 165 deletions
@@ -1,12 +1,12 @@
<script setup lang="ts">
import { createResettableLocalStorage } from '@proj-airi/stage-ui/utils/resettable'
import { FieldInput } from '@proj-airi/ui'
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const defaultWebSocketUrl = import.meta.env.VITE_AIRI_WS_URL || 'ws://localhost:6121/ws'
const [websocketUrl] = createResettableLocalStorage('settings/connection/websocket-url', defaultWebSocketUrl)
const websocketUrl = refManualReset<string>(useLocalStorage('settings/connection/websocket-url', defaultWebSocketUrl))
</script>
<template>
+7 -8
View File
@@ -1,16 +1,15 @@
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { defineStore } from 'pinia'
import { createResettableLocalStorage } from '../utils/resettable'
export const useMcpStore = defineStore('mcp', () => {
const [serverCmd, resetServerCmd] = createResettableLocalStorage('settings/mcp/server-cmd', '')
const [serverArgs, resetServerArgs] = createResettableLocalStorage('settings/mcp/server-args', '')
const [connected, resetConnected] = createResettableLocalStorage('mcp/connected', false) // use local storage to sync between windows
const serverCmd = refManualReset<string>(useLocalStorage<string>('settings/mcp/server-cmd', ''))
const serverArgs = refManualReset<string>(useLocalStorage<string>('settings/mcp/server-args', ''))
const connected = refManualReset<boolean>(useLocalStorage<boolean>('mcp/connected', false)) // use local storage to sync between windows
function resetState() {
resetServerCmd()
resetServerArgs()
resetConnected()
serverCmd.reset()
serverArgs.reset()
connected.reset()
}
return {
@@ -1,5 +1,6 @@
import type { Card, ccv3 } from '@proj-airi/ccc'
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { nanoid } from 'nanoid'
import { defineStore, storeToRefs } from 'pinia'
import { computed, watch } from 'vue'
@@ -7,7 +8,6 @@ import { useI18n } from 'vue-i18n'
import SystemPromptV2 from '../../constants/prompts/system-v2'
import { createResettableLocalStorage } from '../../utils/resettable'
import { useConsciousnessStore } from './consciousness'
import { useSpeechStore } from './speech'
@@ -57,8 +57,8 @@ export interface AiriCard extends Card {
export const useAiriCardStore = defineStore('airi-card', () => {
const { t } = useI18n()
const [cards, resetCards] = createResettableLocalStorage<Map<string, AiriCard>>('airi-cards', new Map())
const [activeCardId, resetActiveCardId] = createResettableLocalStorage('airi-card-active-id', 'default')
const cards = refManualReset<Map<string, AiriCard>>(useLocalStorage('airi-cards', new Map()))
const activeCardId = refManualReset<string>(useLocalStorage('airi-card-active-id', 'default'))
const activeCard = computed(() => cards.value.get(activeCardId.value))
@@ -227,8 +227,8 @@ export const useAiriCardStore = defineStore('airi-card', () => {
})
function resetState() {
resetActiveCardId()
resetCards()
activeCardId.reset()
cards.reset()
}
return {
@@ -1,18 +1,18 @@
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { defineStore } from 'pinia'
import { computed } from 'vue'
import { createResettableLocalStorage, createResettableRef } from '../../utils/resettable'
import { useProvidersStore } from '../providers'
export const useConsciousnessStore = defineStore('consciousness', () => {
const providersStore = useProvidersStore()
// State
const [activeProvider, resetActiveProvider] = createResettableLocalStorage('settings/consciousness/active-provider', '')
const [activeModel, resetActiveModel] = createResettableLocalStorage('settings/consciousness/active-model', '')
const [activeCustomModelName, resetActiveCustomModelName] = createResettableLocalStorage('settings/consciousness/active-custom-model', '')
const [expandedDescriptions, resetExpandedDescriptions] = createResettableRef<Record<string, boolean>>({})
const [modelSearchQuery, resetModelSearchQuery] = createResettableRef('')
const activeProvider = refManualReset<string>(useLocalStorage<string>('settings/consciousness/active-provider', ''))
const activeModel = refManualReset<string>(useLocalStorage<string>('settings/consciousness/active-model', ''))
const activeCustomModelName = refManualReset<string>(useLocalStorage<string>('settings/consciousness/active-custom-model', ''))
const expandedDescriptions = refManualReset<Record<string, boolean>>(() => ({}))
const modelSearchQuery = refManualReset<string>('')
// Computed properties
const supportsModelListing = computed(() => {
@@ -45,10 +45,10 @@ export const useConsciousnessStore = defineStore('consciousness', () => {
})
function resetModelSelection() {
resetActiveModel()
resetActiveCustomModelName()
resetExpandedDescriptions()
resetModelSearchQuery()
activeModel.reset()
activeCustomModelName.reset()
expandedDescriptions.reset()
modelSearchQuery.reset()
}
async function loadModelsForProvider(provider: string) {
@@ -70,7 +70,7 @@ export const useConsciousnessStore = defineStore('consciousness', () => {
})
function resetState() {
resetActiveProvider()
activeProvider.reset()
resetModelSelection()
}
@@ -1,13 +1,13 @@
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { defineStore } from 'pinia'
import { computed } from 'vue'
import { createResettableLocalStorage } from '../../utils/resettable'
import { useConfiguratorByModsChannelServer } from '../configurator'
export const useDiscordStore = defineStore('discord', () => {
const configurator = useConfiguratorByModsChannelServer()
const [enabled, resetEnabled] = createResettableLocalStorage('settings/discord/enabled', false)
const [token, resetToken] = createResettableLocalStorage('settings/discord/token', '')
const enabled = refManualReset<boolean>(useLocalStorage<boolean>('settings/discord/enabled', false))
const token = refManualReset<string>(useLocalStorage<string>('settings/discord/token', ''))
function saveSettings() {
// Data is automatically saved to localStorage via useLocalStorage
@@ -23,8 +23,8 @@ export const useDiscordStore = defineStore('discord', () => {
})
function resetState() {
resetEnabled()
resetToken()
enabled.reset()
token.reset()
saveSettings()
}
@@ -1,17 +1,17 @@
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { defineStore } from 'pinia'
import { computed } from 'vue'
import { createResettableLocalStorage } from '../../utils/resettable'
import { useConfiguratorByModsChannelServer } from '../configurator'
export function createGamingModuleStore(moduleName: string, defaultPort: number) {
return defineStore(moduleName, () => {
const configurator = useConfiguratorByModsChannelServer()
const [enabled, resetEnabled] = createResettableLocalStorage(`settings/${moduleName}/enabled`, false)
const [serverAddress, resetServerAddress] = createResettableLocalStorage(`settings/${moduleName}/server-address`, '')
const [serverPort, resetServerPort] = createResettableLocalStorage<number | null>(`settings/${moduleName}/server-port`, defaultPort)
const [username, resetUsername] = createResettableLocalStorage(`settings/${moduleName}/username`, '')
const enabled = refManualReset<boolean>(useLocalStorage<boolean>(`settings/${moduleName}/enabled`, false))
const serverAddress = refManualReset<string>(useLocalStorage<string>(`settings/${moduleName}/server-address`, ''))
const serverPort = refManualReset<number | null>(useLocalStorage<number | null>(`settings/${moduleName}/server-port`, defaultPort))
const username = refManualReset<string>(useLocalStorage<string>(`settings/${moduleName}/username`, ''))
function saveSettings() {
configurator.updateFor(moduleName, {
@@ -23,10 +23,10 @@ export function createGamingModuleStore(moduleName: string, defaultPort: number)
}
function resetState() {
resetEnabled()
resetServerAddress()
resetServerPort()
resetUsername()
enabled.reset()
serverAddress.reset()
serverPort.reset()
username.reset()
saveSettings()
}
+13 -13
View File
@@ -3,13 +3,13 @@ import type { WithUnknown } from '@xsai/shared'
import type { StreamTranscriptionResult, StreamTranscriptionOptions as XSAIStreamTranscriptionOptions } from '@xsai/stream-transcription'
import { tryCatch } from '@moeru/std'
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { generateTranscription } from '@xsai/generate-transcription'
import { defineStore, storeToRefs } from 'pinia'
import { computed, ref, shallowRef } from 'vue'
import vadWorkletUrl from '../../workers/vad/process.worklet?worker&url'
import { createResettableLocalStorage, createResettableRef } from '../../utils/resettable'
import { useProvidersStore } from '../providers'
import { streamAliyunTranscription } from '../providers/aliyun/stream-transcription'
import { streamWebSpeechAPITranscription } from '../providers/web-speech-api'
@@ -49,12 +49,12 @@ export const useHearingStore = defineStore('hearing-store', () => {
const { allAudioTranscriptionProvidersMetadata } = storeToRefs(providersStore)
// State
const [activeTranscriptionProvider, resetActiveTranscriptionProvider] = createResettableLocalStorage('settings/hearing/active-provider', '')
const [activeTranscriptionModel, resetActiveTranscriptionModel] = createResettableLocalStorage('settings/hearing/active-model', '')
const [activeCustomModelName, resetActiveCustomModelName] = createResettableLocalStorage('settings/hearing/active-custom-model', '')
const [transcriptionModelSearchQuery, resetTranscriptionModelSearchQuery] = createResettableRef('')
const [autoSendEnabled, resetAutoSendEnabled] = createResettableLocalStorage('settings/hearing/auto-send-enabled', false)
const [autoSendDelay, resetAutoSendDelay] = createResettableLocalStorage('settings/hearing/auto-send-delay', 2000) // Default 2 seconds
const activeTranscriptionProvider = refManualReset<string>(useLocalStorage('settings/hearing/active-provider', ''))
const activeTranscriptionModel = refManualReset<string>(useLocalStorage('settings/hearing/active-model', ''))
const activeCustomModelName = refManualReset<string>(useLocalStorage('settings/hearing/active-custom-model', ''))
const transcriptionModelSearchQuery = refManualReset<string>('')
const autoSendEnabled = refManualReset<boolean>(useLocalStorage('settings/hearing/auto-send-enabled', false))
const autoSendDelay = refManualReset<number>(useLocalStorage('settings/hearing/auto-send-delay', 2000)) // Default 2 seconds
// Computed properties
const availableProvidersMetadata = computed(() => allAudioTranscriptionProvidersMetadata.value)
@@ -104,12 +104,12 @@ export const useHearingStore = defineStore('hearing-store', () => {
})
function resetState() {
resetActiveTranscriptionProvider()
resetActiveTranscriptionModel()
resetActiveCustomModelName()
resetTranscriptionModelSearchQuery()
resetAutoSendEnabled()
resetAutoSendDelay()
activeTranscriptionProvider.reset()
activeTranscriptionModel.reset()
activeCustomModelName.reset()
transcriptionModelSearchQuery.reset()
autoSendEnabled.reset()
autoSendDelay.reset()
}
async function transcription(
+25 -25
View File
@@ -2,13 +2,13 @@ import type { SpeechProviderWithExtraOptions } from '@xsai-ext/providers/utils'
import type { VoiceInfo } from '../providers'
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { generateSpeech } from '@xsai/generate-speech'
import { defineStore, storeToRefs } from 'pinia'
import { computed, onMounted, watch } from 'vue'
import { toXml } from 'xast-util-to-xml'
import { x } from 'xastscript'
import { createResettableLocalStorage, createResettableRef } from '../../utils/resettable'
import { useProvidersStore } from '../providers'
export const useSpeechStore = defineStore('speech', () => {
@@ -16,19 +16,19 @@ export const useSpeechStore = defineStore('speech', () => {
const { allAudioSpeechProvidersMetadata } = storeToRefs(providersStore)
// State
const [activeSpeechProvider, resetActiveSpeechProvider] = createResettableLocalStorage('settings/speech/active-provider', '')
const [activeSpeechModel, resetActiveSpeechModel] = createResettableLocalStorage('settings/speech/active-model', 'eleven_multilingual_v2')
const [activeSpeechVoiceId, resetActiveSpeechVoiceId] = createResettableLocalStorage<string>('settings/speech/voice', '')
const [activeSpeechVoice, resetActiveSpeechVoice] = createResettableRef<VoiceInfo | undefined>(undefined)
const activeSpeechProvider = refManualReset<string>(useLocalStorage<string>('settings/speech/active-provider', ''))
const activeSpeechModel = refManualReset<string>(useLocalStorage<string>('settings/speech/active-model', 'eleven_multilingual_v2'))
const activeSpeechVoiceId = refManualReset<string>(useLocalStorage<string>('settings/speech/voice', ''))
const activeSpeechVoice = refManualReset<VoiceInfo | undefined>(undefined)
const [pitch, resetPitch] = createResettableLocalStorage('settings/speech/pitch', 0)
const [rate, resetRate] = createResettableLocalStorage('settings/speech/rate', 1)
const [ssmlEnabled, resetSsmlEnabled] = createResettableLocalStorage('settings/speech/ssml-enabled', false)
const [isLoadingSpeechProviderVoices, resetIsLoadingSpeechProviderVoices] = createResettableRef(false)
const [speechProviderError, resetSpeechProviderError] = createResettableRef<string | null>(null)
const [availableVoices, resetAvailableVoices] = createResettableRef<Record<string, VoiceInfo[]>>({})
const [selectedLanguage, resetSelectedLanguage] = createResettableLocalStorage('settings/speech/language', 'en-US')
const [modelSearchQuery, resetModelSearchQuery] = createResettableRef('')
const pitch = refManualReset<number>(useLocalStorage<number>('settings/speech/pitch', 0))
const rate = refManualReset<number>(useLocalStorage<number>('settings/speech/rate', 1))
const ssmlEnabled = refManualReset<boolean>(useLocalStorage<boolean>('settings/speech/ssml-enabled', false))
const isLoadingSpeechProviderVoices = refManualReset<boolean>(false)
const speechProviderError = refManualReset<string | null>(null)
const availableVoices = refManualReset<Record<string, VoiceInfo[]>>(() => ({}))
const selectedLanguage = refManualReset<string>(useLocalStorage<string>('settings/speech/language', 'en-US'))
const modelSearchQuery = refManualReset<string>('')
// Computed properties
const availableSpeechProvidersMetadata = computed(() => allAudioSpeechProvidersMetadata.value)
@@ -205,18 +205,18 @@ export const useSpeechStore = defineStore('speech', () => {
})
function resetState() {
resetActiveSpeechProvider()
resetActiveSpeechModel()
resetActiveSpeechVoiceId()
resetActiveSpeechVoice()
resetPitch()
resetRate()
resetSsmlEnabled()
resetSelectedLanguage()
resetModelSearchQuery()
resetAvailableVoices()
resetSpeechProviderError()
resetIsLoadingSpeechProviderVoices()
activeSpeechProvider.reset()
activeSpeechModel.reset()
activeSpeechVoiceId.reset()
activeSpeechVoice.reset()
pitch.reset()
rate.reset()
ssmlEnabled.reset()
selectedLanguage.reset()
modelSearchQuery.reset()
availableVoices.reset()
speechProviderError.reset()
isLoadingSpeechProviderVoices.reset()
}
return {
+11 -11
View File
@@ -1,17 +1,17 @@
import { refManualReset, useLocalStorage } from '@vueuse/core'
import { defineStore } from 'pinia'
import { computed } from 'vue'
import { createResettableLocalStorage } from '../../utils/resettable'
import { useConfiguratorByModsChannelServer } from '../configurator'
export const useTwitterStore = defineStore('twitter', () => {
const configurator = useConfiguratorByModsChannelServer()
const [enabled, resetEnabled] = createResettableLocalStorage('settings/twitter/enabled', false)
const [apiKey, resetApiKey] = createResettableLocalStorage('settings/twitter/api-key', '')
const [apiSecret, resetApiSecret] = createResettableLocalStorage('settings/twitter/api-secret', '')
const [accessToken, resetAccessToken] = createResettableLocalStorage('settings/twitter/access-token', '')
const [accessTokenSecret, resetAccessTokenSecret] = createResettableLocalStorage('settings/twitter/access-token-secret', '')
const enabled = refManualReset<boolean>(useLocalStorage<boolean>('settings/twitter/enabled', false))
const apiKey = refManualReset<string>(useLocalStorage<string>('settings/twitter/api-key', ''))
const apiSecret = refManualReset<string>(useLocalStorage<string>('settings/twitter/api-secret', ''))
const accessToken = refManualReset<string>(useLocalStorage<string>('settings/twitter/access-token', ''))
const accessTokenSecret = refManualReset<string>(useLocalStorage<string>('settings/twitter/access-token-secret', ''))
function saveSettings() {
// Data is automatically saved to localStorage via useLocalStorage
@@ -30,11 +30,11 @@ export const useTwitterStore = defineStore('twitter', () => {
})
function resetState() {
resetEnabled()
resetApiKey()
resetApiSecret()
resetAccessToken()
resetAccessTokenSecret()
enabled.reset()
apiKey.reset()
apiSecret.reset()
accessToken.reset()
accessTokenSecret.reset()
saveSettings()
}
+39 -40
View File
@@ -2,12 +2,11 @@ import type { DisplayModel } from './display-models'
import messages from '@proj-airi/i18n/locales'
import { useEventListener } from '@vueuse/core'
import { refManualReset, useEventListener, useLocalStorage } from '@vueuse/core'
import { converter } from 'culori'
import { defineStore } from 'pinia'
import { onMounted, watch } from 'vue'
import { createResettableLocalStorage, createResettableRef } from '../utils/resettable'
import { useAudioDevice } from './audio'
import { DisplayModelFormat, useDisplayModelsStore } from './display-models'
@@ -40,12 +39,12 @@ const getHueFrom = (color?: string) => color ? convert(color)?.h : DEFAULT_THEME
export const useSettings = defineStore('settings', () => {
const displayModelsStore = useDisplayModelsStore()
const [language, resetLanguage] = createResettableLocalStorage('settings/language', '')
const language = refManualReset<string>(useLocalStorage('settings/language', ''))
const [stageModelSelected, resetStageModelSelected] = createResettableLocalStorage<string | undefined>('settings/stage/model', 'preset-live2d-1')
const [stageModelSelectedDisplayModel, resetStageModelSelectedDisplayModel] = createResettableRef<DisplayModel | undefined>(undefined)
const [stageModelSelectedUrl, resetStageModelSelectedUrl] = createResettableRef<string | undefined>(undefined)
const [stageModelRenderer, resetStageModelRenderer] = createResettableRef<'live2d' | 'vrm' | 'disabled' | undefined>(undefined)
const stageModelSelected = refManualReset<string | undefined>(useLocalStorage('settings/stage/model', 'preset-live2d-1'))
const stageModelSelectedDisplayModel = refManualReset<DisplayModel | undefined>(undefined)
const stageModelSelectedUrl = refManualReset<string | undefined>(undefined)
const stageModelRenderer = refManualReset<'live2d' | 'vrm' | 'disabled' | undefined>(undefined)
async function updateStageModel() {
if (!stageModelSelected.value) {
@@ -99,23 +98,23 @@ export const useSettings = defineStore('settings', () => {
}
})
const [stageViewControlsEnabled, resetStageViewControlsEnabled] = createResettableRef(false)
const stageViewControlsEnabled = refManualReset<boolean>(false)
const [live2dDisableFocus, resetLive2dDisableFocus] = createResettableLocalStorage('settings/live2d/disable-focus', false)
const [live2dIdleAnimationEnabled, resetLive2dIdleAnimationEnabled] = createResettableLocalStorage('settings/live2d/idle-animation-enabled', true)
const [live2dAutoBlinkEnabled, resetLive2dAutoBlinkEnabled] = createResettableLocalStorage('settings/live2d/auto-blink-enabled', true)
const [live2dForceAutoBlinkEnabled, resetLive2dForceAutoBlinkEnabled] = createResettableLocalStorage('settings/live2d/force-auto-blink-enabled', false)
const [live2dShadowEnabled, resetLive2dShadowEnabled] = createResettableLocalStorage('settings/live2d/shadow-enabled', true)
const live2dDisableFocus = refManualReset<boolean>(useLocalStorage<boolean>('settings/live2d/disable-focus', false))
const live2dIdleAnimationEnabled = refManualReset<boolean>(useLocalStorage<boolean>('settings/live2d/idle-animation-enabled', true))
const live2dAutoBlinkEnabled = refManualReset<boolean>(useLocalStorage<boolean>('settings/live2d/auto-blink-enabled', true))
const live2dForceAutoBlinkEnabled = refManualReset<boolean>(useLocalStorage<boolean>('settings/live2d/force-auto-blink-enabled', false))
const live2dShadowEnabled = refManualReset<boolean>(useLocalStorage<boolean>('settings/live2d/shadow-enabled', true))
const [disableTransitions, resetDisableTransitions] = createResettableLocalStorage('settings/disable-transitions', true)
const [usePageSpecificTransitions, resetUsePageSpecificTransitions] = createResettableLocalStorage('settings/use-page-specific-transitions', true)
const disableTransitions = refManualReset<boolean>(useLocalStorage<boolean>('settings/disable-transitions', true))
const usePageSpecificTransitions = refManualReset<boolean>(useLocalStorage<boolean>('settings/use-page-specific-transitions', true))
const [themeColorsHue, resetThemeColorsHue] = createResettableLocalStorage('settings/theme/colors/hue', DEFAULT_THEME_COLORS_HUE)
const [themeColorsHueDynamic, resetThemeColorsHueDynamic] = createResettableLocalStorage('settings/theme/colors/hue-dynamic', false)
const themeColorsHue = refManualReset<number>(useLocalStorage<number>('settings/theme/colors/hue', DEFAULT_THEME_COLORS_HUE))
const themeColorsHueDynamic = refManualReset<boolean>(useLocalStorage<boolean>('settings/theme/colors/hue-dynamic', false))
const [allowVisibleOnAllWorkspaces, resetAllowVisibleOnAllWorkspaces] = createResettableLocalStorage('settings/allow-visible-on-all-workspaces', true)
const allowVisibleOnAllWorkspaces = refManualReset<boolean>(useLocalStorage<boolean>('settings/allow-visible-on-all-workspaces', true))
const [controlsIslandIconSize, resetControlsIslandIconSize] = createResettableLocalStorage<'auto' | 'large' | 'small'>('settings/controls-island/icon-size', 'auto')
const controlsIslandIconSize = refManualReset(useLocalStorage<'auto' | 'large' | 'small'>('settings/controls-island/icon-size', 'auto'))
function getLanguage() {
let language = localStorage.getItem('settings/language')
@@ -168,27 +167,27 @@ export const useSettings = defineStore('settings', () => {
if (stageModelSelectedUrl.value)
URL.revokeObjectURL(stageModelSelectedUrl.value)
resetLanguage()
resetStageModelSelected()
resetStageModelSelectedDisplayModel()
resetStageModelSelectedUrl()
resetStageModelRenderer()
resetStageViewControlsEnabled()
language.reset()
stageModelSelected.reset()
stageModelSelectedDisplayModel.reset()
stageModelSelectedUrl.reset()
stageModelRenderer.reset()
stageViewControlsEnabled.reset()
resetLive2dDisableFocus()
resetLive2dIdleAnimationEnabled()
resetLive2dAutoBlinkEnabled()
resetLive2dForceAutoBlinkEnabled()
resetLive2dShadowEnabled()
live2dDisableFocus.reset()
live2dIdleAnimationEnabled.reset()
live2dAutoBlinkEnabled.reset()
live2dForceAutoBlinkEnabled.reset()
live2dShadowEnabled.reset()
resetDisableTransitions()
resetUsePageSpecificTransitions()
disableTransitions.reset()
usePageSpecificTransitions.reset()
resetThemeColorsHue()
resetThemeColorsHueDynamic()
themeColorsHue.reset()
themeColorsHueDynamic.reset()
resetAllowVisibleOnAllWorkspaces()
resetControlsIslandIconSize()
allowVisibleOnAllWorkspaces.reset()
controlsIslandIconSize.reset()
await updateStageModel()
}
@@ -229,8 +228,8 @@ export const useSettings = defineStore('settings', () => {
export const useSettingsAudioDevice = defineStore('settings-audio-devices', () => {
const { audioInputs, deviceConstraints, selectedAudioInput: selectedAudioInputNonPersist, startStream, stopStream, stream, askPermission } = useAudioDevice()
const [selectedAudioInputPersist, resetSelectedAudioInputPersist] = createResettableLocalStorage('settings/audio/input', selectedAudioInputNonPersist.value)
const [selectedAudioInputEnabledPersist, resetSelectedAudioInputEnabledPersist] = createResettableLocalStorage('settings/audio/input/enabled', false)
const selectedAudioInputPersist = refManualReset<string>(useLocalStorage('settings/audio/input', selectedAudioInputNonPersist.value))
const selectedAudioInputEnabledPersist = refManualReset<boolean>(useLocalStorage('settings/audio/input/enabled', false))
watch(selectedAudioInputPersist, (newValue) => {
selectedAudioInputNonPersist.value = newValue
@@ -258,9 +257,9 @@ export const useSettingsAudioDevice = defineStore('settings-audio-devices', () =
})
function resetState() {
resetSelectedAudioInputPersist()
selectedAudioInputPersist.reset()
selectedAudioInputNonPersist.value = ''
resetSelectedAudioInputEnabledPersist()
selectedAudioInputEnabledPersist.reset()
stopStream()
}
-36
View File
@@ -1,36 +0,0 @@
import { useLocalStorage } from '@vueuse/core'
import { ref } from 'vue'
const structuredCloneFn: (<T>(value: T) => T) | undefined = (globalThis as any).structuredClone
function cloneDefault<T>(value: T): T {
if (typeof structuredCloneFn === 'function')
return structuredCloneFn(value)
if (value instanceof Map)
return new Map(value) as unknown as T
if (Array.isArray(value))
return value.map(item => cloneDefault(item)) as unknown as T
if (value && typeof value === 'object')
return JSON.parse(JSON.stringify(value)) as T
return value
}
export function createResettableRef<T>(initialValue: T) {
const state = ref<T>(cloneDefault(initialValue))
const reset = () => {
state.value = cloneDefault(initialValue)
}
return [state, reset] as const
}
export function createResettableLocalStorage<T>(key: string, initialValue: T) {
const state = useLocalStorage<T>(key, cloneDefault(initialValue))
const reset = () => {
state.value = cloneDefault(initialValue)
}
return [state, reset] as const
}