| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  | import {UIElement} from "./UIElement"; | 
					
						
							|  |  |  | import {UIEventSource} from "../Logic/UIEventSource"; | 
					
						
							|  |  |  | import {Translation} from "./i18n/Translation"; | 
					
						
							|  |  |  | import Locale from "./i18n/Locale"; | 
					
						
							|  |  |  | import Combine from "./Base/Combine"; | 
					
						
							|  |  |  | import State from "../State"; | 
					
						
							|  |  |  | import {FixedUiElement} from "./Base/FixedUiElement"; | 
					
						
							|  |  |  | import SpecialVisualizations from "./SpecialVisualizations"; | 
					
						
							| 
									
										
										
										
											2021-03-12 13:48:49 +01:00
										 |  |  | import {Utils} from "../Utils"; | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | export class SubstitutedTranslation extends UIElement { | 
					
						
							| 
									
										
										
										
											2021-04-06 18:17:07 +02:00
										 |  |  |     private static cachedTranslations: | 
					
						
							| 
									
										
										
										
											2021-03-12 13:48:49 +01:00
										 |  |  |         Map<string, Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>>> = new Map<string, Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>>>(); | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |     private readonly tags: UIEventSource<any>; | 
					
						
							|  |  |  |     private readonly translation: Translation; | 
					
						
							|  |  |  |     private content: UIElement[]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private constructor( | 
					
						
							|  |  |  |         translation: Translation, | 
					
						
							|  |  |  |         tags: UIEventSource<any>) { | 
					
						
							|  |  |  |         super(tags); | 
					
						
							|  |  |  |         this.translation = translation; | 
					
						
							|  |  |  |         this.tags = tags; | 
					
						
							|  |  |  |         const self = this; | 
					
						
							|  |  |  |         tags.addCallbackAndRun(() => { | 
					
						
							|  |  |  |             self.content = self.CreateContent(); | 
					
						
							|  |  |  |             self.Update(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Locale.language.addCallback(() => { | 
					
						
							|  |  |  |             self.content = self.CreateContent(); | 
					
						
							|  |  |  |             self.Update(); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2021-02-06 00:05:38 +01:00
										 |  |  |         this.SetClass("w-full") | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public static construct( | 
					
						
							|  |  |  |         translation: Translation, | 
					
						
							|  |  |  |         tags: UIEventSource<any>): SubstitutedTranslation { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-06 18:17:07 +02:00
										 |  |  |         /* let cachedTranslations = Utils.getOrSetDefault(SubstitutedTranslation.cachedTranslations, SubstitutedTranslation.GenerateSubCache); | 
					
						
							|  |  |  |          const innerMap = Utils.getOrSetDefault(cachedTranslations, translation, SubstitutedTranslation.GenerateMap); | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |          const cachedTranslation = innerMap.get(tags); | 
					
						
							|  |  |  |          if (cachedTranslation !== undefined) { | 
					
						
							|  |  |  |              return cachedTranslation; | 
					
						
							|  |  |  |          }*/ | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |         const st = new SubstitutedTranslation(translation, tags); | 
					
						
							| 
									
										
										
										
											2021-04-06 18:17:07 +02:00
										 |  |  |         // innerMap.set(tags, st);
 | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |         return st; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     public static SubstituteKeys(txt: string, tags: any) { | 
					
						
							|  |  |  |         for (const key in tags) { | 
					
						
							| 
									
										
										
										
											2021-04-06 18:17:07 +02:00
										 |  |  |             txt = txt.replace(new RegExp("{" + key + "}", "g"), tags[key]) | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-06 21:10:18 +02:00
										 |  |  |         return txt; | 
					
						
							| 
									
										
										
										
											2021-04-06 18:17:07 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static GenerateMap() { | 
					
						
							|  |  |  |         return new Map<UIEventSource<any>, SubstitutedTranslation>() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static GenerateSubCache() { | 
					
						
							|  |  |  |         return new Map<Translation, Map<UIEventSource<any>, SubstitutedTranslation>>(); | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     InnerRender(): string { | 
					
						
							| 
									
										
										
										
											2021-04-06 18:17:07 +02:00
										 |  |  |         if (this.content.length == 1) { | 
					
						
							| 
									
										
										
										
											2021-02-05 19:11:19 +01:00
										 |  |  |             return this.content[0].Render(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |         return new Combine(this.content).Render(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private CreateContent(): UIElement[] { | 
					
						
							|  |  |  |         let txt = this.translation?.txt; | 
					
						
							|  |  |  |         if (txt === undefined) { | 
					
						
							|  |  |  |             return [] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const tags = this.tags.data; | 
					
						
							|  |  |  |         txt = SubstitutedTranslation.SubstituteKeys(txt, tags); | 
					
						
							|  |  |  |         return this.EvaluateSpecialComponents(txt); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private EvaluateSpecialComponents(template: string): UIElement[] { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (const knownSpecial of SpecialVisualizations.specialVisualizations) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Note: the '.*?' in the regex reads as 'any character, but in a non-greedy way'
 | 
					
						
							|  |  |  |             const matched = template.match(`(.*){${knownSpecial.funcName}\\((.*?)\\)}(.*)`); | 
					
						
							|  |  |  |             if (matched != null) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // We found a special component that should be brought to live
 | 
					
						
							|  |  |  |                 const partBefore = this.EvaluateSpecialComponents(matched[1]); | 
					
						
							|  |  |  |                 const argument = matched[2].trim(); | 
					
						
							|  |  |  |                 const partAfter = this.EvaluateSpecialComponents(matched[3]); | 
					
						
							|  |  |  |                 try { | 
					
						
							|  |  |  |                     const args = knownSpecial.args.map(arg => arg.defaultValue ?? ""); | 
					
						
							|  |  |  |                     if (argument.length > 0) { | 
					
						
							|  |  |  |                         const realArgs = argument.split(",").map(str => str.trim()); | 
					
						
							|  |  |  |                         for (let i = 0; i < realArgs.length; i++) { | 
					
						
							|  |  |  |                             if (args.length <= i) { | 
					
						
							|  |  |  |                                 args.push(realArgs[i]); | 
					
						
							|  |  |  |                             } else { | 
					
						
							|  |  |  |                                 args[i] = realArgs[i]; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     const element = knownSpecial.constr(State.state, this.tags, args); | 
					
						
							|  |  |  |                     return [...partBefore, element, ...partAfter] | 
					
						
							|  |  |  |                 } catch (e) { | 
					
						
							|  |  |  |                     console.error(e); | 
					
						
							|  |  |  |                     return [...partBefore, new FixedUiElement(`Failed loading ${knownSpecial.funcName}(${matched[2]}): ${e}`), ...partAfter] | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-06 21:10:18 +02:00
										 |  |  |         // IF we end up here, no changes have to be made - except to remove any resting {}
 | 
					
						
							|  |  |  |         return [new FixedUiElement(template.replace(/{.*}/g, ""))]; | 
					
						
							| 
									
										
										
										
											2021-02-05 16:32:37 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |