Fix deploy

This commit is contained in:
Pieter Vander Vennet 2020-11-06 01:58:26 +01:00
parent 9c53fe9868
commit 3f8b6e88d3
39 changed files with 381 additions and 562 deletions

View file

@ -1,4 +1,5 @@
import {UIElement} from "../UIElement";
import Translations from "../i18n/Translations";
export default class Link extends UIElement {
@ -6,9 +7,9 @@ export default class Link extends UIElement {
private readonly _target: string;
private readonly _newTab: string;
constructor(embeddedShow: UIElement, target: string, newTab: boolean = false) {
constructor(embeddedShow: UIElement | string, target: string, newTab: boolean = false) {
super();
this._embeddedShow = embeddedShow;
this._embeddedShow = Translations.W(embeddedShow);
this._target = target;
this._newTab = "";
if (newTab) {

View file

@ -5,6 +5,7 @@ import {Imgur} from "../../Logic/Web/Imgur";
import {Mapillary} from "../../Logic/Web/Mapillary";
import {Img} from "../Img";
import {FixedUiElement} from "../Base/FixedUiElement";
import Svg from "../../Svg";
export class MapillaryImage extends UIElement {
@ -53,8 +54,7 @@ export class MapillaryImage extends UIElement {
return "<div class='imgWithAttr'>" +
image +
"<div class='attribution'>" +
new FixedUiElement(Img.mapillaryLogo).SetStyle("height: 1.5em").Render() +
Svg.mapillary_ui().Render() +
attribution +
"</div>" +
"</div>";

View file

@ -1,6 +1,10 @@
import {UIElement} from "../UIElement";
import {LicenseInfo, Wikimedia} from "../../Logic/Web/Wikimedia";
import {UIEventSource} from "../../Logic/UIEventSource";
import Svg from "../../Svg";
import Link from "../Base/Link";
import {FixedUiElement} from "../Base/FixedUiElement";
import Combine from "../Base/Combine";
export class WikimediaImage extends UIElement {
@ -8,7 +12,7 @@ export class WikimediaImage extends UIElement {
static allLicenseInfos: any = {};
private readonly _imageMeta: UIEventSource<LicenseInfo>;
private readonly _imageLocation : string;
private readonly _imageLocation: string;
constructor(source: string) {
super(undefined)
@ -33,21 +37,17 @@ export class WikimediaImage extends UIElement {
let url = Wikimedia.ImageNameToUrl(this._imageLocation, 500, 400);
url = url.replace(/'/g, '%27');
const wikimediaLink =
"<a href='https://commons.wikimedia.org/wiki/" + this._imageLocation + "' target='_blank'>" +
"<img style='width:2em;height: 2em' class='wikimedia-link' src='./assets/wikimedia-commons-white.svg' alt='Wikimedia Commons Logo'/>" +
"</a> ";
const wikimediaLink = new Link(Svg.wikimedia_commons_white_img,
`https://commons.wikimedia.org/wiki/${this._imageLocation}`, true)
.SetStyle("width:2em;height: 2em");
const attribution =
"<span class='attribution-author'>" + (this._imageMeta.data.artist ?? "") + "</span>" + " <span class='license'>" + (this._imageMeta.data.licenseShortName ?? "") + "</span>";
const attribution = new FixedUiElement(this._imageMeta.data.artist ?? "").SetClass("attribution-author");
const license = new FixedUiElement(this._imageMeta.data.licenseShortName ?? "").SetClass("license");
const image = "<img src='" + url + "' " + "alt='" + this._imageMeta.data.description + "' >";
return "<div class='imgWithAttr'>" +
image +
"<div class='attribution'>" +
wikimediaLink +
attribution +
"</div>" +
new Combine([wikimediaLink, attribution]).SetClass("attribution").Render() +
"</div>";
}

View file

@ -1,6 +1,3 @@
import {UIElement} from "./UIElement";
import {FixedUiElement} from "./Base/FixedUiElement";
export class Img {
static AsData(source:string){
@ -10,25 +7,7 @@ export class Img {
static AsImageElement(source: string): string{
return `<img src="${Img.AsData(source)}">`;
}
static AsImage(source: string): UIElement{
return new FixedUiElement(Img.AsImageElement(source))
}
static readonly checkmark = `<svg width="26" height="18" viewBox="0 0 26 18" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3 7.28571L10.8261 15L23 3" stroke="black" stroke-width="4" stroke-linejoin="round"/></svg>`;
static readonly no_checkmark = `<svg width="26" height="18" viewBox="0 0 26 18" fill="none" xmlns="http://www.w3.org/2000/svg"></svg>`;
static closedFilterButton: string = `<svg width="27" height="27" viewBox="0 0 27 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.5353 8.13481C26.4422 8.35428 26.2683 8.47598 26.0632 8.58537C21.9977 10.7452 17.935 12.9085 13.8758 15.0799C13.6475 15.2016 13.4831 15.1962 13.2568 15.0751C9.19822 12.903 5.13484 10.7404 1.07215 8.5758C0.490599 8.26608 0.448478 7.52562 0.991303 7.13796C1.0803 7.07438 1.17813 7.0231 1.2746 6.97045C5.15862 4.86462 9.04536 2.7629 12.9246 0.648187C13.3805 0.399316 13.7779 0.406837 14.2311 0.65434C18.0954 2.76153 21.9658 4.85779 25.8383 6.94926C26.1569 7.12155 26.411 7.32872 26.5353 7.67604C26.5353 7.82919 26.5353 7.98166 26.5353 8.13481Z" fill="#003B8B"/>
<path d="M13.318 26.535C12.1576 25.9046 10.9972 25.2736 9.83614 24.6439C6.96644 23.0877 4.09674 21.533 1.22704 19.9762C0.694401 19.6876 0.466129 19.2343 0.669943 18.7722C0.759621 18.5691 0.931505 18.3653 1.11969 18.2512C1.66659 17.9182 2.23727 17.6228 2.80863 17.3329C2.89423 17.2892 3.04981 17.3206 3.14493 17.3712C6.40799 19.1031 9.66969 20.837 12.9239 22.5845C13.3703 22.8238 13.7609 22.83 14.208 22.59C17.4554 20.8472 20.7117 19.1202 23.9605 17.3801C24.1493 17.2789 24.2838 17.283 24.4632 17.3876C24.8926 17.6386 25.3301 17.8772 25.7751 18.1001C26.11 18.2683 26.3838 18.4857 26.5346 18.8385C26.5346 18.9916 26.5346 19.1441 26.5346 19.2972C26.4049 19.6528 26.1399 19.8613 25.8152 20.0363C22.9964 21.5549 20.1831 23.0829 17.3684 24.609C16.1863 25.2496 15.0055 25.893 13.8248 26.535C13.6556 26.535 13.4865 26.535 13.318 26.535Z" fill="#003B8B"/>
<path d="M26.3988 13.7412C26.2956 13.9661 26.1026 14.081 25.8927 14.1924C21.8198 16.3577 17.749 18.5258 13.6815 20.7013C13.492 20.8025 13.3602 20.7902 13.1795 20.6938C9.09638 18.5114 5.01059 16.3359 0.924798 14.1582C0.399637 13.8786 0.307921 13.2646 0.735251 12.838C0.829005 12.7443 0.947217 12.6705 1.06407 12.6055C1.56545 12.3279 2.07635 12.0654 2.57297 11.7789C2.74214 11.6812 2.86579 11.6921 3.03291 11.7817C6.27492 13.5155 9.52303 15.2378 12.761 16.9792C13.2352 17.2343 13.6394 17.2322 14.1129 16.9772C17.3509 15.2358 20.5996 13.5142 23.8416 11.7796C24.0095 11.69 24.1338 11.6818 24.3016 11.7789C24.7384 12.0339 25.1821 12.2794 25.6352 12.5037C25.9701 12.6691 26.2426 12.8831 26.3995 13.2304C26.3988 13.4014 26.3988 13.5716 26.3988 13.7412Z" fill="#003B8B"/>
</svg> `
static openFilterButton: string = `<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20 2L2 20M20 20L2 2" stroke="#003B8B" stroke-width="4"/>
</svg> `
static mapillaryLogo = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"32\" height=\"32\" fill=\"none\" viewBox=\"0 0 32 32\"><path fill=\"#fff\" fill-rule=\"evenodd\" d=\"M32 16c0 8.837-7.163 16-16 16S0 24.837 0 16 7.163 0 16 0s16 7.163 16 16zm-24.44-.974c-.371-.201-.303-.725.166-.859.398-.113 3.627-1.196 4.605-1.524a.59.59 0 00.373-.369l1.57-4.603c.146-.43.678-.432.894-.015.024.046.325.593.731 1.331v.001c.896 1.629 2.302 4.185 2.372 4.34a.473.473 0 01-.194.617c-.133.083-.314.19-.469.28l-.269.16c-.237.148-.464.045-.573-.183-.065-.137-.39-.719-.713-1.299-.217-.389-.433-.776-.57-1.027-.17-.313-.682-.433-.854.072l-.566 1.66a.613.613 0 01-.376.373l-1.703.564c-.336.111-.5.626-.046.843.038.018.383.202.798.423h.001c.631.337 1.425.76 1.552.82.21.1.328.39.204.595-.168.28-.384.635-.462.75a.48.48 0 01-.626.149c-.223-.119-5.711-3.027-5.844-3.099zm7.378 3.9c.288.147 7.276 3.844 7.496 3.963.441.238.907-.222.668-.652-.041-.073-.507-.929-1.107-2.034l-.002-.004c-1.166-2.144-2.84-5.224-2.925-5.365-.128-.214-.442-.322-.678-.178-.232.14-.498.298-.648.374-.3.153-.338.383-.203.639.297.562 1.232 2.267 1.34 2.446.223.374-.276.801-.615.615-.054-.03-.408-.217-.834-.442-.697-.368-1.587-.839-1.684-.896-.157-.09-.435-.09-.626.218-.138.224-.308.502-.386.642-.155.274-.084.527.204.674z\" clip-rule=\"evenodd\" style=\"transition: all 0.2s ease 0s;\"></path></svg>"
}

View file

@ -4,6 +4,8 @@ import {UIElement} from "../UIElement";
import Combine from "../Base/Combine";
import {SubtleButton} from "../Base/SubtleButton";
import {FixedUiElement} from "../Base/FixedUiElement";
import Svg from "../../Svg";
import {Img} from "../Img";
export class MultiInput<T> extends InputElement<T[]> {
@ -28,7 +30,7 @@ export class MultiInput<T> extends InputElement<T[]> {
this.ListenTo(value.map((latest : T[]) => latest.length));
this._options = options ?? {};
this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement)
this.addTag = new SubtleButton(Img.AsData(Svg.addSmall), addAElement)
.SetClass("small-button")
.onClick(() => {
this.IsSelected.setData(true);
@ -70,7 +72,7 @@ export class MultiInput<T> extends InputElement<T[]> {
this.inputELements.push(input);
input.IsSelected.addCallback(() => this.UpdateIsSelected());
const moveUpBtn = new FixedUiElement("<img src='./assets/up.svg' style='max-width: 1.5em; margin-left: 5px;'>")
const moveUpBtn = new FixedUiElement(Img.AsData(Svg.up))
.onClick(() => {
const v = self._value.data[i];
self._value.data[i] = self._value.data[i - 1];

View file

@ -8,6 +8,8 @@ import State from "../State";
import {VariableUiElement} from "./Base/VariableUIElement";
import {PersonalLayout} from "../Logic/PersonalLayout";
import {Layout} from "../Customizations/Layout";
import Svg from "../Svg";
import {Img} from "./Img";
export class MoreScreen extends UIElement {
@ -77,7 +79,8 @@ export class MoreScreen extends UIElement {
if (userDetails.csCount < State.userJourney.themeGeneratorReadOnlyUnlock) {
return tr.requestATheme.Render();
}
return new SubtleButton("./assets/pencil.svg", tr.createYourOwnTheme, {
return new SubtleButton(
Img.AsData(Svg.pencil), tr.createYourOwnTheme, {
url: "./customGenerator.html",
newTab: false
}).Render();

View file

@ -1,12 +1,12 @@
import {UIElement} from "../UIElement";
import {UIEventSource} from "../../Logic/UIEventSource";
import TagRenderingConfig from "../../Customizations/JSON/TagRenderingConfig";
import {FixedUiElement} from "../Base/FixedUiElement";
import TagRenderingQuestion from "./TagRenderingQuestion";
import Translations from "../i18n/Translations";
import Combine from "../Base/Combine";
import TagRenderingAnswer from "./TagRenderingAnswer";
import State from "../../State";
import Svg from "../../Svg";
export default class EditableTagRendering extends UIElement {
private _tags: UIEventSource<any>;
@ -35,9 +35,8 @@ export default class EditableTagRendering extends UIElement {
if (this._configuration.question !== undefined) {
// 2.3em total width
this._editButton = new FixedUiElement(
"<img style='width: 1.3em;height: 1.3em;padding: 0.5em;border-radius: 0.65em;border: solid black 1px;font-size: medium;float: right;' " +
"src='./assets/pencil.svg' alt='edit'>")
this._editButton =
Svg.pencil_ui().SetClass("edit-button")
.onClick(() => {
self._editMode.setData(true);
});

View file

@ -42,7 +42,7 @@ export class FeatureInfoBox extends UIElement {
new Combine([this._title, this._titleIcons])
.SetClass("featureinfobox-titlebar"),
...this._renderings,
this._questionBox
this._questionBox,
]).Render();
}

View file

@ -5,7 +5,6 @@ import TagRenderingConfig from "../../Customizations/JSON/TagRenderingConfig";
import {InputElement} from "../Input/InputElement";
import {And, Tag, TagsFilter, TagUtils} from "../../Logic/Tags";
import ValidatedTextField from "../Input/ValidatedTextField";
import {Translation} from "../i18n/Translations";
import {FixedInputElement} from "../Input/FixedInputElement";
import {SubstitutedTranslation} from "../SpecialVisualizations";
import {RadioButton} from "../Input/RadioButton";
@ -18,6 +17,7 @@ import {Changes} from "../../Logic/Osm/Changes";
import {VariableUiElement} from "../Base/VariableUIElement";
import Translations from "../i18n/Translations";
import {FixedUiElement} from "../Base/FixedUiElement";
import {Translation} from "../i18n/Translation";
/**
* Shows the question element.

View file

@ -1,30 +1,28 @@
import Locale from "./i18n/Locale";
import {UIElement} from "./UIElement";
import Translation from "./i18n/Translation";
import {VariableUiElement} from "./Base/VariableUIElement";
import {FixedUiElement} from "./Base/FixedUiElement";
import {TextField} from "./Input/TextField";
import {Geocoding} from "../Logic/Osm/Geocoding";
import Translations from "./i18n/Translations";
import State from "../State";
import {UIEventSource} from "../Logic/UIEventSource";
import Svg from "../Svg";
import {Translation} from "./i18n/Translation";
export class SearchAndGo extends UIElement {
private _placeholder = new UIEventSource<Translation>(Translations.t.general.search.search)
private _searchField = new TextField<string>({
private _searchField = new TextField({
placeholder: new VariableUiElement(
this._placeholder.map(uiElement => uiElement.InnerRender(), [Locale.language])
),
fromString: str => str,
toString: str => str,
value: new UIEventSource<string>("")
}
);
private _foundEntries = new UIEventSource([]);
private _goButton = new FixedUiElement("<img class='search-go' src='./assets/search.svg' alt='GO'>");
private _goButton = Svg.search_ui().SetClass('search-go');
constructor() {
super(undefined);

View file

@ -11,9 +11,10 @@ import {Basemap} from "../Logic/Leaflet/Basemap";
import {FilteredLayer} from "../Logic/FilteredLayer";
import {Utils} from "../Utils";
import {UIEventSource} from "../Logic/UIEventSource";
import Translation from "./i18n/Translation";
import {SubtleButton} from "./Base/SubtleButton";
import {Layout} from "../Customizations/Layout";
import Svg from "../Svg";
import {Translation} from "./i18n/Translation";
export class ShareScreen extends UIElement {
private readonly _options: UIElement;
@ -186,7 +187,7 @@ export class ShareScreen extends UIElement {
return "";
}
return new SubtleButton("./assets/pencil.svg",
return new SubtleButton(Img.AsData(Svg.pencil),
new Combine([tr.editThisTheme.SetClass("bold"), "<br/>",
tr.editThemeDescription]),
{url: `./customGenerator.html#${State.state.layoutDefinition}`, newTab: true}).Render();

View file

@ -8,6 +8,8 @@ import Locale from "./i18n/Locale";
import State from "../State";
import {UIEventSource} from "../Logic/UIEventSource";
import {Img} from "./Img";
import Svg from "../Svg";
/**
* Asks to add a feature at the last clicked location, at least if zoom is sufficient
@ -28,7 +30,7 @@ export class SimpleAddUI extends UIElement {
private confirmButton: UIElement = undefined;
private openLayerControl: UIElement;
private cancelButton: UIElement;
private goToInboxButton: UIElement = new SubtleButton("./assets/envelope.svg",
private goToInboxButton: UIElement = new SubtleButton(Img.AsData(Svg.envelope),
Translations.t.general.goToInbox, {url:"https://www.openstreetmap.org/messages/inbox", newTab: false});
constructor() {
@ -52,8 +54,7 @@ export class SimpleAddUI extends UIElement {
const presets = layer.layerDef.presets;
for (const preset of presets) {
let icon: string = layer.layerDef.icon.GetRenderValue(
TagUtils.KVtoProperties(preset.tags ?? [])).txt ??
"./assets/bug.svg";
TagUtils.KVtoProperties(preset.tags ?? [])).txt
const csCount = State.state.osmConnection.userDetails.data.csCount;
let tagInfo = "";
@ -97,14 +98,14 @@ export class SimpleAddUI extends UIElement {
}
this.cancelButton = new SubtleButton(
"./assets/close.svg",
Img.AsData(Svg.close),
Translations.t.general.cancel
).onClick(() => {
self._confirmPreset.setData(undefined);
})
this.openLayerControl = new SubtleButton(
"./assets/layers.svg",
Img.AsData(Svg.layers),
Translations.t.general.add.openLayerControl
).onClick(() => {
State.state.layerControlIsOpened.setData(true);
@ -169,9 +170,8 @@ export class SimpleAddUI extends UIElement {
}
if (userDetails.data.unreadMessages > 0 && userDetails.data.csCount < State.userJourney.addNewPointWithUnreadMessagesUnlock) {
return new Combine([header, "<span class='alert'>",
Translations.t.general.readYourMessages,
"</span>",
return new Combine([header,
Translations.t.general.readYourMessages.Clone().SetClass("alert"),
this.goToInboxButton
]).Render();

View file

@ -4,11 +4,11 @@ import {UIEventSource} from "../Logic/UIEventSource";
import {VariableUiElement} from "./Base/VariableUIElement";
import LiveQueryHandler from "../Logic/Web/LiveQueryHandler";
import {ImageCarousel} from "./Image/ImageCarousel";
import {Translation} from "./i18n/Translations";
import Combine from "./Base/Combine";
import {FixedUiElement} from "./Base/FixedUiElement";
import Locale from "../UI/i18n/Locale";
import {ImageUploadFlow} from "./Image/ImageUploadFlow";
import {Translation} from "./i18n/Translation";
export class SubstitutedTranslation extends UIElement {
private readonly tags: UIEventSource<any>;

View file

@ -7,10 +7,10 @@ import {UserDetails} from "../Logic/Osm/OsmConnection";
import State from "../State";
import {UIEventSource} from "../Logic/UIEventSource";
import Combine from "./Base/Combine";
import Locale from "./i18n/Locale";
import Svg from "../Svg";
import Link from "./Base/Link";
import {Img} from "./Img";
import LanguagePicker from "./LanguagePicker";
/**
* Handles and updates the user badge
@ -26,7 +26,7 @@ export class UserBadge extends UIElement {
constructor() {
super(State.state.osmConnection.userDetails);
this._userDetails = State.state.osmConnection.userDetails;
this._languagePicker = (Locale.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages) ?? new FixedUiElement(""))
this._languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages) ?? new FixedUiElement(""))
.SetStyle("display:inline-block;width:min-content;");
this._loginButton = Translations.t.general.loginWithOpenStreetMap

View file

@ -3,6 +3,7 @@ import Locale from "../UI/i18n/Locale";
import State from "../State";
import Translations from "./i18n/Translations";
import Combine from "./Base/Combine";
import LanguagePicker from "./LanguagePicker";
export class WelcomeMessage extends UIElement {
@ -17,7 +18,7 @@ export class WelcomeMessage extends UIElement {
constructor() {
super(State.state.osmConnection.userDetails);
this.ListenTo(Locale.language);
this.languagePicker = Locale.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages, Translations.t.general.pickLanguage);
this.languagePicker = LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.supportedLanguages, Translations.t.general.pickLanguage);
const layout = State.state.layoutToUse.data;
this.description =Translations.W(layout.welcomeMessage);

103
UI/i18n/Translation.ts Normal file
View file

@ -0,0 +1,103 @@
import {UIElement} from "../UIElement";
import Combine from "../Base/Combine";
import Locale from "./Locale";
import {Utils} from "../../Utils";
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);
}
}

View file

@ -1,110 +1,7 @@
import {UIElement} from "../UIElement";
import {FixedUiElement} from "../Base/FixedUiElement";
import Combine from "../Base/Combine";
import Locale from "./Locale";
import {Utils} from "../../Utils";
import * as TranslationsJson from "../../assets/translations.json"
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);
}
}
import AllTranslationAssets from "../../AllTranslationAssets";
import {Translation} from "./Translation";
export default class Translations {
@ -112,7 +9,7 @@ export default class Translations {
throw "Translations is static. If you want to intitialize a new translation, use the singular form"
}
static t = TranslationsJson;
static t = AllTranslationAssets.t;
private static isTranslation(tr: any): boolean {
for (const key in tr) {
@ -123,27 +20,6 @@ export default class Translations {
return true;
}
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]);
} else if(tr[subKey].translations === undefined /**should not be a translation already*/){
queue.push(tr[subKey]);
}
}
for (const subKey in copy) {
tr[subKey] = copy[subKey]
}
}
return true;
}
private static isInited = Translations.InitT();
public static W(s: string | UIElement): UIElement {
if (typeof (s) === "string") {