2020-06-27 11:24:49 +02:00
|
|
|
// Copyright: Ankitects Pty Ltd and contributors
|
|
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
|
2020-11-01 05:26:58 +01:00
|
|
|
import pb from "./fluent_proto";
|
2020-06-29 05:46:13 +02:00
|
|
|
import "intl-pluralrules";
|
|
|
|
import { FluentBundle, FluentResource, FluentNumber } from "@fluent/bundle/compat";
|
2020-06-27 11:24:49 +02:00
|
|
|
|
2020-06-27 13:10:17 +02:00
|
|
|
type RecordVal = number | string | FluentNumber;
|
|
|
|
|
|
|
|
function formatNumbers(args?: Record<string, RecordVal>): void {
|
2020-06-27 11:24:49 +02:00
|
|
|
if (!args) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (const key of Object.keys(args)) {
|
|
|
|
if (typeof args[key] === "number") {
|
2020-06-27 13:10:17 +02:00
|
|
|
args[key] = new FluentNumber(args[key] as number, {
|
2020-06-28 11:34:19 +02:00
|
|
|
maximumFractionDigits: 2,
|
2020-06-27 13:10:17 +02:00
|
|
|
});
|
2020-06-27 11:24:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class I18n {
|
|
|
|
bundles: FluentBundle[] = [];
|
2020-06-30 07:09:20 +02:00
|
|
|
langs: string[] = [];
|
2020-11-01 05:26:58 +01:00
|
|
|
TR = pb.FluentProto.FluentString;
|
2020-06-27 11:24:49 +02:00
|
|
|
|
2020-11-01 05:26:58 +01:00
|
|
|
tr(id: pb.FluentProto.FluentString, args?: Record<string, RecordVal>): string {
|
2020-06-27 11:24:49 +02:00
|
|
|
formatNumbers(args);
|
|
|
|
const key = this.keyName(id);
|
|
|
|
for (const bundle of this.bundles) {
|
|
|
|
const msg = bundle.getMessage(key);
|
|
|
|
if (msg && msg.value) {
|
|
|
|
return bundle.formatPattern(msg.value, args);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return `missing key: ${key}`;
|
|
|
|
}
|
|
|
|
|
2020-06-28 07:23:36 +02:00
|
|
|
supportsVerticalText(): boolean {
|
|
|
|
const firstLang = this.bundles[0].locales[0];
|
|
|
|
return (
|
|
|
|
firstLang.startsWith("ja") ||
|
|
|
|
firstLang.startsWith("zh") ||
|
|
|
|
firstLang.startsWith("ko")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-04 06:28:46 +02:00
|
|
|
direction(): string {
|
|
|
|
const firstLang = this.bundles[0].locales[0];
|
|
|
|
if (
|
|
|
|
firstLang.startsWith("ar") ||
|
|
|
|
firstLang.startsWith("he") ||
|
|
|
|
firstLang.startsWith("fa")
|
|
|
|
) {
|
|
|
|
return "rtl";
|
|
|
|
} else {
|
|
|
|
return "ltr";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-01 05:26:58 +01:00
|
|
|
private keyName(msg: pb.FluentProto.FluentString): string {
|
2020-06-27 11:24:49 +02:00
|
|
|
return this.TR[msg].toLowerCase().replace(/_/g, "-");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function setupI18n(): Promise<I18n> {
|
|
|
|
const i18n = new I18n();
|
|
|
|
|
|
|
|
const resp = await fetch("/_anki/i18nResources", { method: "POST" });
|
|
|
|
if (!resp.ok) {
|
|
|
|
throw Error(`unexpected reply: ${resp.statusText}`);
|
|
|
|
}
|
|
|
|
const json = await resp.json();
|
|
|
|
|
|
|
|
for (const resourceText of json.resources) {
|
|
|
|
const bundle = new FluentBundle(json.langs);
|
|
|
|
const resource = new FluentResource(resourceText);
|
|
|
|
bundle.addResource(resource);
|
|
|
|
i18n.bundles.push(bundle);
|
|
|
|
}
|
2020-06-30 07:09:20 +02:00
|
|
|
i18n.langs = json.langs;
|
2020-06-27 11:24:49 +02:00
|
|
|
|
|
|
|
return i18n;
|
|
|
|
}
|