forked from MapComplete/MapComplete
		
	Better translators panel
This commit is contained in:
		
							parent
							
								
									063ccd2025
								
							
						
					
					
						commit
						7d7abc303b
					
				
					 3 changed files with 58 additions and 30 deletions
				
			
		|  | @ -4,6 +4,7 @@ import Link from "./Link"; | ||||||
| import Svg from "../../Svg"; | import Svg from "../../Svg"; | ||||||
| 
 | 
 | ||||||
| export default class LinkToWeblate extends VariableUiElement { | export default class LinkToWeblate extends VariableUiElement { | ||||||
|  |     private static URI: any; | ||||||
|     constructor(context: string, availableTranslations: object) { |     constructor(context: string, availableTranslations: object) { | ||||||
|         super( Locale.language.map(ln => { |         super( Locale.language.map(ln => { | ||||||
|             if (Locale.showLinkToWeblate.data === false) { |             if (Locale.showLinkToWeblate.data === false) { | ||||||
|  | @ -36,4 +37,10 @@ export default class LinkToWeblate extends VariableUiElement { | ||||||
|         const baseUrl = "https://hosted.weblate.org/translate/mapcomplete/" |         const baseUrl = "https://hosted.weblate.org/translate/mapcomplete/" | ||||||
|         return baseUrl + category + "/" + language + "/?offset=1&q=context%3A%3D%22" + key + "%22" |         return baseUrl + category + "/" + language + "/?offset=1&q=context%3A%3D%22" + key + "%22" | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public static hrefToWeblateZen(language: string, category: string, searchKey: string): string{ | ||||||
|  |         const baseUrl = "https://hosted.weblate.org/zen/mapcomplete/" | ||||||
|  |         // ?offset=1&q=+state%3A%3Ctranslated+context%3Acampersite&sort_by=-priority%2Cposition&checksum=
 | ||||||
|  |         return baseUrl + category + "/" + language + "?offset=1&q=+state%3A%3Ctranslated+context%3A"+encodeURIComponent(searchKey)+"&sort_by=-priority%2Cposition&checksum=" | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -15,6 +15,8 @@ import {UIEventSource} from "../../Logic/UIEventSource"; | ||||||
| import {SubtleButton} from "../Base/SubtleButton"; | import {SubtleButton} from "../Base/SubtleButton"; | ||||||
| import Svg from "../../Svg"; | import Svg from "../../Svg"; | ||||||
| import * as native_languages from "../../assets/language_native.json" | import * as native_languages from "../../assets/language_native.json" | ||||||
|  | import * as used_languages from "../../assets/generated/used_languages.json" | ||||||
|  | import BaseUIElement from "../BaseUIElement"; | ||||||
| 
 | 
 | ||||||
| class TranslatorsPanelContent extends Combine { | class TranslatorsPanelContent extends Combine { | ||||||
|     constructor(layout: LayoutConfig, isTranslator: UIEventSource<boolean>) { |     constructor(layout: LayoutConfig, isTranslator: UIEventSource<boolean>) { | ||||||
|  | @ -39,17 +41,33 @@ class TranslatorsPanelContent extends Combine { | ||||||
|             completenessPercentage[ln] = "" + Math.round(100 * (completeness.get(ln) ?? 0) / total) |             completenessPercentage[ln] = "" + Math.round(100 * (completeness.get(ln) ?? 0) / total) | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|         const missingTranslationsFor = (ln: string) => Utils.NoNull(untranslated.get(ln) ?? []) |         function missingTranslationsFor(language: string): BaseUIElement[] { | ||||||
|  |             // e.g. "themes:<themename>.layers.0.tagRenderings..., or "layers:<layername>.description
 | ||||||
|  |             const missingKeys = Utils.NoNull(untranslated.get(language) ?? []) | ||||||
|                 .filter(ctx => ctx.indexOf(":") >= 0) |                 .filter(ctx => ctx.indexOf(":") >= 0) | ||||||
|                 .map(ctx => ctx.replace(/note_import_[a-zA-Z0-9_]*/, "note_import")) |                 .map(ctx => ctx.replace(/note_import_[a-zA-Z0-9_]*/, "note_import")) | ||||||
|             .map(context => new Link(context, LinkToWeblate.hrefToWeblate(ln, context), true)) | 
 | ||||||
|  |             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) | ||||||
|  |             return [ | ||||||
|  |                 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)) | ||||||
|  |             ] | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |         //
 | ||||||
|  |         // 
 | ||||||
|         // "translationCompleteness": "Translations for {theme} in {language} are at {percentage}: {translated} out of {total}",
 |         // "translationCompleteness": "Translations for {theme} in {language} are at {percentage}: {translated} out of {total}",
 | ||||||
|         const translated = seed.Subs({total, theme: layout.title, |         const translated = seed.Subs({ | ||||||
|  |             total, theme: layout.title, | ||||||
|             percentage: new Translation(completenessPercentage), |             percentage: new Translation(completenessPercentage), | ||||||
|             translated: new Translation(completenessTr), |             translated: new Translation(completenessTr), | ||||||
|             language: seed.OnEveryLanguage((_, lng) => native_languages[lng]) |             language: seed.OnEveryLanguage((_, lng) => native_languages[lng] ?? lng) | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|         super([ |         super([ | ||||||
|  | @ -66,13 +84,16 @@ class TranslatorsPanelContent extends Combine { | ||||||
|                 }), |                 }), | ||||||
| 
 | 
 | ||||||
|             new VariableUiElement(Locale.language.map(ln => { |             new VariableUiElement(Locale.language.map(ln => { | ||||||
| 
 |  | ||||||
|                 const missing = missingTranslationsFor(ln) |                 const missing = missingTranslationsFor(ln) | ||||||
|                 if (missing.length === 0) { |                 if (missing.length === 0) { | ||||||
|                     return undefined |                     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( |                 return new Toggleable( | ||||||
|                     new Title(Translations.t.translations.missing.Subs({count: missing.length})), |                     new Title(title), | ||||||
|                     new Combine(missing).SetClass("flex flex-col") |                     new Combine(missing).SetClass("flex flex-col") | ||||||
|                 ) |                 ) | ||||||
|             })) |             })) | ||||||
|  | @ -102,6 +123,7 @@ export default class TranslatorsPanel extends Toggle { | ||||||
|         let total = 0 |         let total = 0 | ||||||
|         const completeness = new Map<string, number>() |         const completeness = new Map<string, number>() | ||||||
|         const untranslated = new Map<string, string[]>() |         const untranslated = new Map<string, string[]>() | ||||||
|  | 
 | ||||||
|         Utils.WalkObject(layout, (o, path) => { |         Utils.WalkObject(layout, (o, path) => { | ||||||
|             const translation = <Translation><any>o; |             const translation = <Translation><any>o; | ||||||
|             if (translation.translations["*"] !== undefined) { |             if (translation.translations["*"] !== undefined) { | ||||||
|  | @ -112,10 +134,8 @@ export default class TranslatorsPanel extends Toggle { | ||||||
|                 return |                 return | ||||||
|             } |             } | ||||||
|              |              | ||||||
|             for (const lang of translation.SupportedLanguages()) { |             total ++ | ||||||
|                 completeness.set(lang, 1 + (completeness.get(lang) ?? 0)) |             used_languages.languages.forEach(ln => { | ||||||
|             } |  | ||||||
|             layout.title.SupportedLanguages().forEach(ln => { |  | ||||||
|                 const trans = translation.translations |                 const trans = translation.translations | ||||||
|                 if (trans["*"] !== undefined) { |                 if (trans["*"] !== undefined) { | ||||||
|                     return; |                     return; | ||||||
|  | @ -125,11 +145,11 @@ export default class TranslatorsPanel extends Toggle { | ||||||
|                         untranslated.set(ln, []) |                         untranslated.set(ln, []) | ||||||
|                     } |                     } | ||||||
|                     untranslated.get(ln).push(translation.context) |                     untranslated.get(ln).push(translation.context) | ||||||
|  |                 }else{ | ||||||
|  |                     completeness.set(ln, 1 + (completeness.get(ln) ?? 0)) | ||||||
|                 } |                 } | ||||||
|             }) |             }) | ||||||
|             if(translation.translations["*"] === undefined){ |             | ||||||
|                 total++ |  | ||||||
|             } |  | ||||||
|         }, o => { |         }, o => { | ||||||
|             if (o === undefined || o === null) { |             if (o === undefined || o === null) { | ||||||
|                 return false; |                 return false; | ||||||
|  |  | ||||||
|  | @ -532,6 +532,7 @@ | ||||||
|     }, |     }, | ||||||
|     "translations": { |     "translations": { | ||||||
|         "activateButton": "Help to translate MapComplete", |         "activateButton": "Help to translate MapComplete", | ||||||
|  |         "allMissing": "No translations yet", | ||||||
|         "completeness": "Translations for {theme} in {language} are at {percentage}%: {translated} strings out of {total} are translated", |         "completeness": "Translations for {theme} in {language} are at {percentage}%: {translated} strings out of {total} are translated", | ||||||
|         "deactivate": "Disable translation buttons", |         "deactivate": "Disable translation buttons", | ||||||
|         "help": "Click the 'translate'-icon next to a string to enter or update a piece of text. You need a Weblate-account for this. Create one with your OSM-username to automatically unlock translation mode.", |         "help": "Click the 'translate'-icon next to a string to enter or update a piece of text. You need a Weblate-account for this. Create one with your OSM-username to automatically unlock translation mode.", | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue