mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-15 11:58:34 +08:00
- Extract create/edit modal into ChannelEditModal.vue (defineAsyncComponent), shrinking Channels.vue from 1438 to 370 lines and dropping ~30KB from the initial route chunk. - Move side-effect logic into composables: useWeixinQrcodePoll (QR + 2s status poll, auto-cleanup) and useWecomBotAuth (lazy SDK script with module-level promise dedupe). Pure config-JSON helpers move to utils/channelConfigJson.ts. - Switch i18n locales from static imports to dynamic import keyed by current locale; applyLocale becomes async to avoid first-render flicker. - /channels route opts into keep-alive (meta.keepAlive=true). Channels.vue pauses status polling in onDeactivated and resumes in onActivated, with an isActive guard to prevent late-resolving timers from leaking after navigation. - Initial load goes from serial 3-RTT to Promise.all + 4-card el-skeleton.
59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
import { createI18n } from 'vue-i18n'
|
|
import { ref } from 'vue'
|
|
import { settingsApi } from '@/api'
|
|
|
|
export type AppLocale = 'zh-CN' | 'en-US'
|
|
|
|
const STORAGE_KEY = 'mateclaw_locale'
|
|
const DEFAULT_LOCALE: AppLocale = 'zh-CN'
|
|
|
|
export const currentLocale = ref<AppLocale>(DEFAULT_LOCALE)
|
|
|
|
export const i18n = createI18n({
|
|
legacy: false,
|
|
locale: DEFAULT_LOCALE,
|
|
fallbackLocale: DEFAULT_LOCALE,
|
|
messages: {} as Record<AppLocale, any>,
|
|
})
|
|
|
|
const loadedLocales = new Set<AppLocale>()
|
|
|
|
// Each locale dictionary is ~78KB. Splitting them into their own chunks keeps
|
|
// the entry bundle ~150KB lighter — only the active locale is fetched on cold
|
|
// start, the other one only when the user switches language.
|
|
async function loadLocaleMessages(locale: AppLocale) {
|
|
if (loadedLocales.has(locale)) return
|
|
const messages = locale === 'zh-CN'
|
|
? (await import('./locales/zh-CN')).default
|
|
: (await import('./locales/en-US')).default
|
|
i18n.global.setLocaleMessage(locale, messages)
|
|
loadedLocales.add(locale)
|
|
}
|
|
|
|
function normalizeLocale(locale?: string | null): AppLocale {
|
|
if (locale === 'en' || locale === 'en-US') {
|
|
return 'en-US'
|
|
}
|
|
return 'zh-CN'
|
|
}
|
|
|
|
export async function applyLocale(locale?: string | null) {
|
|
const normalized = normalizeLocale(locale)
|
|
// Must finish loading messages before flipping currentLocale, otherwise the
|
|
// first render after a switch would show the i18n keys verbatim.
|
|
await loadLocaleMessages(normalized)
|
|
currentLocale.value = normalized
|
|
i18n.global.locale.value = normalized
|
|
localStorage.setItem(STORAGE_KEY, normalized)
|
|
return normalized
|
|
}
|
|
|
|
export async function initializeLocale() {
|
|
try {
|
|
const res: any = await settingsApi.getLanguage()
|
|
return await applyLocale(res.data)
|
|
} catch {
|
|
return await applyLocale(localStorage.getItem(STORAGE_KEY))
|
|
}
|
|
}
|