Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 31 additions & 26 deletions dashboard/src/i18n/composables.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ref, computed } from 'vue';
import { translations as staticTranslations } from './translations';
import { SUPPORTED_LOCALES, isLocaleSupported, loadLocaleTranslations } from './translations';
import type { Locale } from './types';

// 全局状态
Expand All @@ -10,35 +10,35 @@ const translations = ref<Record<string, any>>({});
* 初始化i18n系统
*/
export async function initI18n(locale: Locale = 'zh-CN') {
currentLocale.value = locale;

// 加载静态翻译数据
loadTranslations(locale);
// 加载翻译数据并获取实际生效语言(可能回退到zh-CN)
const effectiveLocale = await loadTranslations(locale);
currentLocale.value = effectiveLocale;
}

/**
* 加载翻译数据(现在从静态导入获取)
* 加载翻译数据并返回实际生效语言
*/
function loadTranslations(locale: Locale) {
async function loadTranslations(locale: Locale): Promise<Locale> {
try {
const data = staticTranslations[locale];
if (data) {
translations.value = data;
} else {
console.warn(`Translations not found for locale: ${locale}`);
// 回退到中文
if (locale !== 'zh-CN') {
console.log('Falling back to zh-CN');
translations.value = staticTranslations['zh-CN'];
}
}
const data = await loadLocaleTranslations(locale);
translations.value = data;
return locale;
} catch (error) {
console.error(`Failed to load translations for ${locale}:`, error);

// 回退到中文
if (locale !== 'zh-CN') {
console.log('Falling back to zh-CN');
translations.value = staticTranslations['zh-CN'];
try {
console.log('Falling back to zh-CN');
translations.value = await loadLocaleTranslations('zh-CN');
return 'zh-CN';
} catch (fallbackError) {
console.error('Failed to load fallback translations for zh-CN:', fallbackError);
}
}

// 保持原有语言状态不变,避免状态与已加载翻译不一致
return currentLocale.value;
}
}

Expand Down Expand Up @@ -84,17 +84,22 @@ export function useI18n() {
// 切换语言
const setLocale = async (newLocale: Locale) => {
if (newLocale !== currentLocale.value) {
currentLocale.value = newLocale;
loadTranslations(newLocale);
const previousLocale = currentLocale.value;
const effectiveLocale = await loadTranslations(newLocale);
currentLocale.value = effectiveLocale;

if (effectiveLocale === previousLocale) {
return;
}

// 保存到localStorage
localStorage.setItem('astrbot-locale', newLocale);
localStorage.setItem('astrbot-locale', effectiveLocale);

// 触发自定义事件,通知相关页面重新加载配置数据
// 这是因为插件适配器的 i18n 数据是通过后端 API 注入的,
// 需要根据 Accept-Language 头重新获取
window.dispatchEvent(new CustomEvent('astrbot-locale-changed', {
detail: { locale: newLocale }
detail: { locale: effectiveLocale }
}));
}
};
Expand All @@ -103,7 +108,7 @@ export function useI18n() {
const locale = computed(() => currentLocale.value);

// 获取可用语言列表
const availableLocales: Locale[] = ['zh-CN', 'en-US', 'ru-RU'];
const availableLocales: Locale[] = [...SUPPORTED_LOCALES];

// 检查是否已加载
const isLoaded = computed(() => Object.keys(translations.value).length > 0);
Expand Down Expand Up @@ -221,7 +226,7 @@ function deepMerge(target: Record<string, any>, source: Record<string, any>) {
export async function setupI18n() {
// 从localStorage获取保存的语言设置
const savedLocale = localStorage.getItem('astrbot-locale') as Locale;
const initialLocale = savedLocale && ['zh-CN', 'en-US', 'ru-RU'].includes(savedLocale)
const initialLocale = savedLocale && isLocaleSupported(savedLocale)
? savedLocale
: 'zh-CN';

Expand Down
Loading
Loading