Move functions to common-translation (#10180)

This commit is contained in:
Joakim Sørensen 2021-10-07 11:02:52 +02:00 committed by GitHub
parent 9e35c1ab68
commit 066a0771b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 117 additions and 123 deletions

View File

@ -4,7 +4,7 @@ import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-rel
import { shouldPolyfill as shouldPolyfillDateTime } from "@formatjs/intl-datetimeformat/lib/should-polyfill";
import IntlMessageFormat from "intl-messageformat";
import { Resources } from "../../types";
import { getLocalLanguage } from "../../util/hass-translation";
import { getLocalLanguage } from "../../util/common-translation";
export type LocalizeFunc = (key: string, ...args: any[]) => string;
interface FormatType {

View File

@ -8,7 +8,7 @@ import { DEFAULT_PANEL } from "../data/panel";
import { NumberFormat, TimeFormat } from "../data/translation";
import { translationMetadata } from "../resources/translations-metadata";
import { HomeAssistant } from "../types";
import { getLocalLanguage, getTranslation } from "../util/hass-translation";
import { getLocalLanguage, getTranslation } from "../util/common-translation";
import { demoConfig } from "./demo_config";
import { demoPanels } from "./demo_panels";
import { demoServices } from "./demo_services";

View File

@ -2,7 +2,7 @@ import { LitElement, PropertyValues } from "lit";
import { property } from "lit/decorators";
import { computeLocalize, LocalizeFunc } from "../common/translations/localize";
import { Constructor, Resources } from "../types";
import { getLocalLanguage, getTranslation } from "../util/hass-translation";
import { getLocalLanguage, getTranslation } from "../util/common-translation";
const empty = () => "";

View File

@ -22,7 +22,7 @@ import { Constructor, ServiceCallResponse } from "../types";
import { fetchWithAuth } from "../util/fetch-with-auth";
import { getState } from "../util/ha-pref-storage";
import hassCallApi from "../util/hass-call-api";
import { getLocalLanguage } from "../util/hass-translation";
import { getLocalLanguage } from "../util/common-translation";
import { HassBaseEl } from "./hass-base-mixin";
export const connectionMixin = <T extends Constructor<HassBaseEl>>(

View File

@ -17,7 +17,7 @@ import {
getLocalLanguage,
getTranslation,
getUserLocale,
} from "../util/hass-translation";
} from "../util/common-translation";
import { HassBaseEl } from "./hass-base-mixin";
declare global {
@ -376,3 +376,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
}
}
};
// Load selected translation into memory immediately so it is ready when Polymer
// initializes.
getTranslation(null, getLocalLanguage());

View File

