Merge develop

This commit is contained in:
Pieter Vander Vennet 2022-04-13 02:44:42 +02:00
commit 01ba686270
50 changed files with 686 additions and 860 deletions

View file

@ -22,7 +22,7 @@ import {OsmConnection} from "../../Logic/Osm/OsmConnection";
import Constants from "../../Models/Constants";
import ContributorCount from "../../Logic/ContributorCount";
import Img from "../Base/Img";
import {Translation} from "../i18n/Translation";
import {TypedTranslation} from "../i18n/Translation";
import TranslatorsPanel from "./TranslatorsPanel";
export class OpenIdEditor extends VariableUiElement {
@ -198,7 +198,7 @@ export default class CopyrightPanel extends Combine {
this.SetStyle("max-width:100%; width: 40rem; margin-left: 0.75rem; margin-right: 0.5rem")
}
private static CodeContributors(contributors, translation: Translation): BaseUIElement {
private static CodeContributors(contributors, translation: TypedTranslation<{contributors, hiddenCount}>): BaseUIElement {
const total = contributors.contributors.length;
let filtered = [...contributors.contributors]

View file

@ -14,7 +14,7 @@ import Title from "../Base/Title";
import {UIEventSource} from "../../Logic/UIEventSource";
import {SubtleButton} from "../Base/SubtleButton";
import Svg from "../../Svg";
import * as native_languages from "../../assets/language_native.json"
class TranslatorsPanelContent extends Combine {
constructor(layout: LayoutConfig, isTranslator: UIEventSource<boolean>) {
@ -48,7 +48,8 @@ class TranslatorsPanelContent extends Combine {
// "translationCompleteness": "Translations for {theme} in {language} are at {percentage}: {translated} out of {total}",
const translated = seed.Subs({total, theme: layout.title,
percentage: new Translation(completenessPercentage),
translated: new Translation(completenessTr)
translated: new Translation(completenessTr),
language: seed.OnEveryLanguage((_, lng) => native_languages[lng])
})
super([

View file

@ -25,7 +25,7 @@ export default class ReviewElement extends VariableUiElement {
SingleReview.GenStars(avg),
new Link(
revs.length === 1 ? Translations.t.reviews.title_singular.Clone() :
Translations.t.reviews.title.Clone()
Translations.t.reviews.title
.Subs({count: "" + revs.length}),
`https://mangrove.reviews/search?sub=${encodeURIComponent(subject)}`,
true

View file

@ -1,7 +1,7 @@
import {VariableUiElement} from "../Base/VariableUIElement";
import {UIEventSource} from "../../Logic/UIEventSource";
import Wikidata, {WikidataResponse} from "../../Logic/Web/Wikidata";
import {Translation} from "../i18n/Translation";
import {Translation, TypedTranslation} from "../i18n/Translation";
import {FixedUiElement} from "../Base/FixedUiElement";
import Loading from "../Base/Loading";
import Translations from "../i18n/Translations";
@ -22,7 +22,7 @@ export default class WikidataPreviewBox extends VariableUiElement {
private static extraProperties: {
requires?: { p: number, q?: number }[],
property: string,
display: Translation | Map<string, string | (() => BaseUIElement) /*If translation: Subs({value: * }) */>
display: TypedTranslation<{value}> | Map<string, string | (() => BaseUIElement) /*If translation: Subs({value: * }) */>
}[] = [
{
requires: WikidataPreviewBox.isHuman,

View file

@ -1,9 +1,6 @@
import Locale from "./Locale";
import {Utils} from "../../Utils";
import BaseUIElement from "../BaseUIElement";
import Link from "../Base/Link";
import Svg from "../../Svg";
import {VariableUiElement} from "../Base/VariableUIElement";
import LinkToWeblate from "../Base/LinkToWeblate";
export class Translation extends BaseUIElement {
@ -164,25 +161,7 @@ export class Translation extends BaseUIElement {
public AllValues(): string[] {
return this.SupportedLanguages().map(lng => this.translations[lng]);
}
/**
* Substitutes text in a translation.
* If a translation is passed, it'll be fused
*
* // Should replace simple keys
* new Translation({"en": "Some text {key}"}).Subs({key: "xyz"}).textFor("en") // => "Some text xyz"
*
* // Should fuse translations
* const subpart = new Translation({"en": "subpart","nl":"onderdeel"})
* const tr = new Translation({"en": "Full sentence with {part}", nl: "Volledige zin met {part}"})
* const subbed = tr.Subs({part: subpart})
* subbed.textFor("en") // => "Full sentence with subpart"
* subbed.textFor("nl") // => "Volledige zin met onderdeel"
*/
public Subs(text: any, context?: string): Translation {
return this.OnEveryLanguage((template, lang) => Utils.SubstituteKeys(template, text, lang), context)
}
public OnEveryLanguage(f: (s: string, language: string) => string, context?: string): Translation {
const newTranslations = {};
for (const lang in this.translations) {
@ -278,5 +257,28 @@ export class Translation extends BaseUIElement {
return this.txt
}
}
export class TypedTranslation<T> extends Translation {
constructor(translations: object, context?: string) {
super(translations, context);
}
/**
* Substitutes text in a translation.
* If a translation is passed, it'll be fused
*
* // Should replace simple keys
* new TypedTranslation<object>({"en": "Some text {key}"}).Subs({key: "xyz"}).textFor("en") // => "Some text xyz"
*
* // Should fuse translations
* const subpart = new Translation({"en": "subpart","nl":"onderdeel"})
* const tr = new TypedTranslation<object>({"en": "Full sentence with {part}", nl: "Volledige zin met {part}"})
* const subbed = tr.Subs({part: subpart})
* subbed.textFor("en") // => "Full sentence with subpart"
* subbed.textFor("nl") // => "Volledige zin met onderdeel"
*/
Subs(text: T, context?: string): Translation {
return this.OnEveryLanguage((template, lang) => Utils.SubstituteKeys(template, text, lang), context)
}
}

View file

@ -1,5 +1,5 @@
import {FixedUiElement} from "../Base/FixedUiElement";
import {Translation} from "./Translation";
import {Translation, TypedTranslation} from "./Translation";
import BaseUIElement from "../BaseUIElement";
import * as known_languages from "../../assets/generated/used_languages.json"
import CompiledTranslations from "../../assets/generated/CompiledTranslations";
@ -22,7 +22,7 @@ export default class Translations {
return s;
}
static T(t: string | any, context = undefined): Translation {
static T(t: string | any, context = undefined): TypedTranslation<object> {
if (t === undefined || t === null) {
return undefined;
}
@ -30,17 +30,17 @@ export default class Translations {
t = "" + t
}
if (typeof t === "string") {
return new Translation({"*": t}, context);
return new TypedTranslation({"*": t}, context);
}
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
}
if (t instanceof Translation) {
if (t instanceof TypedTranslation) {
return t;
}
return new Translation(t, context);
return new TypedTranslation(t, context);
}
/**