refactor(stage-ui): provide each individual reset state function for each store
This commit is contained in:
+8
-1
@@ -1,5 +1,12 @@
|
||||
[workspace]
|
||||
members = [ "crates/tauri-plugin-ipc-audio-transcription-ort", "crates/tauri-plugin-ipc-audio-vad-ort", "crates/tauri-plugin-mcp", "crates/tauri-plugin-rdev", "crates/tauri-plugin-window-pass-through-on-hover", "crates/tauri-plugin-window-router-link" ]
|
||||
members = [
|
||||
"crates/tauri-plugin-ipc-audio-transcription-ort",
|
||||
"crates/tauri-plugin-ipc-audio-vad-ort",
|
||||
"crates/tauri-plugin-mcp",
|
||||
"crates/tauri-plugin-rdev",
|
||||
"crates/tauri-plugin-window-pass-through-on-hover",
|
||||
"crates/tauri-plugin-window-router-link"
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
|
||||
@@ -15,14 +15,14 @@ interface InputSource {
|
||||
discord: Discord
|
||||
}
|
||||
|
||||
export type ContextSource =
|
||||
| 'text'
|
||||
| 'stt'
|
||||
| 'vision'
|
||||
| 'llm'
|
||||
| 'server-channel'
|
||||
| 'plugin'
|
||||
| 'system'
|
||||
export type ContextSource
|
||||
= | 'text'
|
||||
| 'stt'
|
||||
| 'vision'
|
||||
| 'llm'
|
||||
| 'server-channel'
|
||||
| 'plugin'
|
||||
| 'system'
|
||||
|
||||
export interface ContextMessage<Payload = unknown, Meta = Record<string, unknown>> {
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export * from './dialogs'
|
||||
export * from './chat'
|
||||
export * from './dialogs'
|
||||
export * from './providers'
|
||||
export * from './settings'
|
||||
export * from './toasters'
|
||||
|
||||
@@ -94,7 +94,7 @@ export function useLive2DMotionManagerUpdate(options: UseLive2DMotionManagerUpda
|
||||
|
||||
if (!ctx.handled && ctx.hookedUpdate) {
|
||||
const result = ctx.hookedUpdate.call(motionManager, model, now)
|
||||
if (Boolean(result))
|
||||
if (result)
|
||||
ctx.handled = true
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import type { ChatEntry } from '../stores/chat'
|
||||
|
||||
import { isStageTamagotchi } from '@proj-airi/stage-shared'
|
||||
import { DEFAULT_THEME_COLORS_HUE, useSettings, useSettingsAudioDevice } from '../stores/settings'
|
||||
import { defaultModelParameters, useLive2d } from '../stores/live2d'
|
||||
|
||||
import { useChatStore } from '../stores/chat'
|
||||
import { useDisplayModelsStore } from '../stores/display-models'
|
||||
import { useLive2d } from '../stores/live2d'
|
||||
import { useMcpStore } from '../stores/mcp'
|
||||
import { useAiriCardStore } from '../stores/modules/airi-card'
|
||||
import { useConsciousnessStore } from '../stores/modules/consciousness'
|
||||
import { useDiscordStore } from '../stores/modules/discord'
|
||||
@@ -9,12 +14,9 @@ import { useMinecraftStore } from '../stores/modules/gaming-minecraft'
|
||||
import { useHearingStore } from '../stores/modules/hearing'
|
||||
import { useSpeechStore } from '../stores/modules/speech'
|
||||
import { useTwitterStore } from '../stores/modules/twitter'
|
||||
import type { ChatEntry } from '../stores/chat'
|
||||
import { useChatStore } from '../stores/chat'
|
||||
import { useDisplayModelsStore } from '../stores/display-models'
|
||||
import { useMcpStore } from '../stores/mcp'
|
||||
import { useOnboardingStore } from '../stores/onboarding'
|
||||
import { useProvidersStore } from '../stores/providers'
|
||||
import { useSettings, useSettingsAudioDevice } from '../stores/settings'
|
||||
|
||||
export function useDataMaintenance() {
|
||||
const chatStore = useChatStore()
|
||||
@@ -45,45 +47,13 @@ export function useDataMaintenance() {
|
||||
}
|
||||
|
||||
function resetModulesSettings() {
|
||||
hearingStore.activeTranscriptionProvider = ''
|
||||
hearingStore.activeTranscriptionModel = ''
|
||||
hearingStore.activeCustomModelName = ''
|
||||
|
||||
speechStore.activeSpeechProvider = ''
|
||||
speechStore.activeSpeechModel = 'eleven_multilingual_v2'
|
||||
speechStore.activeSpeechVoiceId = ''
|
||||
speechStore.activeSpeechVoice = undefined
|
||||
speechStore.pitch = 0
|
||||
speechStore.rate = 1
|
||||
speechStore.ssmlEnabled = false
|
||||
speechStore.selectedLanguage = 'en-US'
|
||||
|
||||
consciousnessStore.activeProvider = ''
|
||||
consciousnessStore.activeModel = ''
|
||||
consciousnessStore.activeCustomModelName = ''
|
||||
|
||||
twitterStore.enabled = false
|
||||
twitterStore.apiKey = ''
|
||||
twitterStore.apiSecret = ''
|
||||
twitterStore.accessToken = ''
|
||||
twitterStore.accessTokenSecret = ''
|
||||
twitterStore.saveSettings()
|
||||
|
||||
discordStore.enabled = false
|
||||
discordStore.token = ''
|
||||
discordStore.saveSettings()
|
||||
|
||||
factorioStore.enabled = false
|
||||
factorioStore.serverAddress = ''
|
||||
factorioStore.serverPort = 34197
|
||||
factorioStore.username = ''
|
||||
factorioStore.saveSettings()
|
||||
|
||||
minecraftStore.enabled = false
|
||||
minecraftStore.serverAddress = ''
|
||||
minecraftStore.serverPort = 25565
|
||||
minecraftStore.username = ''
|
||||
minecraftStore.saveSettings()
|
||||
hearingStore.resetState()
|
||||
speechStore.resetState()
|
||||
consciousnessStore.resetState()
|
||||
twitterStore.resetState()
|
||||
discordStore.resetState()
|
||||
factorioStore.resetState()
|
||||
minecraftStore.resetState()
|
||||
}
|
||||
|
||||
function deleteAllChatSessions() {
|
||||
@@ -107,42 +77,13 @@ export function useDataMaintenance() {
|
||||
chatStore.replaceSessions(sessions)
|
||||
}
|
||||
|
||||
function resetSettingsState() {
|
||||
settingsStore.language = ''
|
||||
settingsStore.stageModelSelected = 'preset-live2d-1'
|
||||
settingsStore.stageViewControlsEnabled = false
|
||||
|
||||
settingsStore.live2dDisableFocus = false
|
||||
settingsStore.live2dIdleAnimationEnabled = true
|
||||
settingsStore.live2dAutoBlinkEnabled = true
|
||||
settingsStore.live2dShadowEnabled = true
|
||||
|
||||
settingsStore.disableTransitions = true
|
||||
settingsStore.usePageSpecificTransitions = true
|
||||
|
||||
settingsStore.themeColorsHue = DEFAULT_THEME_COLORS_HUE
|
||||
settingsStore.themeColorsHueDynamic = false
|
||||
|
||||
settingsStore.allowVisibleOnAllWorkspaces = true
|
||||
|
||||
audioSettingsStore.enabled = false
|
||||
audioSettingsStore.selectedAudioInput = ''
|
||||
audioSettingsStore.stopStream()
|
||||
|
||||
live2dStore.position = { x: 0, y: 0 }
|
||||
live2dStore.scale = 1
|
||||
live2dStore.motionMap = {}
|
||||
live2dStore.modelParameters = { ...defaultModelParameters }
|
||||
|
||||
mcpStore.serverCmd = ''
|
||||
mcpStore.serverArgs = ''
|
||||
mcpStore.connected = false
|
||||
|
||||
async function resetSettingsState() {
|
||||
await settingsStore.resetState()
|
||||
audioSettingsStore.resetState()
|
||||
live2dStore.resetState()
|
||||
mcpStore.resetState()
|
||||
onboardingStore.resetSetupState()
|
||||
airiCardStore.activeCardId = 'default'
|
||||
airiCardStore.cards = new Map()
|
||||
|
||||
void settingsStore.updateStageModel()
|
||||
airiCardStore.resetState()
|
||||
}
|
||||
|
||||
async function deleteAllData() {
|
||||
@@ -150,14 +91,14 @@ export function useDataMaintenance() {
|
||||
await resetProvidersSettings()
|
||||
resetModulesSettings()
|
||||
deleteAllChatSessions()
|
||||
resetSettingsState()
|
||||
await resetSettingsState()
|
||||
}
|
||||
|
||||
function resetDesktopApplicationState() {
|
||||
async function resetDesktopApplicationState() {
|
||||
if (!isStageTamagotchi())
|
||||
return
|
||||
|
||||
resetSettingsState()
|
||||
await resetSettingsState()
|
||||
resetModulesSettings()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { useBroadcastChannel, useLocalStorage } from '@vueuse/core'
|
||||
import { useBroadcastChannel } from '@vueuse/core'
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import { createResettableLocalStorage, createResettableRef } from '../utils/resettable'
|
||||
|
||||
type BroadcastChannelEvents
|
||||
= | BroadcastChannelEventShouldUpdateView
|
||||
|
||||
@@ -53,18 +55,28 @@ export const useLive2d = defineStore('live2d', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const position = useLocalStorage('settings/live2d/position', { x: 0, y: 0 }) // position is relative to the center of the screen, units are %
|
||||
const [position, resetPosition] = createResettableLocalStorage('settings/live2d/position', { x: 0, y: 0 }) // position is relative to the center of the screen, units are %
|
||||
const positionInPercentageString = computed(() => ({
|
||||
x: `${position.value.x}%`,
|
||||
y: `${position.value.y}%`,
|
||||
}))
|
||||
const currentMotion = ref<{ group: string, index?: number }>({ group: 'Idle', index: 0 })
|
||||
const availableMotions = ref<{ motionName: string, motionIndex: number, fileName: string }[]>([])
|
||||
const motionMap = useLocalStorage<Record<string, string>>('settings/live2d/motion-map', {})
|
||||
const scale = useLocalStorage('settings/live2d/scale', 1)
|
||||
const [currentMotion, resetCurrentMotion] = createResettableRef<{ group: string, index?: number }>({ group: 'Idle', index: 0 })
|
||||
const [availableMotions, resetAvailableMotions] = createResettableRef<{ motionName: string, motionIndex: number, fileName: string }[]>([])
|
||||
const [motionMap, resetMotionMap] = createResettableLocalStorage<Record<string, string>>('settings/live2d/motion-map', {})
|
||||
const [scale, resetScale] = createResettableLocalStorage('settings/live2d/scale', 1)
|
||||
|
||||
// Live2D model parameters
|
||||
const modelParameters = useLocalStorage('settings/live2d/parameters', defaultModelParameters)
|
||||
const [modelParameters, resetModelParameters] = createResettableLocalStorage('settings/live2d/parameters', defaultModelParameters)
|
||||
|
||||
function resetState() {
|
||||
resetPosition()
|
||||
resetCurrentMotion()
|
||||
resetAvailableMotions()
|
||||
resetMotionMap()
|
||||
resetScale()
|
||||
resetModelParameters()
|
||||
shouldUpdateView()
|
||||
}
|
||||
|
||||
return {
|
||||
position,
|
||||
@@ -77,5 +89,6 @@ export const useLive2d = defineStore('live2d', () => {
|
||||
|
||||
onShouldUpdateView,
|
||||
shouldUpdateView,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import { createResettableLocalStorage } from '../utils/resettable'
|
||||
|
||||
export const useMcpStore = defineStore('mcp', () => {
|
||||
const serverCmd = useLocalStorage('settings/mcp/server-cmd', '')
|
||||
const serverArgs = useLocalStorage('settings/mcp/server-args', '')
|
||||
const connected = useLocalStorage('mcp/connected', false) // use local storage to sync between windows
|
||||
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
|
||||
|
||||
function resetState() {
|
||||
resetServerCmd()
|
||||
resetServerArgs()
|
||||
resetConnected()
|
||||
}
|
||||
|
||||
return {
|
||||
serverCmd,
|
||||
serverArgs,
|
||||
connected,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Card, ccv3 } from '@proj-airi/ccc'
|
||||
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { nanoid } from 'nanoid'
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { computed, onMounted, watch } from 'vue'
|
||||
@@ -8,6 +7,7 @@ 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'
|
||||
|
||||
@@ -54,8 +54,8 @@ export interface AiriCard extends Card {
|
||||
}
|
||||
|
||||
export const useAiriCardStore = defineStore('airi-card', () => {
|
||||
const cards = useLocalStorage<Map<string, AiriCard>>('airi-cards', new Map())
|
||||
const activeCardId = useLocalStorage('airi-card-active-id', 'default')
|
||||
const [cards, resetCards] = createResettableLocalStorage<Map<string, AiriCard>>('airi-cards', new Map())
|
||||
const [activeCardId, resetActiveCardId] = createResettableLocalStorage('airi-card-active-id', 'default')
|
||||
|
||||
const activeCard = computed(() => cards.value.get(activeCardId.value))
|
||||
|
||||
@@ -208,6 +208,11 @@ export const useAiriCardStore = defineStore('airi-card', () => {
|
||||
activeSpeechVoiceId.value = extension?.modules?.speech?.voice_id
|
||||
})
|
||||
|
||||
function resetState() {
|
||||
resetActiveCardId()
|
||||
resetCards()
|
||||
}
|
||||
|
||||
return {
|
||||
cards,
|
||||
activeCard,
|
||||
@@ -215,6 +220,7 @@ export const useAiriCardStore = defineStore('airi-card', () => {
|
||||
addCard,
|
||||
removeCard,
|
||||
getCard,
|
||||
resetState,
|
||||
|
||||
currentModels: computed(() => {
|
||||
return {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { defineStore } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
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 = useLocalStorage('settings/consciousness/active-provider', '')
|
||||
const activeModel = useLocalStorage('settings/consciousness/active-model', '')
|
||||
const activeCustomModelName = useLocalStorage('settings/consciousness/active-custom-model', '')
|
||||
const expandedDescriptions = ref<Record<string, boolean>>({})
|
||||
const modelSearchQuery = ref('')
|
||||
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('')
|
||||
|
||||
// Computed properties
|
||||
const supportsModelListing = computed(() => {
|
||||
@@ -45,10 +45,10 @@ export const useConsciousnessStore = defineStore('consciousness', () => {
|
||||
})
|
||||
|
||||
function resetModelSelection() {
|
||||
activeModel.value = ''
|
||||
activeCustomModelName.value = ''
|
||||
expandedDescriptions.value = {}
|
||||
modelSearchQuery.value = ''
|
||||
resetActiveModel()
|
||||
resetActiveCustomModelName()
|
||||
resetExpandedDescriptions()
|
||||
resetModelSearchQuery()
|
||||
}
|
||||
|
||||
async function loadModelsForProvider(provider: string) {
|
||||
@@ -69,6 +69,11 @@ export const useConsciousnessStore = defineStore('consciousness', () => {
|
||||
return !!activeProvider.value && !!activeModel.value
|
||||
})
|
||||
|
||||
function resetState() {
|
||||
resetActiveProvider()
|
||||
resetModelSelection()
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
configured,
|
||||
@@ -89,5 +94,6 @@ export const useConsciousnessStore = defineStore('consciousness', () => {
|
||||
resetModelSelection,
|
||||
loadModelsForProvider,
|
||||
getModelsForProvider,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { 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 = useLocalStorage('settings/discord/enabled', false)
|
||||
const token = useLocalStorage('settings/discord/token', '')
|
||||
const [enabled, resetEnabled] = createResettableLocalStorage('settings/discord/enabled', false)
|
||||
const [token, resetToken] = createResettableLocalStorage('settings/discord/token', '')
|
||||
|
||||
function saveSettings() {
|
||||
// Data is automatically saved to localStorage via useLocalStorage
|
||||
@@ -22,10 +22,17 @@ export const useDiscordStore = defineStore('discord', () => {
|
||||
return !!token.value.trim()
|
||||
})
|
||||
|
||||
function resetState() {
|
||||
resetEnabled()
|
||||
resetToken()
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
return {
|
||||
enabled,
|
||||
token,
|
||||
configured,
|
||||
saveSettings,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { 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 = useLocalStorage(`settings/${moduleName}/enabled`, false)
|
||||
const serverAddress = useLocalStorage(`settings/${moduleName}/server-address`, '')
|
||||
const serverPort = useLocalStorage<number | null>(`settings/${moduleName}/server-port`, defaultPort)
|
||||
const username = useLocalStorage(`settings/${moduleName}/username`, '')
|
||||
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`, '')
|
||||
|
||||
function saveSettings() {
|
||||
configurator.updateFor(moduleName, {
|
||||
@@ -22,10 +22,18 @@ export function createGamingModuleStore(moduleName: string, defaultPort: number)
|
||||
})
|
||||
}
|
||||
|
||||
function resetState() {
|
||||
resetEnabled()
|
||||
resetServerAddress()
|
||||
resetServerPort()
|
||||
resetUsername()
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
const configured = computed(() => {
|
||||
return !!(serverAddress.value.trim() && username.value.trim() && serverPort.value !== null)
|
||||
})
|
||||
|
||||
return { enabled, serverAddress, serverPort, username, configured, saveSettings }
|
||||
return { enabled, serverAddress, serverPort, username, configured, saveSettings, resetState }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@ import type { TranscriptionProviderWithExtraOptions } from '@xsai-ext/shared-pro
|
||||
import type { WithUnknown } from '@xsai/shared'
|
||||
import type { StreamTranscriptionResult, StreamTranscriptionOptions as XSAIStreamTranscriptionOptions } from '@xsai/stream-transcription'
|
||||
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { generateTranscription } from '@xsai/generate-transcription'
|
||||
import { streamTranscription } from '@xsai/stream-transcription'
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { createResettableLocalStorage, createResettableRef } from '../../utils/resettable'
|
||||
import { useProvidersStore } from '../providers'
|
||||
|
||||
export interface StreamTranscriptionFileInputOptions extends Omit<XSAIStreamTranscriptionOptions, 'file' | 'fileName'> {
|
||||
@@ -44,10 +44,10 @@ export const useHearingStore = defineStore('hearing-store', () => {
|
||||
const { allAudioTranscriptionProvidersMetadata } = storeToRefs(providersStore)
|
||||
|
||||
// State
|
||||
const activeTranscriptionProvider = useLocalStorage('settings/hearing/active-provider', '')
|
||||
const activeTranscriptionModel = useLocalStorage('settings/hearing/active-model', '')
|
||||
const activeCustomModelName = useLocalStorage('settings/hearing/active-custom-model', '')
|
||||
const transcriptionModelSearchQuery = ref('')
|
||||
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('')
|
||||
|
||||
// Computed properties
|
||||
const availableProvidersMetadata = computed(() => allAudioTranscriptionProvidersMetadata.value)
|
||||
@@ -87,6 +87,13 @@ export const useHearingStore = defineStore('hearing-store', () => {
|
||||
return !!activeTranscriptionProvider.value && !!activeTranscriptionModel.value
|
||||
})
|
||||
|
||||
function resetState() {
|
||||
resetActiveTranscriptionProvider()
|
||||
resetActiveTranscriptionModel()
|
||||
resetActiveCustomModelName()
|
||||
resetTranscriptionModelSearchQuery()
|
||||
}
|
||||
|
||||
async function transcription(
|
||||
providerId: string,
|
||||
provider: TranscriptionProviderWithExtraOptions<string, any>,
|
||||
@@ -178,6 +185,7 @@ export const useHearingStore = defineStore('hearing-store', () => {
|
||||
transcription,
|
||||
loadModelsForProvider,
|
||||
getModelsForProvider,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ import type { SpeechProviderWithExtraOptions } from '@xsai-ext/shared-providers'
|
||||
|
||||
import type { VoiceInfo } from '../providers'
|
||||
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { generateSpeech } from '@xsai/generate-speech'
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
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 = useLocalStorage('settings/speech/active-provider', '')
|
||||
const activeSpeechModel = useLocalStorage('settings/speech/active-model', 'eleven_multilingual_v2')
|
||||
const activeSpeechVoiceId = useLocalStorage<string>('settings/speech/voice', '')
|
||||
const activeSpeechVoice = ref<VoiceInfo>()
|
||||
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 pitch = useLocalStorage('settings/speech/pitch', 0)
|
||||
const rate = useLocalStorage('settings/speech/rate', 1)
|
||||
const ssmlEnabled = useLocalStorage('settings/speech/ssml-enabled', false)
|
||||
const isLoadingSpeechProviderVoices = ref(false)
|
||||
const speechProviderError = ref<string | null>(null)
|
||||
const availableVoices = ref<Record<string, VoiceInfo[]>>({})
|
||||
const selectedLanguage = useLocalStorage('settings/speech/language', 'en-US')
|
||||
const modelSearchQuery = ref('')
|
||||
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('')
|
||||
|
||||
// Computed properties
|
||||
const availableSpeechProvidersMetadata = computed(() => allAudioSpeechProvidersMetadata.value)
|
||||
@@ -204,6 +204,21 @@ export const useSpeechStore = defineStore('speech', () => {
|
||||
return !!activeSpeechProvider.value && !!activeSpeechModel.value && !!activeSpeechVoiceId.value
|
||||
})
|
||||
|
||||
function resetState() {
|
||||
resetActiveSpeechProvider()
|
||||
resetActiveSpeechModel()
|
||||
resetActiveSpeechVoiceId()
|
||||
resetActiveSpeechVoice()
|
||||
resetPitch()
|
||||
resetRate()
|
||||
resetSsmlEnabled()
|
||||
resetSelectedLanguage()
|
||||
resetModelSearchQuery()
|
||||
resetAvailableVoices()
|
||||
resetSpeechProviderError()
|
||||
resetIsLoadingSpeechProviderVoices()
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
configured,
|
||||
@@ -234,5 +249,6 @@ export const useSpeechStore = defineStore('speech', () => {
|
||||
loadVoicesForProvider,
|
||||
getVoicesForProvider,
|
||||
generateSSML,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { 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 = useLocalStorage('settings/twitter/enabled', false)
|
||||
const apiKey = useLocalStorage('settings/twitter/api-key', '')
|
||||
const apiSecret = useLocalStorage('settings/twitter/api-secret', '')
|
||||
const accessToken = useLocalStorage('settings/twitter/access-token', '')
|
||||
const accessTokenSecret = useLocalStorage('settings/twitter/access-token-secret', '')
|
||||
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', '')
|
||||
|
||||
function saveSettings() {
|
||||
// Data is automatically saved to localStorage via useLocalStorage
|
||||
@@ -29,6 +29,15 @@ export const useTwitterStore = defineStore('twitter', () => {
|
||||
return !!(apiKey.value.trim() && apiSecret.value.trim() && accessToken.value.trim() && accessTokenSecret.value.trim())
|
||||
})
|
||||
|
||||
function resetState() {
|
||||
resetEnabled()
|
||||
resetApiKey()
|
||||
resetApiSecret()
|
||||
resetAccessToken()
|
||||
resetAccessTokenSecret()
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
return {
|
||||
enabled,
|
||||
apiKey,
|
||||
@@ -37,5 +46,6 @@ export const useTwitterStore = defineStore('twitter', () => {
|
||||
accessTokenSecret,
|
||||
configured,
|
||||
saveSettings,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { ContextMessage } from '@proj-airi/server-sdk'
|
||||
|
||||
import type { ContextPayload } from '../chat'
|
||||
|
||||
import { useBroadcastChannel } from '@vueuse/core'
|
||||
import { watch } from 'vue'
|
||||
|
||||
import type { ContextPayload } from '../chat'
|
||||
import { CONTEXT_CHANNEL_NAME, useChatStore } from '../chat'
|
||||
import { useModsChannelServerStore } from '../mods/api/channel-server'
|
||||
|
||||
|
||||
@@ -2,11 +2,12 @@ import type { DisplayModel } from './display-models'
|
||||
|
||||
import messages from '@proj-airi/i18n/locales'
|
||||
|
||||
import { useEventListener, useLocalStorage } from '@vueuse/core'
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import { converter } from 'culori'
|
||||
import { defineStore } from 'pinia'
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { onMounted, watch } from 'vue'
|
||||
|
||||
import { createResettableLocalStorage, createResettableRef } from '../utils/resettable'
|
||||
import { useAudioDevice } from './audio'
|
||||
import { DisplayModelFormat, useDisplayModelsStore } from './display-models'
|
||||
|
||||
@@ -37,12 +38,12 @@ const getHueFrom = (color?: string) => color ? convert(color)?.h : DEFAULT_THEME
|
||||
export const useSettings = defineStore('settings', () => {
|
||||
const displayModelsStore = useDisplayModelsStore()
|
||||
|
||||
const language = useLocalStorage('settings/language', '')
|
||||
const [language, resetLanguage] = createResettableLocalStorage('settings/language', '')
|
||||
|
||||
const stageModelSelected = useLocalStorage<string | undefined>('settings/stage/model', 'preset-live2d-1')
|
||||
const stageModelSelectedDisplayModel = ref<DisplayModel | undefined>()
|
||||
const stageModelSelectedUrl = ref<string>()
|
||||
const stageModelRenderer = ref<'live2d' | 'vrm' | 'disabled'>()
|
||||
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)
|
||||
|
||||
async function updateStageModel() {
|
||||
if (!stageModelSelected.value) {
|
||||
@@ -96,20 +97,20 @@ export const useSettings = defineStore('settings', () => {
|
||||
}
|
||||
})
|
||||
|
||||
const stageViewControlsEnabled = ref(false)
|
||||
const [stageViewControlsEnabled, resetStageViewControlsEnabled] = createResettableRef(false)
|
||||
|
||||
const live2dDisableFocus = useLocalStorage('settings/live2d/disable-focus', false)
|
||||
const live2dIdleAnimationEnabled = useLocalStorage('settings/live2d/idle-animation-enabled', true)
|
||||
const live2dAutoBlinkEnabled = useLocalStorage('settings/live2d/auto-blink-enabled', true)
|
||||
const live2dShadowEnabled = useLocalStorage('settings/live2d/shadow-enabled', true)
|
||||
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 [live2dShadowEnabled, resetLive2dShadowEnabled] = createResettableLocalStorage('settings/live2d/shadow-enabled', true)
|
||||
|
||||
const disableTransitions = useLocalStorage('settings/disable-transitions', true)
|
||||
const usePageSpecificTransitions = useLocalStorage('settings/use-page-specific-transitions', true)
|
||||
const [disableTransitions, resetDisableTransitions] = createResettableLocalStorage('settings/disable-transitions', true)
|
||||
const [usePageSpecificTransitions, resetUsePageSpecificTransitions] = createResettableLocalStorage('settings/use-page-specific-transitions', true)
|
||||
|
||||
const themeColorsHue = useLocalStorage('settings/theme/colors/hue', DEFAULT_THEME_COLORS_HUE)
|
||||
const themeColorsHueDynamic = useLocalStorage('settings/theme/colors/hue-dynamic', false)
|
||||
const [themeColorsHue, resetThemeColorsHue] = createResettableLocalStorage('settings/theme/colors/hue', DEFAULT_THEME_COLORS_HUE)
|
||||
const [themeColorsHueDynamic, resetThemeColorsHueDynamic] = createResettableLocalStorage('settings/theme/colors/hue-dynamic', false)
|
||||
|
||||
const allowVisibleOnAllWorkspaces = useLocalStorage('settings/allow-visible-on-all-workspaces', true)
|
||||
const [allowVisibleOnAllWorkspaces, resetAllowVisibleOnAllWorkspaces] = createResettableLocalStorage('settings/allow-visible-on-all-workspaces', true)
|
||||
|
||||
function getLanguage() {
|
||||
let language = localStorage.getItem('settings/language')
|
||||
@@ -158,6 +159,33 @@ export const useSettings = defineStore('settings', () => {
|
||||
return hueDifference < 0.01 || hueDifference > 359.99
|
||||
}
|
||||
|
||||
async function resetState() {
|
||||
if (stageModelSelectedUrl.value)
|
||||
URL.revokeObjectURL(stageModelSelectedUrl.value)
|
||||
|
||||
resetLanguage()
|
||||
resetStageModelSelected()
|
||||
resetStageModelSelectedDisplayModel()
|
||||
resetStageModelSelectedUrl()
|
||||
resetStageModelRenderer()
|
||||
resetStageViewControlsEnabled()
|
||||
|
||||
resetLive2dDisableFocus()
|
||||
resetLive2dIdleAnimationEnabled()
|
||||
resetLive2dAutoBlinkEnabled()
|
||||
resetLive2dShadowEnabled()
|
||||
|
||||
resetDisableTransitions()
|
||||
resetUsePageSpecificTransitions()
|
||||
|
||||
resetThemeColorsHue()
|
||||
resetThemeColorsHueDynamic()
|
||||
|
||||
resetAllowVisibleOnAllWorkspaces()
|
||||
|
||||
await updateStageModel()
|
||||
}
|
||||
|
||||
onMounted(() => language.value = getLanguage())
|
||||
|
||||
return {
|
||||
@@ -185,14 +213,15 @@ export const useSettings = defineStore('settings', () => {
|
||||
isColorSelectedForPrimary,
|
||||
initializeStageModel,
|
||||
updateStageModel,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
export const useSettingsAudioDevice = defineStore('settings-audio-devices', () => {
|
||||
const { audioInputs, deviceConstraints, selectedAudioInput: selectedAudioInputNonPersist, startStream, stopStream, stream, askPermission } = useAudioDevice()
|
||||
|
||||
const selectedAudioInputPersist = useLocalStorage('settings/audio/input', selectedAudioInputNonPersist.value)
|
||||
const selectedAudioInputEnabledPersist = useLocalStorage('settings/audio/input/enabled', false)
|
||||
const [selectedAudioInputPersist, resetSelectedAudioInputPersist] = createResettableLocalStorage('settings/audio/input', selectedAudioInputNonPersist.value)
|
||||
const [selectedAudioInputEnabledPersist, resetSelectedAudioInputEnabledPersist] = createResettableLocalStorage('settings/audio/input/enabled', false)
|
||||
|
||||
watch(selectedAudioInputPersist, (newValue) => {
|
||||
selectedAudioInputNonPersist.value = newValue
|
||||
@@ -216,6 +245,13 @@ export const useSettingsAudioDevice = defineStore('settings-audio-devices', () =
|
||||
}
|
||||
})
|
||||
|
||||
function resetState() {
|
||||
resetSelectedAudioInputPersist()
|
||||
selectedAudioInputNonPersist.value = ''
|
||||
resetSelectedAudioInputEnabledPersist()
|
||||
stopStream()
|
||||
}
|
||||
|
||||
return {
|
||||
audioInputs,
|
||||
deviceConstraints,
|
||||
@@ -227,5 +263,6 @@ export const useSettingsAudioDevice = defineStore('settings-audio-devices', () =
|
||||
askPermission,
|
||||
startStream,
|
||||
stopStream,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
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
|
||||
}
|
||||
@@ -75,4 +75,4 @@
|
||||
"tinyexec": "^1.0.2",
|
||||
"vscode-ext-gen": "^1.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user