Merge pull request #988 from dermotduffy/language-wrong2

Fix language choice when localStorage language may be unavailable
This commit is contained in:
Dermot Duffy
2023-03-04 14:42:49 -08:00
committed by GitHub
2 changed files with 41 additions and 32 deletions
+1 -1
View File
@@ -1159,7 +1159,7 @@ class FrigateCard extends LitElement {
.initializeMultipleIfNecessary({ .initializeMultipleIfNecessary({
// Caution: Ensure nothing in this set of initializers requires // Caution: Ensure nothing in this set of initializers requires
// languages since they will not yet have been initialized. // languages since they will not yet have been initialized.
[InitializationAspect.LANGUAGES]: async () => loadLanguages, [InitializationAspect.LANGUAGES]: async () => loadLanguages(hass),
[InitializationAspect.SIDE_LOAD_ELEMENTS]: async () => [InitializationAspect.SIDE_LOAD_ELEMENTS]: async () =>
sideLoadHomeAssistantElements, sideLoadHomeAssistantElements,
}) })
+34 -25
View File
@@ -1,57 +1,66 @@
import { HomeAssistant } from 'custom-card-helpers';
import * as en from './languages/en.json'; import * as en from './languages/en.json';
const DEFAULT_LANG = 'en' as const;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const languages: Record<string, any> = { const languages: Record<string, any> = {
// English as always loaded as it's the fallback language that will be used // English as always loaded as it's the fallback language that will be used
// when translations are not found or before they are loaded (via // when translations are not found or before they are loaded (via
// loadLanguages()). // loadLanguages()).
en: en, [DEFAULT_LANG]: en,
} };
// The language is calculated and stored once, then re-used to avoid needing to
// repeat the lookups and to ensure minimal information needs to be plumbed
// through on each localization call.
let frigateCardLanguage: string | undefined;
/** /**
* Get the configured language. * Get the configured language.
*/ */
export function getLanguage(): string { export function getLanguage(hass?: HomeAssistant): string {
const canonicalizeLanguage = (language?: string | null): string | null => { const canonicalizeLanguage = (language: string): string => {
if (!language) {
return null;
}
return language.replace('-', '_'); return language.replace('-', '_');
}; };
// Try the HA language first... // Try the hass language first...
let lang: string | null = null; const hassLanguage = hass?.language ?? hass?.selectedLanguage;
const HALanguage = localStorage.getItem('selectedLanguage'); if (hassLanguage) {
if (HALanguage) { return canonicalizeLanguage(hassLanguage);
const selectedLanguage = canonicalizeLanguage(JSON.parse(HALanguage));
if (selectedLanguage) {
lang = selectedLanguage;
} }
// Then the language that hass may have stored locally.
const storageLanguage = localStorage.getItem('selectedLanguage');
if (storageLanguage) {
return canonicalizeLanguage(JSON.parse(storageLanguage));
} }
// Then fall back to the browser language. // Then fall back to the browser language.
if (!lang) {
for (const language of navigator.languages) { for (const language of navigator.languages) {
const canonicalLanguage = canonicalizeLanguage(language); const canonicalLanguage = canonicalizeLanguage(language);
if (canonicalLanguage && canonicalLanguage in languages) { if (canonicalLanguage && canonicalLanguage in languages) {
lang = language; return canonicalLanguage;
} }
} }
} return DEFAULT_LANG;
return lang || 'en';
} }
/** /**
* Load required languages. * Load required languages.
*/ */
export const loadLanguages = async (): Promise<void> => { export const loadLanguages = async (hass: HomeAssistant): Promise<void> => {
const lang = getLanguage(); const lang = getLanguage(hass);
if (lang === 'it') { if (lang === 'it') {
languages['it'] = await import('./languages/it.json'); languages['it'] = await import('./languages/it.json');
} else if (lang === 'pt_BR') { } else if (lang === 'pt_BR') {
languages['pt_BR'] = await import('./languages/pt-BR.json'); languages['pt_BR'] = await import('./languages/pt-BR.json');
} }
if (lang) {
frigateCardLanguage = lang;
} }
};
/** /**
* Get a localized version of a given string key. * Get a localized version of a given string key.
@@ -61,16 +70,16 @@ export const loadLanguages = async (): Promise<void> => {
* @returns * @returns
*/ */
export function localize(string: string, search = '', replace = ''): string { export function localize(string: string, search = '', replace = ''): string {
const lang = getLanguage();
let translated = ''; let translated = '';
try { try {
translated = string.split('.').reduce((o, i) => o[i], languages[lang]); translated = string
} catch (_) { .split('.')
} .reduce((o, i) => o[i], languages[frigateCardLanguage ?? DEFAULT_LANG]);
} catch (_) {}
if (!translated) { if (!translated) {
translated = string.split('.').reduce((o, i) => o[i], languages['en']); translated = string.split('.').reduce((o, i) => o[i], languages[DEFAULT_LANG]);
} }
if (search !== '' && replace !== '') { if (search !== '' && replace !== '') {