forked from MapComplete/MapComplete
		
	Merge branch 'develop'
This commit is contained in:
		
						commit
						9d40af94e1
					
				
					 12 changed files with 224 additions and 228 deletions
				
			
		|  | @ -261,6 +261,10 @@ | |||
|                     "if": "theme=ghostsigns", | ||||
|                     "then": "./assets/themes/advertising/wall_painting.svg" | ||||
|                   }, | ||||
|                   { | ||||
|                     "if": "theme=glutenfree", | ||||
|                     "then": "./assets/themes/glutenfree/glutenfree.svg" | ||||
|                   }, | ||||
|                   { | ||||
|                     "if": "theme=grb", | ||||
|                     "then": "./assets/themes/grb/logo.svg" | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ export default abstract class Script { | |||
|                 const green = (s) => "\x1b[92m" + s + "\x1b[0m" | ||||
|                 console.log(green("All done! (" + millisNeeded + " ms)")) | ||||
|             }) | ||||
|             .catch((e) => console.log("ERROR:", e)) | ||||
|             .catch((e) => console.log("ERROR in script:", e)) | ||||
|     } | ||||
| 
 | ||||
|     public printHelp() { | ||||
|  |  | |||
|  | @ -35,7 +35,15 @@ export abstract class Conversion<TIn, TOut> { | |||
|     public convertStrict(json: TIn, context?: ConversionContext): TOut { | ||||
|         context ??= ConversionContext.construct([], []) | ||||
|         context = context.inOperation(this.name) | ||||
|         const fixed = this.convert(json, context) | ||||
| 
 | ||||
|         let fixed: TOut | ||||
|         try { | ||||
|             fixed = this.convert(json, context) | ||||
|         } catch (e) { | ||||
|             console.error(e) | ||||
|             context.err("ERROR WHILE RUNNING STEP " + this.name+": "+e) | ||||
|             fixed = undefined | ||||
|         } | ||||
|         for (const msg of context.messages) { | ||||
|             if (msg.level === "debug") { | ||||
|                 continue | ||||
|  | @ -46,11 +54,12 @@ export abstract class Conversion<TIn, TOut> { | |||
|             throw new Error( | ||||
|                 [ | ||||
|                     "Detected one or more errors, stopping now:", | ||||
|                     context.getAll("error").map((e) => e.context.path.join(".") + ": " + e.message), | ||||
|                     context.getAll("error").map((e) => e.context.path.join(".") + ": " + e.message) | ||||
|                 ].join("\n\t") | ||||
|             ) | ||||
|         } | ||||
|         return fixed | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public andThenF<X>(f: (tout: TOut) => X): Conversion<TIn, X> { | ||||
|  | @ -60,7 +69,8 @@ export abstract class Conversion<TIn, TOut> { | |||
|     public abstract convert(json: TIn, context: ConversionContext): TOut | ||||
| } | ||||
| 
 | ||||
| export abstract class DesugaringStep<T> extends Conversion<T, T> {} | ||||
| export abstract class DesugaringStep<T> extends Conversion<T, T> { | ||||
| } | ||||
| 
 | ||||
| export class Pipe<TIn, TInter, TOut> extends Conversion<TIn, TOut> { | ||||
|     private readonly _step0: Conversion<TIn, TInter> | ||||
|  | @ -247,7 +257,7 @@ export class Cached<TIn, TOut> extends Conversion<TIn, TOut> { | |||
|         const converted = this._step.convert(json, context) | ||||
|         Object.defineProperty(json, this.key, { | ||||
|             value: converted, | ||||
|             enumerable: false, | ||||
|             enumerable: false | ||||
|         }) | ||||
|         return converted | ||||
|     } | ||||
|  | @ -260,8 +270,8 @@ export class Fuse<T> extends DesugaringStep<T> { | |||
|     constructor(doc: string, ...steps: DesugaringStep<T>[]) { | ||||
|         super( | ||||
|             (doc ?? "") + | ||||
|                 "This fused pipeline of the following steps: " + | ||||
|                 steps.map((s) => s.name).join(", "), | ||||
|             "This fused pipeline of the following steps: " + | ||||
|             steps.map((s) => s.name).join(", "), | ||||
|             Utils.Dedup([].concat(...steps.map((step) => step.modifiedAttributes))), | ||||
|             "Fuse(" + steps.map((s) => s.name).join(", ") + ")" | ||||
|         ) | ||||
|  |  | |||
|  | @ -124,9 +124,9 @@ export class ConversionContext { | |||
|         this.messages.push({ context: this, level: "warning", message }) | ||||
|     } | ||||
| 
 | ||||
|     err(message: string) { | ||||
|     err(...message: string[]) { | ||||
|         this._hasErrors = true | ||||
|         this.messages.push({ context: this, level: "error", message }) | ||||
|         this.messages.push({ context: this, level: "error", message: message.join(" ") }) | ||||
|     } | ||||
| 
 | ||||
|     info(message: string) { | ||||
|  |  | |||
|  | @ -83,7 +83,6 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> { | |||
|                     context.err("Got undefined as filter expansion in "+tagRendering["id"]) | ||||
|                     continue | ||||
|                 } | ||||
|                 console.log("Adding filter",filterName," due to", tagRendering["id"]) | ||||
|                 filters.push(filterName) | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -71,6 +71,10 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs | |||
| 
 | ||||
|         for (const name of names) { | ||||
|             const found = Utils.Clone(state.sharedLayers.get(name)) | ||||
|             if(found === undefined){ | ||||
|                 context.err("Layer with name "+name+" not found") | ||||
|                 continue | ||||
|             } | ||||
|             found["_basedOn"] = name | ||||
|             if (found === undefined) { | ||||
|                 reportNotFound(name) | ||||
|  | @ -367,7 +371,8 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|     private static CalculateDependencies( | ||||
|         alreadyLoaded: LayerConfigJson[], | ||||
|         allKnownLayers: Map<string, LayerConfigJson>, | ||||
|         themeId: string | ||||
|         themeId: string, | ||||
|         context: ConversionContext | ||||
|     ): { config: LayerConfigJson; reason: string }[] { | ||||
|         const dependenciesToAdd: { config: LayerConfigJson; reason: string }[] = [] | ||||
|         const loadedLayerIds: Set<string> = new Set<string>(alreadyLoaded.map((l) => l?.id)) | ||||
|  | @ -388,6 +393,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|             }[] = [] | ||||
| 
 | ||||
|             for (const layerConfig of alreadyLoaded) { | ||||
| 
 | ||||
|                 try { | ||||
|                     const layerDeps = DependencyCalculator.getLayerDependencies( | ||||
|                         new LayerConfig(layerConfig, themeId + "(dependencies)") | ||||
|  | @ -396,7 +402,7 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|                 } catch (e) { | ||||
|                     console.error(e) | ||||
|                     throw ( | ||||
|                         "Detecting layer dependencies for " + layerConfig.id + " failed due to " + e | ||||
|                         "Detecting layer dependencies for " + layerConfig?.id + " failed due to " + e | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|  | @ -467,7 +473,8 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { | |||
|         const dependencies = AddDependencyLayersToTheme.CalculateDependencies( | ||||
|             layers, | ||||
|             allKnownLayers, | ||||
|             theme.id | ||||
|             theme.id, | ||||
|             context | ||||
|         ) | ||||
|         if (dependencies.length > 0) { | ||||
|             for (const dependency of dependencies) { | ||||
|  |  | |||
|  | @ -25,8 +25,11 @@ export default class FilterConfig { | |||
|     public readonly defaultSelection?: number | ||||
| 
 | ||||
|     constructor(json: FilterConfigJson, context: string) { | ||||
|         if(typeof json === "string"){ | ||||
|             throw "Got a non-expanded filter, just a string: "+json | ||||
|         } | ||||
|         if (json.options === undefined) { | ||||
|             throw `A filter without options was given at ${context}` | ||||
|             throw `A filter without options was given at ${context}. The ID is ${JSON.stringify(json)}` | ||||
|         } | ||||
|         if (json.id === undefined) { | ||||
|             throw `A filter without id was found at ${context}` | ||||
|  |  | |||
|  | @ -72,7 +72,7 @@ export default class LayerConfig extends WithContextLoader { | |||
|     private readonly _basedOn: string | undefined | ||||
| 
 | ||||
|     constructor(json: LayerConfigJson, context?: string, official: boolean = true) { | ||||
|         context = context + "." + json.id | ||||
|         context = context + "." + json?.id | ||||
|         const translationContext = "layers:" + json.id | ||||
|         super(json, context) | ||||
|         this.id = json.id | ||||
|  | @ -292,7 +292,9 @@ export default class LayerConfig extends WithContextLoader { | |||
|             this.filterIsSameAs = json.filter["sameAs"] | ||||
|             this.filters = [] | ||||
|         } else { | ||||
|             this.filters = (<FilterConfigJson[]>json.filter ?? []).map((option, i) => { | ||||
|             this.filters = (<FilterConfigJson[]>json.filter ?? []) | ||||
|                 .filter(f => typeof f !== "string") | ||||
|                 .map((option, i) => { | ||||
|                 return new FilterConfig(option, `layers:${this.id}.filter.${i}`) | ||||
|             }) | ||||
|         } | ||||
|  |  | |||
|  | @ -23,16 +23,16 @@ | |||
|   export let assignTo: UIEventSource<string> = Locale.language | ||||
|   export let preferredLanguages: Store<string[]> = undefined | ||||
|   let preferredFiltered: string[] = undefined | ||||
| 
 | ||||
|   preferredLanguages?.addCallbackAndRunD((preferredLanguages) => { | ||||
|     let lng = navigator.language | ||||
|     if (lng === "en-US") { | ||||
|       lng = "en" | ||||
|     } | ||||
|     const lng = Locale.getBestSupportedLanguage() | ||||
|     if (preferredLanguages?.indexOf(lng) < 0) { | ||||
|       preferredLanguages?.push(lng) | ||||
|     } | ||||
|     preferredFiltered = preferredLanguages?.filter((l) => availableLanguages.indexOf(l) >= 0) | ||||
|   }) | ||||
| 
 | ||||
| 
 | ||||
|   export let clss: string = undefined | ||||
|   let current = Locale.language | ||||
| </script> | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import { UIEventSource } from "../../Logic/UIEventSource" | |||
| import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource" | ||||
| import { Utils } from "../../Utils" | ||||
| import { QueryParameters } from "../../Logic/Web/QueryParameters" | ||||
| import native from "../../assets/language_native.json" | ||||
| 
 | ||||
| export default class Locale { | ||||
|     public static showLinkToWeblate: UIEventSource<boolean> = new UIEventSource<boolean>(false) | ||||
|  | @ -11,6 +12,23 @@ export default class Locale { | |||
|     public static showLinkOnMobile: UIEventSource<boolean> = new UIEventSource<boolean>(false) | ||||
|     public static language: UIEventSource<string> = Locale.setup() | ||||
| 
 | ||||
|     public static getBestSupportedLanguage(browserLanguage?: string){ | ||||
|         browserLanguage ??= navigator.languages?.[0] ?? navigator.language ?? "en" | ||||
|         console.log("Browser language is", browserLanguage) | ||||
|         const availableLanguages = Object.keys(native) | ||||
|         const hasBrowserLang = availableLanguages.indexOf(browserLanguage) >= 0 | ||||
|         if (hasBrowserLang) { | ||||
|             return browserLanguage | ||||
|         } | ||||
|         browserLanguage = browserLanguage.replace(/[-_].*/g, "") | ||||
|         const hasBrowserLangFallback = availableLanguages.indexOf(browserLanguage) >= 0 | ||||
|         if(hasBrowserLangFallback){ | ||||
|            return browserLanguage | ||||
|         } | ||||
|         console.log("Language",browserLanguage,"not supported, defaulting to english") | ||||
|         return "en" | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Creates the UIEventSource containing the identifier of the current language | ||||
|      * | ||||
|  | @ -54,11 +72,7 @@ export default class Locale { | |||
|         } else { | ||||
|             let browserLanguage = "en" | ||||
|             if (typeof navigator !== "undefined") { | ||||
|                 browserLanguage = navigator.languages?.[0] ?? navigator.language ?? "en" | ||||
|                 console.log("Browser language is", browserLanguage) | ||||
|                 if (browserLanguage === "en-US") { | ||||
|                     browserLanguage = "en" | ||||
|                 } | ||||
|                browserLanguage = Locale.getBestSupportedLanguage() | ||||
|             } | ||||
|             source = LocalStorageSource.Get("language", browserLanguage) | ||||
|         } | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ | |||
|   "gl": "lingua galega", | ||||
|   "he": "עברית", | ||||
|   "hu": "magyar", | ||||
|   "id": "Indonesia", | ||||
|   "id": "bahasa Indonesia", | ||||
|   "it": "italiano", | ||||
|   "ja": "日本語", | ||||
|   "nb_NO": "bokmål", | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue