mirror of
https://github.com/CringeStudios/element-desktop.git
synced 2025-02-12 11:04:18 +01:00
Fix i18n interpolation (#432)
This commit is contained in:
parent
0f52d2057e
commit
d31622d98c
@ -18,7 +18,7 @@ import counterpart from "counterpart";
|
|||||||
|
|
||||||
import type Store from 'electron-store';
|
import type Store from 'electron-store';
|
||||||
|
|
||||||
const DEFAULT_LOCALE = "en";
|
const FALLBACK_LOCALE = 'en';
|
||||||
|
|
||||||
export function _td(text: string): string {
|
export function _td(text: string): string {
|
||||||
return text;
|
return text;
|
||||||
@ -32,9 +32,7 @@ interface IVariables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function _t(text: string, variables: IVariables = {}): string {
|
export function _t(text: string, variables: IVariables = {}): string {
|
||||||
const args = Object.assign({ interpolate: false }, variables);
|
const { count } = variables;
|
||||||
|
|
||||||
const { count } = args;
|
|
||||||
|
|
||||||
// Horrible hack to avoid https://github.com/vector-im/element-web/issues/4191
|
// Horrible hack to avoid https://github.com/vector-im/element-web/issues/4191
|
||||||
// The interpolation library that counterpart uses does not support undefined/null
|
// The interpolation library that counterpart uses does not support undefined/null
|
||||||
@ -43,21 +41,20 @@ export function _t(text: string, variables: IVariables = {}): string {
|
|||||||
// valid ES6 template strings to i18n strings it's extremely easy to pass undefined/null
|
// valid ES6 template strings to i18n strings it's extremely easy to pass undefined/null
|
||||||
// if there are no existing null guards. To avoid this making the app completely inoperable,
|
// if there are no existing null guards. To avoid this making the app completely inoperable,
|
||||||
// we'll check all the values for undefined/null and stringify them here.
|
// we'll check all the values for undefined/null and stringify them here.
|
||||||
Object.keys(args).forEach((key) => {
|
Object.keys(variables).forEach((key) => {
|
||||||
if (args[key] === undefined) {
|
if (variables[key] === undefined) {
|
||||||
console.warn("safeCounterpartTranslate called with undefined interpolation name: " + key);
|
console.warn("safeCounterpartTranslate called with undefined interpolation name: " + key);
|
||||||
args[key] = 'undefined';
|
variables[key] = 'undefined';
|
||||||
}
|
}
|
||||||
if (args[key] === null) {
|
if (variables[key] === null) {
|
||||||
console.warn("safeCounterpartTranslate called with null interpolation name: " + key);
|
console.warn("safeCounterpartTranslate called with null interpolation name: " + key);
|
||||||
args[key] = 'null';
|
variables[key] = 'null';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let translated = counterpart.translate(text, args);
|
let translated = counterpart.translate(text, variables);
|
||||||
if (translated === undefined && count !== undefined) {
|
if (!translated && count !== undefined) {
|
||||||
// counterpart does not do fallback if no pluralisation exists
|
// counterpart does not do fallback if no pluralisation exists in the preferred language, so do it here
|
||||||
// in the preferred language, so do it here
|
translated = counterpart.translate(text, { ...variables, locale: FALLBACK_LOCALE });
|
||||||
translated = counterpart.translate(text, Object.assign({}, args, { locale: DEFAULT_LOCALE }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution)
|
// The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution)
|
||||||
@ -75,8 +72,8 @@ export class AppLocalization {
|
|||||||
private readonly localizedComponents?: Set<Component>;
|
private readonly localizedComponents?: Set<Component>;
|
||||||
|
|
||||||
constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
|
constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
|
||||||
counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN"));
|
counterpart.registerTranslations(FALLBACK_LOCALE, this.fetchTranslationJson("en_EN"));
|
||||||
counterpart.setFallbackLocale('en');
|
counterpart.setFallbackLocale(FALLBACK_LOCALE);
|
||||||
counterpart.setSeparator('|');
|
counterpart.setSeparator('|');
|
||||||
|
|
||||||
if (Array.isArray(components)) {
|
if (Array.isArray(components)) {
|
||||||
@ -122,16 +119,15 @@ export class AppLocalization {
|
|||||||
locales = [locales];
|
locales = [locales];
|
||||||
}
|
}
|
||||||
|
|
||||||
locales.forEach(locale => {
|
const loadedLocales = locales.filter(locale => {
|
||||||
const translations = this.fetchTranslationJson(locale);
|
const translations = this.fetchTranslationJson(locale);
|
||||||
if (translations !== null) {
|
if (translations !== null) {
|
||||||
counterpart.registerTranslations(locale, translations);
|
counterpart.registerTranslations(locale, translations);
|
||||||
}
|
}
|
||||||
|
return !!translations;
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
counterpart.setLocale(loadedLocales[0]);
|
||||||
// @ts-ignore - this looks like a bug but is out of scope for this conversion
|
|
||||||
counterpart.setLocale(locales);
|
|
||||||
this.store.set(AppLocalization.STORE_KEY, locales);
|
this.store.set(AppLocalization.STORE_KEY, locales);
|
||||||
|
|
||||||
this.resetLocalizedUI();
|
this.resetLocalizedUI();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user