| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import Toggle from "../Input/Toggle" | 
					
						
							|  |  |  | import Lazy from "../Base/Lazy" | 
					
						
							|  |  |  | import { Utils } from "../../Utils" | 
					
						
							|  |  |  | import Translations from "../i18n/Translations" | 
					
						
							|  |  |  | import Combine from "../Base/Combine" | 
					
						
							|  |  |  | import Locale from "../i18n/Locale" | 
					
						
							|  |  |  | import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig" | 
					
						
							|  |  |  | import { Translation } from "../i18n/Translation" | 
					
						
							|  |  |  | import { VariableUiElement } from "../Base/VariableUIElement" | 
					
						
							|  |  |  | import Link from "../Base/Link" | 
					
						
							|  |  |  | import LinkToWeblate from "../Base/LinkToWeblate" | 
					
						
							|  |  |  | import Toggleable from "../Base/Toggleable" | 
					
						
							|  |  |  | import Title from "../Base/Title" | 
					
						
							|  |  |  | import { Store, UIEventSource } from "../../Logic/UIEventSource" | 
					
						
							|  |  |  | import { SubtleButton } from "../Base/SubtleButton" | 
					
						
							|  |  |  | import Svg from "../../Svg" | 
					
						
							| 
									
										
										
										
											2022-04-13 01:19:28 +02:00
										 |  |  | import * as native_languages from "../../assets/language_native.json" | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  | import * as used_languages from "../../assets/generated/used_languages.json" | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import BaseUIElement from "../BaseUIElement" | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TranslatorsPanelContent extends Combine { | 
					
						
							| 
									
										
										
										
											2022-06-19 13:55:33 +02:00
										 |  |  |     constructor(layout: LayoutConfig, isTranslator: Store<boolean>) { | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         const t = Translations.t.translations | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const { completeness, untranslated, total } = | 
					
						
							|  |  |  |             TranslatorsPanel.MissingTranslationsFor(layout) | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         const seed = t.completeness | 
					
						
							|  |  |  |         for (const ln of Array.from(completeness.keys())) { | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |             if (ln === "*") { | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |                 continue | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (seed.translations[ln] === undefined) { | 
					
						
							|  |  |  |                 seed.translations[ln] = seed.translations["en"] | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         const completenessTr = {} | 
					
						
							|  |  |  |         const completenessPercentage = {} | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         seed.SupportedLanguages().forEach((ln) => { | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |             completenessTr[ln] = "" + (completeness.get(ln) ?? 0) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             completenessPercentage[ln] = | 
					
						
							|  |  |  |                 "" + Math.round((100 * (completeness.get(ln) ?? 0)) / total) | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |         function missingTranslationsFor(language: string): BaseUIElement[] { | 
					
						
							|  |  |  |             // e.g. "themes:<themename>.layers.0.tagRenderings..., or "layers:<layername>.description
 | 
					
						
							|  |  |  |             const missingKeys = Utils.NoNull(untranslated.get(language) ?? []) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 .filter((ctx) => ctx.indexOf(":") >= 0) | 
					
						
							|  |  |  |                 .map((ctx) => ctx.replace(/note_import_[a-zA-Z0-9_]*/, "note_import")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const hasMissingTheme = missingKeys.some((k) => k.startsWith("themes:")) | 
					
						
							|  |  |  |             const missingLayers = Utils.Dedup( | 
					
						
							|  |  |  |                 missingKeys | 
					
						
							|  |  |  |                     .filter((k) => k.startsWith("layers:")) | 
					
						
							|  |  |  |                     .map((k) => k.slice("layers:".length).split(".")[0]) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             console.log( | 
					
						
							|  |  |  |                 "Getting untranslated string for", | 
					
						
							|  |  |  |                 language, | 
					
						
							|  |  |  |                 "raw:", | 
					
						
							|  |  |  |                 missingKeys, | 
					
						
							|  |  |  |                 "hasMissingTheme:", | 
					
						
							|  |  |  |                 hasMissingTheme, | 
					
						
							|  |  |  |                 "missingLayers:", | 
					
						
							|  |  |  |                 missingLayers | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |             return [ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 hasMissingTheme | 
					
						
							|  |  |  |                     ? new Link( | 
					
						
							|  |  |  |                           "themes:" + layout.id + ".* (zen mode)", | 
					
						
							|  |  |  |                           LinkToWeblate.hrefToWeblateZen(language, "themes", layout.id), | 
					
						
							|  |  |  |                           true | 
					
						
							|  |  |  |                       ) | 
					
						
							|  |  |  |                     : undefined, | 
					
						
							|  |  |  |                 ...missingLayers.map( | 
					
						
							|  |  |  |                     (id) => | 
					
						
							|  |  |  |                         new Link( | 
					
						
							|  |  |  |                             "layer:" + id + ".* (zen mode)", | 
					
						
							|  |  |  |                             LinkToWeblate.hrefToWeblateZen(language, "layers", id), | 
					
						
							|  |  |  |                             true | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |                 ...missingKeys.map( | 
					
						
							|  |  |  |                     (context) => | 
					
						
							|  |  |  |                         new Link(context, LinkToWeblate.hrefToWeblate(language, context), true) | 
					
						
							|  |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |             ] | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |         //
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         //
 | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |         // "translationCompleteness": "Translations for {theme} in {language} are at {percentage}: {translated} out of {total}",
 | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |         const translated = seed.Subs({ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             total, | 
					
						
							|  |  |  |             theme: layout.title, | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |             percentage: new Translation(completenessPercentage), | 
					
						
							| 
									
										
										
										
											2022-04-13 01:19:28 +02:00
										 |  |  |             translated: new Translation(completenessTr), | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             language: seed.OnEveryLanguage((_, lng) => native_languages[lng] ?? lng), | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         super([ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             new Title(Translations.t.translations.activateButton), | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |             new Toggle(t.isTranslator.SetClass("thanks block"), undefined, isTranslator), | 
					
						
							|  |  |  |             t.help, | 
					
						
							|  |  |  |             translated, | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |             /*Disable button:*/ | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             new SubtleButton(undefined, t.deactivate).onClick(() => { | 
					
						
							|  |  |  |                 Locale.showLinkToWeblate.setData(false) | 
					
						
							|  |  |  |             }), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             new VariableUiElement( | 
					
						
							|  |  |  |                 Locale.language.map((ln) => { | 
					
						
							|  |  |  |                     const missing = missingTranslationsFor(ln) | 
					
						
							|  |  |  |                     if (missing.length === 0) { | 
					
						
							|  |  |  |                         return undefined | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     let title = Translations.t.translations.allMissing | 
					
						
							|  |  |  |                     if (untranslated.get(ln) !== undefined) { | 
					
						
							|  |  |  |                         title = Translations.t.translations.missing.Subs({ | 
					
						
							|  |  |  |                             count: untranslated.get(ln).length, | 
					
						
							|  |  |  |                         }) | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     return new Toggleable( | 
					
						
							|  |  |  |                         new Title(title), | 
					
						
							|  |  |  |                         new Combine(missing).SetClass("flex flex-col") | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         ]) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default class TranslatorsPanel extends Toggle { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     constructor( | 
					
						
							|  |  |  |         state: { layoutToUse: LayoutConfig; isTranslator: Store<boolean> }, | 
					
						
							|  |  |  |         iconStyle?: string | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         const t = Translations.t.translations | 
					
						
							|  |  |  |         super( | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             new Lazy( | 
					
						
							|  |  |  |                 () => new TranslatorsPanelContent(state.layoutToUse, state.isTranslator) | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |             ).SetClass("flex flex-col"), | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             new SubtleButton(Svg.translate_ui().SetStyle(iconStyle), t.activateButton).onClick(() => | 
					
						
							|  |  |  |                 Locale.showLinkToWeblate.setData(true) | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  |             Locale.showLinkToWeblate | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  |         this.SetClass("hidden-on-mobile") | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |     public static MissingTranslationsFor(layout: LayoutConfig): { | 
					
						
							|  |  |  |         completeness: Map<string, number> | 
					
						
							|  |  |  |         untranslated: Map<string, string[]> | 
					
						
							|  |  |  |         total: number | 
					
						
							|  |  |  |     } { | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |         let total = 0 | 
					
						
							|  |  |  |         const completeness = new Map<string, number>() | 
					
						
							|  |  |  |         const untranslated = new Map<string, string[]>() | 
					
						
							| 
									
										
										
										
											2022-04-15 00:10:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         Utils.WalkObject( | 
					
						
							|  |  |  |             layout, | 
					
						
							|  |  |  |             (o) => { | 
					
						
							|  |  |  |                 const translation = <Translation>(<any>o) | 
					
						
							|  |  |  |                 if (translation.translations["*"] !== undefined) { | 
					
						
							|  |  |  |                     return | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (translation.context === undefined || translation.context.indexOf(":") < 0) { | 
					
						
							|  |  |  |                     // no source given - lets ignore
 | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 total++ | 
					
						
							|  |  |  |                 used_languages.languages.forEach((ln) => { | 
					
						
							|  |  |  |                     const trans = translation.translations | 
					
						
							|  |  |  |                     if (trans["*"] !== undefined) { | 
					
						
							|  |  |  |                         return | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     if (trans[ln] === undefined) { | 
					
						
							|  |  |  |                         if (!untranslated.has(ln)) { | 
					
						
							|  |  |  |                             untranslated.set(ln, []) | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                         untranslated.get(ln).push(translation.context) | 
					
						
							|  |  |  |                     } else { | 
					
						
							|  |  |  |                         completeness.set(ln, 1 + (completeness.get(ln) ?? 0)) | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 }) | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             (o) => { | 
					
						
							|  |  |  |                 if (o === undefined || o === null) { | 
					
						
							|  |  |  |                     return false | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return o instanceof Translation | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         return { completeness, untranslated, total } | 
					
						
							| 
									
										
										
										
											2022-04-01 21:17:27 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-04-01 12:51:55 +02:00
										 |  |  | } |