2022-07-04 22:52:53 +00:00
|
|
|
import type { InitModule } from '~/types'
|
|
|
|
|
2022-04-17 22:43:58 +00:00
|
|
|
import { usePreferredLanguages } from '@vueuse/core'
|
2022-09-08 14:32:45 +00:00
|
|
|
import { nextTick, watch } from 'vue'
|
|
|
|
import { createI18n } from 'vue-i18n'
|
|
|
|
|
|
|
|
import locales from '~/locales.json'
|
2022-04-18 08:24:47 +00:00
|
|
|
import store from '~/store'
|
2022-04-17 22:43:58 +00:00
|
|
|
|
2022-09-08 14:32:45 +00:00
|
|
|
import useLogger from '~/composables/useLogger'
|
|
|
|
|
|
|
|
const logger = useLogger()
|
|
|
|
|
2022-04-18 08:24:47 +00:00
|
|
|
const defaultLanguage = store.state.ui.currentLanguage ?? 'en_US'
|
2022-09-08 14:32:45 +00:00
|
|
|
export const SUPPORTED_LOCALES = locales.reduce((map: Record<string, string>, locale) => {
|
2022-04-18 08:24:47 +00:00
|
|
|
map[locale.code] = locale.label
|
|
|
|
return map
|
|
|
|
}, {})
|
2022-04-17 22:43:58 +00:00
|
|
|
|
2022-09-08 14:32:45 +00:00
|
|
|
export const i18n = createI18n<false>({
|
|
|
|
formatFallbackMessages: true,
|
|
|
|
globalInjection: true,
|
|
|
|
fallbackLocale: 'en',
|
|
|
|
legacy: false,
|
|
|
|
locale: 'en'
|
2022-04-18 08:24:47 +00:00
|
|
|
})
|
2022-04-17 22:43:58 +00:00
|
|
|
|
2022-09-08 14:32:45 +00:00
|
|
|
export const setI18nLanguage = async (locale: string) => {
|
|
|
|
if (!Object.keys(SUPPORTED_LOCALES).includes(locale)) {
|
|
|
|
throw new Error(`Unsupported locale: ${locale}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
// load locale messages
|
|
|
|
if (!i18n.global.availableLocales.includes(locale)) {
|
|
|
|
try {
|
|
|
|
const { default: messages } = await import(`./locales/${locale}.json`)
|
|
|
|
i18n.global.setLocaleMessage(locale, messages)
|
|
|
|
await nextTick()
|
|
|
|
} catch (error) {
|
|
|
|
logger.warn(`Unsupported locale: ${locale}`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// set locale
|
|
|
|
i18n.global.locale.value = locale
|
|
|
|
document.querySelector('html')?.setAttribute('lang', locale)
|
|
|
|
}
|
|
|
|
|
|
|
|
export const install: InitModule = async ({ store, app }) => {
|
|
|
|
app.use(i18n)
|
2022-04-17 22:43:58 +00:00
|
|
|
|
|
|
|
// Set default language
|
|
|
|
if (!store.state.ui.selectedLanguage) {
|
|
|
|
// NOTE: We're selecting the language only once, hence we don't need to make it reactive
|
|
|
|
const languages = usePreferredLanguages().value.map((code) => {
|
|
|
|
return code.replace(/-/g, '_')
|
|
|
|
})
|
|
|
|
|
2022-09-08 14:32:45 +00:00
|
|
|
let language = Object.keys(SUPPORTED_LOCALES).find(code => {
|
2022-04-17 22:43:58 +00:00
|
|
|
return languages.includes(code)
|
|
|
|
})
|
|
|
|
|
|
|
|
if (!language) {
|
2022-09-08 14:32:45 +00:00
|
|
|
language = Object.keys(SUPPORTED_LOCALES).find(code => {
|
2022-04-17 22:43:58 +00:00
|
|
|
return languages.map(lang => lang.split('_')[0]).includes(code.split('_')[0])
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-09-08 14:32:45 +00:00
|
|
|
await store.dispatch('ui/currentLanguage', language ?? defaultLanguage)
|
|
|
|
await setI18nLanguage(language ?? defaultLanguage)
|
2022-04-17 22:43:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Handle language change
|
2022-09-08 14:32:45 +00:00
|
|
|
watch(() => store.state.ui.currentLanguage, async (locale) => {
|
|
|
|
await store.dispatch('ui/currentLanguage', locale)
|
|
|
|
await setI18nLanguage(locale)
|
|
|
|
// TODO (wvffle): Set moment locale
|
|
|
|
// store.commit('ui/momentLocale', 'en')
|
2022-04-17 22:43:58 +00:00
|
|
|
}, { immediate: true })
|
|
|
|
}
|