|
|
|
import fs from 'fs';
|
|
|
|
import _ from 'lodash';
|
|
|
|
import path from 'path';
|
|
|
|
import type { LocalizerDictionary } from '../types/Localizer';
|
|
|
|
import { getAppRootPath } from './getRootPath';
|
|
|
|
|
|
|
|
function normalizeLocaleName(locale: string) {
|
|
|
|
const dashedLocale = locale.replaceAll('_', '-');
|
|
|
|
|
|
|
|
// Note: this is a pain, but we somehow needs to keep in sync this logic and the LOCALE_PATH_MAPPING from
|
|
|
|
// https://github.com/oxen-io/session-shared-scripts/blob/main/crowdin/generate_desktop_strings.py
|
|
|
|
// What we do, is keep as is, anything given in LOCALE_PATH_MAPPING, but otherwise, keep only the first part of the locale.
|
|
|
|
// So `es-419` is allowed, but `es-es` is hardcoded to es, fr_FR is hardcoded to fr, and so on.
|
|
|
|
if (
|
|
|
|
/^es-419/.test(dashedLocale) ||
|
|
|
|
/^hy-AM/.test(dashedLocale) ||
|
|
|
|
/^kmr-TR/.test(dashedLocale) ||
|
|
|
|
/^pt-BR/.test(dashedLocale) ||
|
|
|
|
/^pt-PT/.test(dashedLocale) ||
|
|
|
|
/^zh-CN/.test(dashedLocale) ||
|
|
|
|
/^zh-TW/.test(dashedLocale)
|
|
|
|
) {
|
|
|
|
return dashedLocale;
|
|
|
|
}
|
|
|
|
const firstDash = dashedLocale.indexOf('-');
|
|
|
|
if (firstDash > 0) {
|
|
|
|
return dashedLocale.slice(0, firstDash);
|
|
|
|
}
|
|
|
|
return dashedLocale;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getLocaleMessages(locale: string): LocalizerDictionary {
|
|
|
|
if (locale.includes('_')) {
|
|
|
|
throw new Error(
|
|
|
|
"getLocaleMessages: expected locale to not have a '_' in it. Those should have been replaced to -"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const targetFile = path.join(getAppRootPath(), '_locales', locale, 'messages.json');
|
|
|
|
|
|
|
|
return JSON.parse(fs.readFileSync(targetFile, 'utf-8'));
|
|
|
|
}
|
|
|
|
|
|
|
|
export function load({ appLocale, logger }: { appLocale?: string; logger?: any } = {}): {
|
|
|
|
name: string;
|
|
|
|
messages: LocalizerDictionary;
|
|
|
|
} {
|
|
|
|
if (!appLocale) {
|
|
|
|
throw new TypeError('`appLocale` is required');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!logger || !logger.error) {
|
|
|
|
throw new TypeError('`logger.error` is required');
|
|
|
|
}
|
|
|
|
|
|
|
|
const english = getLocaleMessages('en');
|
|
|
|
const normalizedLocaleName = normalizeLocaleName(appLocale);
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Load locale - if we can't load messages for the current locale, we
|
|
|
|
// default to 'en'
|
|
|
|
//
|
|
|
|
// possible locales:
|
|
|
|
// https://github.com/electron/electron/blob/master/docs/api/locales.md
|
|
|
|
|
|
|
|
// We start with english, then overwrite that with anything present in locale
|
|
|
|
const messages = _.merge(english, getLocaleMessages(normalizedLocaleName));
|
|
|
|
return {
|
|
|
|
name: normalizedLocaleName,
|
|
|
|
messages,
|
|
|
|
};
|
|
|
|
} catch (e) {
|
|
|
|
logger.error(`Problem loading messages for locale ${normalizedLocaleName} ${e.stack}`);
|
|
|
|
logger.error('Falling back to en locale');
|
|
|
|
|
|
|
|
return {
|
|
|
|
name: 'en',
|
|
|
|
messages: english,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|