Files
NotesAgentic/frontend/src/stores/chatPreferences.ts
T

24 lines
1.5 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref } from 'vue'
export interface ChatPreferences { persona: string; presetDialogue: string; aiAvatar: string; userAvatar: string }
const storageKey = 'chat-persona-preferences-v1'
const empty = (): ChatPreferences => ({ persona: '', presetDialogue: '', aiAvatar: '', userAvatar: '' })
export function validAvatar(value: unknown): value is string {
return typeof value === 'string' && (value === '' || (value.length <= 710000 && /^data:image\/(png|jpeg|webp);base64,[A-Za-z0-9+/=]+$/.test(value)))
}
function validate(value: ChatPreferences) {
if (typeof value.persona !== 'string' || typeof value.presetDialogue !== 'string' || value.persona.length > 16000 || value.presetDialogue.length > 32000 || !validAvatar(value.aiAvatar) || !validAvatar(value.userAvatar)) throw new Error('人设、预设对话或头像格式无效 / Invalid chat preferences')
return {persona:value.persona, presetDialogue:value.presetDialogue, aiAvatar:value.aiAvatar, userAvatar:value.userAvatar}
}
export const useChatPreferences = defineStore('chatPreferences', () => {
const settings = ref<ChatPreferences>(empty())
try { const stored = localStorage.getItem(storageKey); if (stored) settings.value = validate(JSON.parse(stored)) } catch { /* Invalid or unavailable local settings use defaults. */ }
function save(value: ChatPreferences) {
const next = validate(value)
localStorage.setItem(storageKey, JSON.stringify(next))
settings.value = next
}
return { settings, save }
})