//REF: https://github.com/home-assistant/frontend/blob/dev/src/common/translations/localize.ts import IntlMessageFormat from "intl-messageformat"; import { Resources } from "../types"; export type LocalizeFunc = (key: string, ...args: any[]) => string; interface FormatType { [format: string]: any; } export interface FormatsType { number: FormatType; date: FormatType; time: FormatType; } // !!! Polyfills do not have to be handles since they get handled by the homeassistant frontend already !!! // Ref -> https://discord.com/channels/330944238910963714/351047592588869643/898945966953078804 /** * Adapted from Polymer app-localize-behavior. * * Copyright (c) 2016 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ export const computeLocalize = async ( cache: any, language: string, resources: Resources, formats?: FormatsType ): Promise => { // Everytime any of the parameters change, invalidate the strings cache. cache._localizationCache = {}; return (key, ...args) => { if (!key || !resources || !language || !resources[language]) { return ""; } // Cache the key/value pairs for the same language, so that we don't // do extra work if we're just reusing strings across an application. const translatedValue = resources[language][key]; if (!translatedValue) { return ""; } const messageKey = key + translatedValue; let translatedMessage = cache._localizationCache[messageKey] as | IntlMessageFormat | undefined; if (!translatedMessage) { try { translatedMessage = new IntlMessageFormat( translatedValue, language, formats ); } catch (err: any) { return "Translation error: " + err.message; } cache._localizationCache[messageKey] = translatedMessage; } let argObject = {}; if (args.length === 1 && typeof args[0] === "object") { argObject = args[0]; } else { for (let i = 0; i < args.length; i += 2) { argObject[args[i]] = args[i + 1]; } } try { return translatedMessage.format(argObject) as string; } catch (err: any) { return "Translation " + err; } }; };