diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 75363f36..4e403417 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -7,8 +7,9 @@ */ import { i18n } from '@lingui/core'; -import { detectLocale } from '@/lib/ISOLanguageUtil.ts'; +import { detectLocale, SELECTED_LANGUAGE_CODE_KEY } from '@/lib/ISOLanguageUtil.ts'; import localesConfig from '@/i18n/locales.json'; +import { AppStorage } from '@/lib/storage/AppStorage.ts'; export const i18nResources = localesConfig.locales; @@ -21,6 +22,8 @@ export async function loadCatalog(locale: string): Promise { const { messages } = await import(`./locales/${localeToLoad}.po`); i18n.loadAndActivate({ locale: localeToLoad, messages }); + + AppStorage.local.setItem(SELECTED_LANGUAGE_CODE_KEY, localeToLoad); } export async function initializeLocalization(): Promise { diff --git a/src/lib/ISOLanguageUtil.ts b/src/lib/ISOLanguageUtil.ts index 73a1f7b6..8ebe2959 100644 --- a/src/lib/ISOLanguageUtil.ts +++ b/src/lib/ISOLanguageUtil.ts @@ -8,11 +8,14 @@ import { ISOLanguage, IsoLanguages } from '@/base/IsoLanguages.ts'; import { i18nResources } from '@/i18n'; +import { AppStorage } from '@/lib/storage/AppStorage.ts'; export type LanguageObject = ISOLanguage & { orgCode: string; isoCode: string }; export const DEFAULT_LANGUAGE = 'en'; +export const SELECTED_LANGUAGE_CODE_KEY = 'i18n:selected-language'; + // source: https://github.com/i18next/i18next/blob/485b4ec8183952b3de8fe5e79dff6467c3afd9d3/src/i18next.js#L561 const RTL_LANGUAGES = [ 'ar', @@ -140,7 +143,11 @@ export function getLanguageReadingDirection(code: string): 'ltr' | 'rtl' { } export function detectLocale(): string { - const normalizedLanguageCodes = getPreferredISOLanguageCodes() + const storedLanguage = AppStorage.local.getItem(SELECTED_LANGUAGE_CODE_KEY); + const preferredLanguages = getPreferredISOLanguageCodes(); + const languageCodes = [storedLanguage, ...preferredLanguages]; + + const normalizedLanguageCodes = languageCodes .filter((code) => code !== null) .filter((code) => getISOLanguage(code)) .filter((code) => i18nResources.includes(code as (typeof i18nResources)[number]));