2020-07-21 00:07:04 +02:00
|
|
|
import {UIElement} from "../UIElement";
|
|
|
|
import {FixedUiElement} from "../Base/FixedUiElement";
|
2020-10-28 11:19:47 +01:00
|
|
|
import Combine from "../Base/Combine";
|
|
|
|
import Locale from "./Locale";
|
|
|
|
import {Utils} from "../../Utils";
|
2020-11-04 20:55:43 +01:00
|
|
|
import * as TranslationsJson from "../../assets/translations.json"
|
2020-07-20 12:39:43 +02:00
|
|
|
|
2020-10-28 11:19:47 +01:00
|
|
|
export class Translation extends UIElement {
|
|
|
|
|
|
|
|
private static forcedLanguage = undefined;
|
|
|
|
|
|
|
|
public Subs(text: any): Translation {
|
|
|
|
const newTranslations = {};
|
|
|
|
for (const lang in this.translations) {
|
|
|
|
let template: string = this.translations[lang];
|
|
|
|
for (const k in text) {
|
|
|
|
const combined = [];
|
|
|
|
const parts = template.split("{" + k + "}");
|
|
|
|
const el: string | UIElement = text[k];
|
|
|
|
if (el === undefined) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let rtext: string = "";
|
|
|
|
if (typeof (el) === "string") {
|
|
|
|
rtext = el;
|
|
|
|
} else {
|
|
|
|
Translation.forcedLanguage = lang; // This is a very dirty hack - it'll bite me one day
|
|
|
|
rtext = el.InnerRender();
|
|
|
|
}
|
|
|
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
|
|
combined.push(parts[i]);
|
|
|
|
combined.push(rtext)
|
|
|
|
}
|
|
|
|
combined.push(parts[parts.length - 1]);
|
|
|
|
template = new Combine(combined).InnerRender();
|
|
|
|
}
|
|
|
|
newTranslations[lang] = template;
|
|
|
|
}
|
|
|
|
Translation.forcedLanguage = undefined;
|
|
|
|
return new Translation(newTranslations);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get txt(): string {
|
|
|
|
if (this.translations["*"]) {
|
|
|
|
return this.translations["*"];
|
|
|
|
}
|
|
|
|
const txt = this.translations[Translation.forcedLanguage ?? Locale.language.data];
|
|
|
|
if (txt !== undefined) {
|
|
|
|
return txt;
|
|
|
|
}
|
|
|
|
const en = this.translations["en"];
|
|
|
|
if (en !== undefined) {
|
|
|
|
return en;
|
|
|
|
}
|
|
|
|
for (const i in this.translations) {
|
|
|
|
return this.translations[i]; // Return a random language
|
|
|
|
}
|
|
|
|
console.error("Missing language ",Locale.language.data,"for",this.translations)
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
InnerRender(): string {
|
|
|
|
return this.txt
|
|
|
|
}
|
|
|
|
|
|
|
|
public readonly translations: object
|
|
|
|
|
|
|
|
constructor(translations: object) {
|
|
|
|
super(Locale.language)
|
|
|
|
let count = 0;
|
|
|
|
for (const translationsKey in translations) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
this.translations = translations
|
|
|
|
}
|
|
|
|
|
|
|
|
public replace(a: string, b: string) {
|
|
|
|
if(a.startsWith("{") && a.endsWith("}")){
|
|
|
|
a = a.substr(1, a.length - 2);
|
|
|
|
}
|
|
|
|
const result= this.Subs({[a]: b});
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Clone() {
|
|
|
|
return new Translation(this.translations)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FirstSentence() {
|
|
|
|
|
|
|
|
const tr = {};
|
|
|
|
for (const lng in this.translations) {
|
|
|
|
let txt = this.translations[lng];
|
|
|
|
txt = txt.replace(/\..*/, "");
|
|
|
|
txt = Utils.EllipsesAfter(txt, 255);
|
|
|
|
tr[lng] = txt;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Translation(tr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-20 12:39:43 +02:00
|
|
|
export default class Translations {
|
2020-07-21 23:31:41 +02:00
|
|
|
|
|
|
|
constructor() {
|
|
|
|
throw "Translations is static. If you want to intitialize a new translation, use the singular form"
|
|
|
|
}
|
|
|
|
|
2020-11-04 20:55:43 +01:00
|
|
|
static t = TranslationsJson;
|
2020-07-21 23:31:41 +02:00
|
|
|
|
2020-11-04 20:55:43 +01:00
|
|
|
private static isTranslation(tr: any): boolean {
|
|
|
|
for (const key in tr) {
|
|
|
|
if (typeof tr[key] !== "string") {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2020-10-08 19:03:00 +02:00
|
|
|
|
2020-11-04 20:55:43 +01:00
|
|
|
private static InitT(): boolean {
|
|
|
|
const queue = [Translations.t]
|
|
|
|
while (queue.length > 0) {
|
|
|
|
const tr = queue.pop();
|
|
|
|
const copy = {}
|
|
|
|
for (const subKey in tr) {
|
|
|
|
if (Translations.isTranslation(tr[subKey])) {
|
|
|
|
copy[subKey] = new Translation(tr[subKey]);
|
2020-11-05 13:34:48 +01:00
|
|
|
} else if(tr[subKey].translations === undefined /**should not be a translation already*/){
|
2020-11-04 20:55:43 +01:00
|
|
|
queue.push(tr[subKey]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const subKey in copy) {
|
|
|
|
tr[subKey] = copy[subKey]
|
2020-10-06 02:09:09 +02:00
|
|
|
}
|
2020-07-26 02:01:34 +02:00
|
|
|
}
|
2020-11-04 20:55:43 +01:00
|
|
|
return true;
|
2020-07-21 00:07:04 +02:00
|
|
|
}
|
|
|
|
|
2020-11-04 20:55:43 +01:00
|
|
|
private static isInited = Translations.InitT();
|
|
|
|
|
|
|
|
|
2020-07-21 00:38:03 +02:00
|
|
|
public static W(s: string | UIElement): UIElement {
|
2020-08-22 02:12:46 +02:00
|
|
|
if (typeof (s) === "string") {
|
|
|
|
return new FixedUiElement(s);
|
2020-07-20 12:39:43 +02:00
|
|
|
}
|
2020-08-22 02:12:46 +02:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2020-10-27 01:01:34 +01:00
|
|
|
|
|
|
|
static T(t: string | any): Translation {
|
|
|
|
if(t === undefined){
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
if(typeof t === "string"){
|
|
|
|
return new Translation({"*":t});
|
|
|
|
}
|
|
|
|
if(t.render !== undefined){
|
|
|
|
const msg = "Creating a translation, but this object contains a 'render'-field. Use the translation directly"
|
|
|
|
console.error(msg, t);
|
|
|
|
throw msg
|
|
|
|
}
|
|
|
|
return new Translation(t);
|
|
|
|
}
|
|
|
|
|
2020-10-14 12:15:09 +02:00
|
|
|
private static wtcache = {}
|
2020-08-22 02:12:46 +02:00
|
|
|
public static WT(s: string | Translation): Translation {
|
2020-10-12 01:25:27 +02:00
|
|
|
if(s === undefined){
|
|
|
|
return undefined;
|
|
|
|
}
|
2020-08-22 02:12:46 +02:00
|
|
|
if (typeof (s) === "string") {
|
2020-10-14 12:15:09 +02:00
|
|
|
if(Translations.wtcache[s]){
|
|
|
|
return Translations.wtcache[s];
|
|
|
|
}
|
|
|
|
const tr = new Translation({en: s});
|
|
|
|
Translations.wtcache[s]= tr;
|
|
|
|
return tr;
|
2020-08-22 02:12:46 +02:00
|
|
|
}
|
2020-10-09 20:10:21 +02:00
|
|
|
if (s instanceof Translation) {
|
|
|
|
return s;
|
|
|
|
}
|
2020-10-10 14:09:12 +02:00
|
|
|
console.error("Trying to Translation.WT, but got ",s)
|
2020-10-09 20:10:21 +02:00
|
|
|
throw "??? Not a valid translation"
|
2020-07-20 12:39:43 +02:00
|
|
|
}
|
2020-07-21 00:07:04 +02:00
|
|
|
|
2020-07-26 02:01:34 +02:00
|
|
|
public static CountTranslations() {
|
|
|
|
const queue: any = [Translations.t];
|
|
|
|
const tr: Translation[] = [];
|
|
|
|
while (queue.length > 0) {
|
|
|
|
const item = queue.pop();
|
|
|
|
if (item instanceof Translation || item.translations !== undefined) {
|
|
|
|
tr.push(item);
|
2020-07-31 17:38:03 +02:00
|
|
|
} else if (typeof (item) === "string") {
|
|
|
|
console.warn("Got single string in translationgs file: ", item);
|
2020-07-26 02:01:34 +02:00
|
|
|
} else {
|
|
|
|
for (const t in item) {
|
|
|
|
const x = item[t];
|
|
|
|
queue.push(x)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const langaugeCounts = {};
|
|
|
|
for (const translation of tr) {
|
|
|
|
for (const language in translation.translations) {
|
|
|
|
if (langaugeCounts[language] === undefined) {
|
|
|
|
langaugeCounts[language] = 1
|
|
|
|
} else {
|
|
|
|
langaugeCounts[language]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const language in langaugeCounts) {
|
|
|
|
console.log("Total translations in ", language, langaugeCounts[language], "/", tr.length)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-09-15 18:44:58 +02:00
|
|
|
}
|