Newer
Older
import Polyglot from 'node-polyglot'
import { App, computed, reactive } from 'vue'
import { has } from '@/utilities'
import { range } from 'lodash'
import { parseISO } from 'date-fns'
const STORAGE_KEY = 'aura:locale'
const DEFAULT_LOCALE =
localStorage.getItem(STORAGE_KEY) ?? import.meta.env.VUE_APP_DEFAULT_LOCALE ?? 'de'
const locales = Object.fromEntries(
Object.entries(import.meta.glob('./??.js', { import: 'default', eager: true })).map(
([key, locale]) => [(/([a-z]+)?.[jt]s$/.exec(key) as string[])[1], locale],
function createPolyglot(locale: string) {
return new Polyglot({ phrases: locales[locale] })
}
const state = reactive({
locale: DEFAULT_LOCALE,
polyglot: createPolyglot(DEFAULT_LOCALE),
})
const locale = computed({
get() {
return state.locale
},
set(newLocale) {
updateLocale(newLocale)
},
})
const availableLocales = computed(() => Object.keys(locales))
function t(phrase: string, context = {}): string {
return state.polyglot.t(phrase, context)
}
// IMHO this is not the best naming for this function, but it is consistent
// with the vue-i18n library that most people working on vue applications
// will be familiar with.
function te(phrase: string): boolean {
return state.polyglot.has(phrase)
}
function updateLocale(newLocale: string): void {
if (has(locales, newLocale)) {
state.locale = newLocale
state.polyglot = createPolyglot(newLocale)
localStorage.setItem(STORAGE_KEY, newLocale)
} else {
throw new Error(`Unknown locale code for language: ${newLocale}`)
}
}
export function getLanguageName(languageCode: string) {
return new Intl.DisplayNames([languageCode], { type: 'language' }).of(languageCode)
}
/**
* Returns a list of weekday names starting on monday.
* @param locale string
*/
export function getDayNames(locale: string) {
return range(7).map((i) =>
// January, 1st 2018 is a monday
parseISO(`2018-01-0${i + 1}`).toLocaleString(locale, { weekday: 'long' }),
)
}
export function getMonthNames(locale: string) {
return range(12).map((i) =>
parseISO(`2018-${(i + 1).toString().padStart(2, '0')}-01`).toLocaleString(locale, {
month: 'long',
}),
)
}
const dayNames = computed(() => getDayNames(locale.value))
const monthNames = computed(() => getMonthNames(locale.value))
export function useI18n() {
// This interface is intentionally similar to the one provided by
// Vue I18n to make it easier for newcomers already familiar with it
// and to ease a potential future migration.
// See https://vue-i18n.intlify.dev/guide/advanced/composition.html#basic-usage
return {
t,
te,
locale,
dayNames,
monthNames,
availableLocales,
}
}
export const TranslationPlugin = {
install(app: App) {
app.config.globalProperties.$activeLocale = () => locale.value
app.config.globalProperties.$locale = updateLocale
app.config.globalProperties.$t = t
app.config.globalProperties.$te = te