2020-09-18 20:43:19 +02:00
|
|
|
// For documentation on i18n in Zulip, see:
|
|
|
|
// https://zulip.readthedocs.io/en/latest/translating/internationalization.html
|
|
|
|
|
2021-05-27 20:08:50 +02:00
|
|
|
import type {MessageDescriptor} from "@formatjs/intl";
|
2021-04-14 21:12:07 +02:00
|
|
|
import {DEFAULT_INTL_CONFIG, IntlErrorCode, createIntl, createIntlCache} from "@formatjs/intl";
|
2021-05-27 20:08:50 +02:00
|
|
|
import type {FormatXMLElementFn, PrimitiveType} from "intl-messageformat";
|
2021-04-10 03:11:59 +02:00
|
|
|
import _ from "lodash";
|
2016-05-13 12:44:03 +02:00
|
|
|
|
2024-02-16 22:56:36 +01:00
|
|
|
import {page_params} from "./base_page_params";
|
2021-03-25 22:35:45 +01:00
|
|
|
|
2021-04-10 03:11:59 +02:00
|
|
|
const cache = createIntlCache();
|
|
|
|
export const intl = createIntl(
|
|
|
|
{
|
2021-04-24 01:32:32 +02:00
|
|
|
locale: page_params.request_language,
|
2021-04-10 03:11:59 +02:00
|
|
|
defaultLocale: "en",
|
2024-02-16 22:56:36 +01:00
|
|
|
messages: "translation_data" in page_params ? page_params.translation_data : {},
|
2022-11-17 23:33:43 +01:00
|
|
|
/* istanbul ignore next */
|
|
|
|
onError(error) {
|
2021-04-14 21:12:07 +02:00
|
|
|
// Ignore complaints about untranslated strings that were
|
|
|
|
// added since the last sync-translations run.
|
|
|
|
if (error.code !== IntlErrorCode.MISSING_TRANSLATION) {
|
|
|
|
DEFAULT_INTL_CONFIG.onError(error);
|
|
|
|
}
|
|
|
|
},
|
2021-04-10 03:11:59 +02:00
|
|
|
},
|
|
|
|
cache,
|
|
|
|
);
|
|
|
|
|
2021-09-23 00:27:09 +02:00
|
|
|
export const $t = intl.formatMessage.bind(intl);
|
2021-04-10 03:11:59 +02:00
|
|
|
|
|
|
|
export const default_html_elements = Object.fromEntries(
|
|
|
|
["b", "code", "em", "i", "kbd", "p", "strong"].map((tag) => [
|
|
|
|
tag,
|
2022-11-03 20:14:03 +01:00
|
|
|
(content_html: string[]) => `<${tag}>${content_html.join("")}</${tag}>`,
|
2021-04-10 03:11:59 +02:00
|
|
|
]),
|
|
|
|
);
|
|
|
|
|
2021-05-27 20:08:50 +02:00
|
|
|
export function $t_html(
|
|
|
|
descriptor: MessageDescriptor,
|
|
|
|
values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>,
|
|
|
|
): string {
|
2021-04-10 03:11:59 +02:00
|
|
|
return intl.formatMessage(descriptor, {
|
|
|
|
...default_html_elements,
|
|
|
|
...Object.fromEntries(
|
|
|
|
Object.entries(values ?? {}).map(([key, value]) => [
|
|
|
|
key,
|
2021-05-27 20:08:50 +02:00
|
|
|
typeof value === "function" ? value : _.escape(value?.toString()),
|
2021-04-10 03:11:59 +02:00
|
|
|
]),
|
|
|
|
),
|
|
|
|
});
|
|
|
|
}
|
2021-06-15 22:37:07 +02:00
|
|
|
|
2024-02-16 22:56:36 +01:00
|
|
|
export let language_list: (typeof page_params & {page_type: "home"})["language_list"];
|
2021-06-18 02:16:48 +02:00
|
|
|
|
2024-06-05 20:58:14 +02:00
|
|
|
export function get_language_name(language_code: string): string | undefined {
|
|
|
|
return language_list.find((language) => language.code === language_code)?.name;
|
2021-06-18 02:16:48 +02:00
|
|
|
}
|
2021-06-15 22:37:07 +02:00
|
|
|
|
2021-05-27 20:08:50 +02:00
|
|
|
export function initialize(language_params: {language_list: typeof language_list}): void {
|
2021-06-18 02:16:48 +02:00
|
|
|
const language_list_raw = language_params.language_list;
|
|
|
|
|
|
|
|
// Limit offered languages to options with percentage translation >= 5%
|
|
|
|
language_list = [];
|
|
|
|
for (const language of language_list_raw) {
|
2021-06-15 22:37:07 +02:00
|
|
|
if (language.percent_translated === undefined || language.percent_translated >= 5) {
|
|
|
|
language_list.push({
|
|
|
|
code: language.code,
|
|
|
|
locale: language.locale,
|
|
|
|
name: language.name,
|
|
|
|
percent_translated: language.percent_translated,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2021-06-18 02:16:48 +02:00
|
|
|
}
|
2021-06-15 22:37:07 +02:00
|
|
|
|
2022-06-06 15:38:17 +02:00
|
|
|
type Language = {
|
|
|
|
code: string;
|
|
|
|
name: string;
|
|
|
|
name_with_percent: string;
|
|
|
|
selected: boolean;
|
2021-05-27 20:08:50 +02:00
|
|
|
};
|
|
|
|
|
2022-06-06 15:38:17 +02:00
|
|
|
export function get_language_list_columns(default_language: string): Language[] {
|
|
|
|
const formatted_list: Language[] = [];
|
|
|
|
for (const language of language_list) {
|
|
|
|
let name_with_percent = language.name;
|
|
|
|
if (language.percent_translated !== undefined) {
|
|
|
|
name_with_percent = `${language.name} (${language.percent_translated}%)`;
|
|
|
|
}
|
2021-06-15 22:37:07 +02:00
|
|
|
|
2022-07-13 02:25:43 +02:00
|
|
|
const selected = default_language === language.code || default_language === language.locale;
|
2022-06-06 15:38:17 +02:00
|
|
|
formatted_list.push({
|
|
|
|
code: language.code,
|
|
|
|
name: language.name,
|
|
|
|
name_with_percent,
|
|
|
|
selected,
|
|
|
|
});
|
2021-06-15 22:37:07 +02:00
|
|
|
}
|
|
|
|
return formatted_list;
|
|
|
|
}
|