Dynamically load non-fallback languages.
This commit is contained in:
+11
-1
@@ -8,7 +8,7 @@ import styles from 'rollup-plugin-styles';
|
|||||||
import image from '@rollup/plugin-image';
|
import image from '@rollup/plugin-image';
|
||||||
import replace from '@rollup/plugin-replace';
|
import replace from '@rollup/plugin-replace';
|
||||||
import gitInfo from 'rollup-plugin-git-info';
|
import gitInfo from 'rollup-plugin-git-info';
|
||||||
import { visualizer } from "rollup-plugin-visualizer";
|
import { visualizer } from 'rollup-plugin-visualizer';
|
||||||
|
|
||||||
const watch = process.env.ROLLUP_WATCH === 'true' || process.env.ROLLUP_WATCH === '1';
|
const watch = process.env.ROLLUP_WATCH === 'true' || process.env.ROLLUP_WATCH === '1';
|
||||||
const dev = watch || process.env.DEV === 'true' || process.env.DEV === '1';
|
const dev = watch || process.env.DEV === 'true' || process.env.DEV === '1';
|
||||||
@@ -69,6 +69,16 @@ const config = {
|
|||||||
output: {
|
output: {
|
||||||
entryFileNames: 'frigate-hass-card.js',
|
entryFileNames: 'frigate-hass-card.js',
|
||||||
dir: 'dist',
|
dir: 'dist',
|
||||||
|
chunkFileNames: (chunk) => {
|
||||||
|
// Add "lang-" to the front of the language chunk names for readability.
|
||||||
|
if (
|
||||||
|
chunk.facadeModuleId &&
|
||||||
|
chunk.facadeModuleId.match(/localize\/languages\/.*\.json/)
|
||||||
|
) {
|
||||||
|
return 'lang-[name]-[hash].js';
|
||||||
|
}
|
||||||
|
return '[name]-[hash].js';
|
||||||
|
},
|
||||||
format: 'es',
|
format: 'es',
|
||||||
...(dev && {
|
...(dev && {
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
|
|||||||
+16
-5
@@ -37,7 +37,7 @@ import {
|
|||||||
MEDIA_PLAYER_SUPPORT_BROWSE_MEDIA,
|
MEDIA_PLAYER_SUPPORT_BROWSE_MEDIA,
|
||||||
REPO_URL,
|
REPO_URL,
|
||||||
} from './const.js';
|
} from './const.js';
|
||||||
import { getLanguage, localize } from './localize/localize.js';
|
import { getLanguage, loadLanguages, localize } from './localize/localize.js';
|
||||||
import cardStyle from './scss/card.scss';
|
import cardStyle from './scss/card.scss';
|
||||||
import {
|
import {
|
||||||
Actions,
|
Actions,
|
||||||
@@ -206,7 +206,8 @@ export class FrigateCard extends LitElement {
|
|||||||
protected _boundMouseHandler = throttle(this._mouseHandler.bind(this), 1 * 1000);
|
protected _boundMouseHandler = throttle(this._mouseHandler.bind(this), 1 * 1000);
|
||||||
|
|
||||||
// Whether the card has been successfully initialized.
|
// Whether the card has been successfully initialized.
|
||||||
protected _initialized = false;
|
protected _loadedHAElements = false;
|
||||||
|
protected _loadedLanguages = false;
|
||||||
|
|
||||||
protected _triggers: Map<string, Date> = new Map();
|
protected _triggers: Map<string, Date> = new Map();
|
||||||
protected _untriggerTimerID: number | null = null;
|
protected _untriggerTimerID: number | null = null;
|
||||||
@@ -1101,11 +1102,12 @@ export class FrigateCard extends LitElement {
|
|||||||
* Called before each update.
|
* Called before each update.
|
||||||
*/
|
*/
|
||||||
protected willUpdate(changedProps: PropertyValues): void {
|
protected willUpdate(changedProps: PropertyValues): void {
|
||||||
// Side load the necessary elements if not already initialized.
|
// Side load the necessary elements if not already initialized (do not need
|
||||||
if (!this._initialized) {
|
// to block for the loading to complete).
|
||||||
|
if (!this._loadedHAElements) {
|
||||||
sideLoadHomeAssistantElements().then((success) => {
|
sideLoadHomeAssistantElements().then((success) => {
|
||||||
if (success) {
|
if (success) {
|
||||||
this._initialized = true;
|
this._loadedHAElements = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1244,6 +1246,15 @@ export class FrigateCard extends LitElement {
|
|||||||
* @returns `true` if the element should be updated.
|
* @returns `true` if the element should be updated.
|
||||||
*/
|
*/
|
||||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||||
|
// Load the relevant languages. Cannot do anything until then.
|
||||||
|
if (!this._loadedLanguages) {
|
||||||
|
loadLanguages().then(() => {
|
||||||
|
this._loadedLanguages = true;
|
||||||
|
this.requestUpdate();
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const oldHass = changedProps.get('_hass') as HomeAssistant | undefined;
|
const oldHass = changedProps.get('_hass') as HomeAssistant | undefined;
|
||||||
let shouldUpdate = !oldHass || changedProps.size != 1;
|
let shouldUpdate = !oldHass || changedProps.size != 1;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import * as en from './languages/en.json';
|
import * as en from './languages/en.json';
|
||||||
import * as pt_BR from './languages/pt-BR.json';
|
|
||||||
import * as it from './languages/it.json';
|
|
||||||
|
|
||||||
// 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
|
||||||
|
// when translations are not found or before they are loaded (via
|
||||||
|
// loadLanguages()).
|
||||||
en: en,
|
en: en,
|
||||||
pt_BR: pt_BR,
|
}
|
||||||
it: it,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configured language.
|
||||||
|
*/
|
||||||
export function getLanguage(): string {
|
export function getLanguage(): string {
|
||||||
const canonicalizeLanguage = (language?: string | null): string | null => {
|
const canonicalizeLanguage = (language?: string | null): string | null => {
|
||||||
if (!language) {
|
if (!language) {
|
||||||
@@ -39,14 +41,32 @@ export function getLanguage(): string {
|
|||||||
return lang || 'en';
|
return lang || 'en';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load required languages.
|
||||||
|
*/
|
||||||
|
export const loadLanguages = async (): Promise<void> => {
|
||||||
|
const lang = getLanguage();
|
||||||
|
if (lang === 'it') {
|
||||||
|
languages['it'] = await import('./languages/it.json');
|
||||||
|
} else if (lang === 'pt_BR') {
|
||||||
|
languages['pt_BR'] = await import('./languages/pt-BR.json');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a localized version of a given string key.
|
||||||
|
* @param string The key.
|
||||||
|
* @param search An optional search key to be used with 'replace'.
|
||||||
|
* @param replace An optional replacement text to be used with 'search'.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function localize(string: string, search = '', replace = ''): string {
|
export function localize(string: string, search = '', replace = ''): string {
|
||||||
const lang = getLanguage();
|
const lang = getLanguage();
|
||||||
let translated: string;
|
let translated = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
translated = string.split('.').reduce((o, i) => o[i], languages[lang]);
|
translated = string.split('.').reduce((o, i) => o[i], languages[lang]);
|
||||||
} catch (e) {
|
} catch (_) {
|
||||||
translated = string.split('.').reduce((o, i) => o[i], languages['en']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!translated) {
|
if (!translated) {
|
||||||
|
|||||||
Reference in New Issue
Block a user