@ -1,6 +1,12 @@
import {
fetchTranslationPreferences,
FrontendLocaleData,
} from "../data/translation";
import { translationMetadata } from "../resources/translations-metadata";
import { HomeAssistant } from "../types";
const DEFAULT_BASE_URL = "/static/translations";
const STORAGE = window.localStorage || {};
// Store loaded translations in memory so translations are available immediately
// when DOM is created in Polymer. Even a cache lookup creates noticeable latency.
@ -18,6 +24,108 @@ async function fetchTranslation(fingerprint: string, base_url: string) {
return response.json();
}
// Chinese locales need map to Simplified or Traditional Chinese
const LOCALE_LOOKUP = {
"zh-cn": "zh-Hans",
"zh-sg": "zh-Hans",
"zh-my": "zh-Hans",
"zh-tw": "zh-Hant",
"zh-hk": "zh-Hant",
"zh-mo": "zh-Hant",
zh: "zh-Hant", // all other Chinese locales map to Traditional Chinese
};
/**
* Search for a matching translation from most specific to general
*/
export function findAvailableLanguage(language: string) {
// In most case, the language has the same format with our translation meta data
if (language in translationMetadata.translations) {
return language;
}
// Perform case-insenstive comparison since browser isn't required to
// report languages with specific cases.
const langLower = language.toLowerCase();
if (langLower in LOCALE_LOOKUP) {
return LOCALE_LOOKUP[langLower];
}
const translation = Object.keys(translationMetadata.translations).find(
(lang) => lang.toLowerCase() === langLower
);
if (translation) {
return translation;
}
if (language.includes("-")) {
return findAvailableLanguage(language.split("-")[0]);
}
return undefined;
}
/**
* Get user selected locale data from backend
*/
export async function getUserLocale(
hass: HomeAssistant
): Promise<Partial<FrontendLocaleData>> {
const result = await fetchTranslationPreferences(hass);
const language = result?.language;
const number_format = result?.number_format;
const time_format = result?.time_format;
if (language) {
const availableLanguage = findAvailableLanguage(language);
if (availableLanguage) {
return {
language: availableLanguage,
number_format,
time_format,
};
}
}
return {
number_format,
time_format,
};
}
/**
* Get browser specific language
*/
export function getLocalLanguage() {
let language = null;
if (STORAGE.selectedLanguage) {
try {
const stored = JSON.parse(STORAGE.selectedLanguage);
if (stored) {
language = findAvailableLanguage(stored);
if (language) {
return language;
}
}
} catch (err: any) {
// Ignore parsing error.
}
}
if (navigator.languages) {
for (const locale of navigator.languages) {
language = findAvailableLanguage(locale);
if (language) {
return language;
}
}
}
language = findAvailableLanguage(navigator.language);
if (language) {
return language;
}
// Final fallback
return "en";
}
export async function getTranslation(
fragment: string | null,
language: string,

View File

@ -1,118 +0,0 @@
import {
fetchTranslationPreferences,
FrontendLocaleData,
} from "../data/translation";
import { translationMetadata } from "../resources/translations-metadata";
import { HomeAssistant } from "../types";
import { getTranslation as commonGetTranslation } from "./common-translation";
const STORAGE = window.localStorage || {};
// Chinese locales need map to Simplified or Traditional Chinese
const LOCALE_LOOKUP = {
"zh-cn": "zh-Hans",
"zh-sg": "zh-Hans",
"zh-my": "zh-Hans",
"zh-tw": "zh-Hant",
"zh-hk": "zh-Hant",
"zh-mo": "zh-Hant",
zh: "zh-Hant", // all other Chinese locales map to Traditional Chinese
};
/**
* Search for a matching translation from most specific to general
*/
export function findAvailableLanguage(language: string) {
// In most case, the language has the same format with our translation meta data
if (language in translationMetadata.translations) {
return language;
}
// Perform case-insenstive comparison since browser isn't required to
// report languages with specific cases.
const langLower = language.toLowerCase();
if (langLower in LOCALE_LOOKUP) {
return LOCALE_LOOKUP[langLower];
}
const translation = Object.keys(translationMetadata.translations).find(
(lang) => lang.toLowerCase() === langLower
);
if (translation) {
return translation;
}
if (language.includes("-")) {
return findAvailableLanguage(language.split("-")[0]);
}
return undefined;
}
/**
* Get user selected locale data from backend
*/
export async function getUserLocale(
hass: HomeAssistant
): Promise<Partial<FrontendLocaleData>> {
const result = await fetchTranslationPreferences(hass);
const language = result?.language;
const number_format = result?.number_format;
const time_format = result?.time_format;
if (language) {
const availableLanguage = findAvailableLanguage(language);
if (availableLanguage) {
return {
language: availableLanguage,
number_format,
time_format,
};
}
}
return {
number_format,
time_format,
};
}
/**
* Get browser specific language
*/
export function getLocalLanguage() {
let language = null;
if (STORAGE.selectedLanguage) {
try {
const stored = JSON.parse(STORAGE.selectedLanguage);
if (stored) {
language = findAvailableLanguage(stored);
if (language) {
return language;
}
}
} catch (err: any) {
// Ignore parsing error.
}
}
if (navigator.languages) {
for (const locale of navigator.languages) {
language = findAvailableLanguage(locale);
if (language) {
return language;
}
}
}
language = findAvailableLanguage(navigator.language);
if (language) {
return language;
}
// Final fallback
return "en";
}
export const getTranslation = (fragment: string | null, language: string) =>
commonGetTranslation(fragment, language);
// Load selected translation into memory immediately so it is ready when Polymer
// initializes.
commonGetTranslation(null, getLocalLanguage());