- Reorganize project structure with new electron and shared directories - Add comprehensive i18n support with Chinese, English, and Japanese locales - Update build configurations and TypeScript paths for new structure - Add various UI components including chat interface and task management - Include Windows release binaries and localization files - Update dependencies and fix import paths throughout the codebase
129 lines
3.7 KiB
TypeScript
129 lines
3.7 KiB
TypeScript
import { defineStore } from 'pinia';
|
||
import { i18n, setLanguage, getLanguage, type LanguageCode } from '@src/i18n';
|
||
import { SUPPORTED_LANGUAGES, SUPPORTED_LANGUAGE_CODES } from '@src/i18n/constants';
|
||
import { resolveSupportedLanguage, detectSystemLanguage } from '@src/i18n/resolver';
|
||
|
||
// 持久化键
|
||
const STORAGE_KEY = 'diona-language';
|
||
|
||
interface LocaleState {
|
||
language: LanguageCode;
|
||
initialized: boolean;
|
||
}
|
||
|
||
export const useLocaleStore = defineStore('locale', {
|
||
state: (): LocaleState => ({
|
||
language: 'zh',
|
||
initialized: false,
|
||
}),
|
||
|
||
getters: {
|
||
currentLanguage: (state) => state.language,
|
||
isChinese: (state) => state.language === 'zh',
|
||
isEnglish: (state) => state.language === 'en',
|
||
isJapanese: (state) => state.language === 'ja',
|
||
languageLabel: (state) => {
|
||
const lang = SUPPORTED_LANGUAGES.find(l => l.code === state.language);
|
||
return lang?.label || '中文';
|
||
},
|
||
},
|
||
|
||
actions: {
|
||
/**
|
||
* 初始化语言设置
|
||
* 优先级:持久化设置 > 系统语言 > 默认中文
|
||
*/
|
||
async init() {
|
||
if (this.initialized) return;
|
||
|
||
try {
|
||
// 1. 尝试从 localStorage 读取持久化设置
|
||
const saved = localStorage.getItem(STORAGE_KEY);
|
||
let lang: LanguageCode = 'zh';
|
||
|
||
if (saved && SUPPORTED_LANGUAGE_CODES.includes(saved as LanguageCode)) {
|
||
lang = saved as LanguageCode;
|
||
} else {
|
||
// 2. 检测系统语言
|
||
lang = detectSystemLanguage();
|
||
}
|
||
|
||
// 3. 应用语言设置
|
||
await this.setLanguage(lang, false); // 不持久化,因为已经是持久化的值
|
||
|
||
this.initialized = true;
|
||
} catch (error) {
|
||
console.error('Failed to initialize locale store:', error);
|
||
// 降级处理:使用默认中文
|
||
await this.setLanguage('zh', false);
|
||
this.initialized = true;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 设置语言
|
||
* @param language 目标语言代码
|
||
* @param persist 是否持久化到 localStorage(默认为 true)
|
||
*/
|
||
async setLanguage(language: LanguageCode, persist: boolean = true) {
|
||
// 验证语言代码有效性
|
||
const resolvedLang = resolveSupportedLanguage(language);
|
||
|
||
if (resolvedLang === this.language) {
|
||
return; // 语言未变化
|
||
}
|
||
|
||
try {
|
||
// 1. 更新 i18n 实例
|
||
await setLanguage(resolvedLang, i18n);
|
||
|
||
// 2. 更新 store 状态
|
||
this.language = resolvedLang;
|
||
|
||
// 3. 持久化到 localStorage
|
||
if (persist) {
|
||
localStorage.setItem(STORAGE_KEY, resolvedLang);
|
||
}
|
||
|
||
// 4. 触发语言变化事件(供其他组件监听)
|
||
window.dispatchEvent(new CustomEvent('language-changed', {
|
||
detail: { language: resolvedLang }
|
||
}));
|
||
} catch (error) {
|
||
console.error('Failed to set language:', error);
|
||
throw error;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 切换语言(轮换支持的语言)
|
||
*/
|
||
async toggleLanguage() {
|
||
const currentIndex = SUPPORTED_LANGUAGE_CODES.indexOf(this.language);
|
||
const nextIndex = (currentIndex + 1) % SUPPORTED_LANGUAGE_CODES.length;
|
||
const nextLanguage = SUPPORTED_LANGUAGE_CODES[nextIndex];
|
||
await this.setLanguage(nextLanguage);
|
||
},
|
||
|
||
/**
|
||
* 重置为系统语言
|
||
*/
|
||
async resetToSystemLanguage() {
|
||
const systemLang = detectSystemLanguage();
|
||
await this.setLanguage(systemLang);
|
||
},
|
||
|
||
/**
|
||
* 同步 i18n 实例与 store 状态(用于外部更改的情况)
|
||
*/
|
||
syncWithI18n() {
|
||
const currentLang = getLanguage();
|
||
if (currentLang !== this.language) {
|
||
this.language = currentLang as LanguageCode;
|
||
}
|
||
},
|
||
},
|
||
});
|
||
|
||
// 导出类型
|
||
export type { LanguageCode }; |