|
1 | 1 | import { type App } from "vue"; |
2 | 2 | import { createI18n } from "vue-i18n"; |
3 | 3 | import { locale } from "@/stores/settings"; |
| 4 | +import type { Locale } from "vue-i18n"; |
4 | 5 |
|
5 | | -import messages from "@intlify/unplugin-vue-i18n/messages"; |
| 6 | +const localesMap = Object.fromEntries( |
| 7 | + Object.entries(import.meta.glob("../../locales/*.yml")).map(([path, loadLocale]) => [ |
| 8 | + path.match(/([\w-]*)\.yml$/)?.[1], |
| 9 | + loadLocale, |
| 10 | + ]), |
| 11 | +) as Record<Locale, () => Promise<{ default: Record<string, string> }>>; |
6 | 12 |
|
7 | | -const defaultLocale = messages?.hasOwnProperty(navigator.language) |
8 | | - ? navigator.language |
9 | | - : navigator.language.slice(0, 2); |
| 13 | +export const availableLocales = Object.keys(localesMap); |
| 14 | + |
| 15 | +function setI18nLanguage(lang: Locale) { |
| 16 | + i18n.global.locale.value = lang; |
| 17 | + return lang; |
| 18 | +} |
| 19 | + |
| 20 | +const loadedLanguages: string[] = []; |
| 21 | +async function loadLanguage(lang: string): Promise<Locale> { |
| 22 | + if (i18n.global.locale.value === lang) return setI18nLanguage(lang); |
| 23 | + if (loadedLanguages.includes(lang)) return setI18nLanguage(lang); |
| 24 | + |
| 25 | + const messages = await localesMap[lang](); |
| 26 | + i18n.global.setLocaleMessage(lang, messages.default); |
| 27 | + loadedLanguages.push(lang); |
| 28 | + return setI18nLanguage(lang); |
| 29 | +} |
10 | 30 |
|
11 | 31 | const i18n = createI18n({ |
12 | 32 | legacy: false, |
13 | | - locale: locale.value || defaultLocale, |
14 | | - fallbackLocale: "en", |
15 | | - messages, |
| 33 | + locale: "", |
| 34 | + messages: {}, |
16 | 35 | }); |
17 | 36 |
|
18 | | -watch(locale, (value) => { |
19 | | - i18n.global.locale.value = value || defaultLocale; |
| 37 | +watchEffect(() => { |
| 38 | + loadLanguage( |
| 39 | + locale.value || |
| 40 | + [navigator.language, navigator.language.slice(0, 2)].find((l) => availableLocales.includes(l)) || |
| 41 | + "en", |
| 42 | + ); |
20 | 43 | }); |
21 | 44 |
|
22 | 45 | export const install = (app: App) => app.use(i18n); |
|
0 commit comments