forked from MapComplete/MapComplete
		
	Full, interactive i18n (still some quests to enable it though)
This commit is contained in:
		
							parent
							
								
									fd6f77c98e
								
							
						
					
					
						commit
						0f2dff8f41
					
				
					 15 changed files with 205 additions and 90 deletions
				
			
		|  | @ -50,7 +50,7 @@ export class LayerDefinition { | ||||||
|     /** |     /** | ||||||
|      * This UIElement is rendered as title element in the popup |      * This UIElement is rendered as title element in the popup | ||||||
|      */ |      */ | ||||||
|     title: TagRenderingOptions | UIElement; |     title: TagRenderingOptions; | ||||||
|     /** |     /** | ||||||
|      * These are the questions/shown attributes in the popup |      * These are the questions/shown attributes in the popup | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|  | @ -1,13 +1,18 @@ | ||||||
| import {LayerDefinition} from "./LayerDefinition"; | import {LayerDefinition} from "./LayerDefinition"; | ||||||
| import { UIElement } from "../UI/UIElement"; | import {UIElement} from "../UI/UIElement"; | ||||||
| import {FixedUiElement} from "../UI/Base/FixedUiElement"; | import {FixedUiElement} from "../UI/Base/FixedUiElement"; | ||||||
| import Translation from "../UI/i18n/Translation"; | import Translation from "../UI/i18n/Translation"; | ||||||
| import Translations from "../UI/i18n/Translations"; | import Translations from "../UI/i18n/Translations"; | ||||||
|  | import Locale from "../UI/i18n/Locale"; | ||||||
|  | import {VariableUiElement} from "../UI/Base/VariableUIElement"; | ||||||
|  | import {OsmConnection, UserDetails} from "../Logic/OsmConnection"; | ||||||
|  | import {UIEventSource} from "../UI/UIEventSource"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * A layout is a collection of settings of the global view (thus: welcome text, title, selection of layers). |  * A layout is a collection of settings of the global view (thus: welcome text, title, selection of layers). | ||||||
|  */ |  */ | ||||||
| export class Layout { | export class Layout { | ||||||
|  | 
 | ||||||
|     public name: string; |     public name: string; | ||||||
|     public title: UIElement; |     public title: UIElement; | ||||||
|     public layers: LayerDefinition[]; |     public layers: LayerDefinition[]; | ||||||
|  | @ -45,8 +50,8 @@ export class Layout { | ||||||
|         startLat: number, |         startLat: number, | ||||||
|         startLon: number, |         startLon: number, | ||||||
|         welcomeMessage: UIElement | string, |         welcomeMessage: UIElement | string, | ||||||
|         gettingStartedPlzLogin: UIElement | string = "Please login to get started", |         gettingStartedPlzLogin: UIElement | string = Translations.t.general.getStarted, | ||||||
|         welcomeBackMessage: UIElement | string = "You are logged in. Welcome back!", |         welcomeBackMessage: UIElement | string = Translations.t.general.welcomeBack, | ||||||
|         welcomeTail: UIElement | string = "" |         welcomeTail: UIElement | string = "" | ||||||
|     ) { |     ) { | ||||||
|         this.supportedLanguages = supportedLanguages; |         this.supportedLanguages = supportedLanguages; | ||||||
|  | @ -56,11 +61,62 @@ export class Layout { | ||||||
|         this.startzoom = startzoom; |         this.startzoom = startzoom; | ||||||
|         this.name = name; |         this.name = name; | ||||||
|         this.layers = layers; |         this.layers = layers; | ||||||
|         this.welcomeMessage =Translations.W(welcomeMessage) |         this.welcomeMessage = Translations.W(welcomeMessage) | ||||||
|         this.gettingStartedPlzLogin = Translations.W(gettingStartedPlzLogin); |         this.gettingStartedPlzLogin = Translations.W(gettingStartedPlzLogin); | ||||||
|         this.welcomeBackMessage = Translations.W(welcomeBackMessage); |         this.welcomeBackMessage = Translations.W(welcomeBackMessage); | ||||||
|         this.welcomeTail = Translations.W(welcomeTail); |         this.welcomeTail = Translations.W(welcomeTail); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class WelcomeMessage extends UIElement { | ||||||
|  |     private readonly layout: Layout; | ||||||
|  |     private readonly userDetails: UIEventSource<UserDetails>; | ||||||
|  |     private osmConnection: OsmConnection; | ||||||
|  | 
 | ||||||
|  |     private readonly description: UIElement; | ||||||
|  |     private readonly plzLogIn: UIElement; | ||||||
|  |     private readonly welcomeBack: UIElement; | ||||||
|  |     private readonly tail: UIElement; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     constructor(layout: Layout, osmConnection: OsmConnection) { | ||||||
|  |         super(osmConnection.userDetails); | ||||||
|  |         this.ListenTo(Locale.language); | ||||||
|  |         this.osmConnection = osmConnection; | ||||||
|  |         this.layout = layout; | ||||||
|  |         this.userDetails = osmConnection.userDetails; | ||||||
|  | 
 | ||||||
|  |         this.description = layout.welcomeMessage; | ||||||
|  |         console.log("   >>>>",this.description, "DESCR ") | ||||||
|  |         this.plzLogIn = layout.gettingStartedPlzLogin; | ||||||
|  |         this.welcomeBack = layout.welcomeBackMessage; | ||||||
|  |         this.tail = layout.welcomeTail; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     InnerRender(): string { | ||||||
|  |         return "<div id='welcomeMessage'>" + | ||||||
|  |             this.description.Render() + | ||||||
|  |             "<br/>"+ | ||||||
|  |             (this.userDetails.data.loggedIn ? this.welcomeBack : this.plzLogIn).Render() + | ||||||
|  |             "<br/>"+ | ||||||
|  |             this.tail.Render() + | ||||||
|  |             "</div>" | ||||||
|  | 
 | ||||||
|  |             ; | ||||||
|  |         /* | ||||||
|  |         return new VariableUiElement( | ||||||
|  |             this.userDetails.map((userdetails) => { | ||||||
|  |             }), | ||||||
|  |             function () { | ||||||
|  |                 | ||||||
|  |             }).ListenTo(Locale.language);*/ | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected InnerUpdate(htmlElement: HTMLElement) { | ||||||
|  |         this.osmConnection.registerActivateOsmAUthenticationClass() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,13 +19,14 @@ export default class Cyclofix extends Layout { | ||||||
|             16, |             16, | ||||||
|             50.8465573, |             50.8465573, | ||||||
|             4.3516970, |             4.3516970, | ||||||
|  |                /* Translations.t.cyclofix.title/*/ | ||||||
|             new Combine([ |             new Combine([ | ||||||
|                 "<h3>", |                 "<h3>", | ||||||
|                 Translations.t.cyclofix.title, |                 Translations.t.cyclofix.title, | ||||||
|                 "</h3><br/><p>", |                 "</h3><br/><p>", | ||||||
|                 Translations.t.cyclofix.description, |                 Translations.t.cyclofix.description, | ||||||
|                 "</p>" |                 "</p>" | ||||||
|             ]), |             ])//*/
 | ||||||
|             "", ""); |         ); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,38 +1,61 @@ | ||||||
| import {TagRenderingOptions} from "../../TagRendering"; | import {TagRenderingOptions} from "../../TagRendering"; | ||||||
| import {Tag} from "../../../Logic/TagsFilter"; | import {Tag} from "../../../Logic/TagsFilter"; | ||||||
| import Translations from "../../../UI/i18n/Translations"; | import Translations from "../../../UI/i18n/Translations"; | ||||||
|  | import Combine from "../../../UI/Base/Combine"; | ||||||
| 
 | 
 | ||||||
|  | class ParkingTypeHelper { | ||||||
|  |     static GenerateMappings() { | ||||||
|  |         const images = { | ||||||
|  |             stands: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bike_racks_at_north-west_of_Westfield_-_geograph.org.uk_-_1041057.jpg/100px-Bike_racks_at_north-west_of_Westfield_-_geograph.org.uk_-_1041057.jpg", | ||||||
|  |             wall_loops: "https://wiki.openstreetmap.org/w/images/thumb/c/c2/Bike-parking-wheelbender.jpg/100px-Bike-parking-wheelbender.jpg", | ||||||
|  |             handlebar_holder: "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Bicycle_parking_handlebar_holder.jpg/100px-Bicycle_parking_handlebar_holder.jpg", | ||||||
|  |             shed: "https://wiki.openstreetmap.org/w/images/thumb/b/b2/Bike-shelter.jpg/100px-Bike-shelter.jpg", | ||||||
|  |             rack: "https://wiki.openstreetmap.org/w/images/thumb/4/41/Triton_Bike_Rack.png/100px-Triton_Bike_Rack.png", | ||||||
|  |             "two-tier": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Bicis_a_l%27estaci%C3%B3_de_Leiden.JPG/100px-Bicis_a_l%27estaci%C3%B3_de_Leiden.JPG" | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         const toImg = (url) => `<img src=${url}>` | ||||||
|  |         const mappings = []; | ||||||
|  |         const to = Translations.t.cyclofix.parking.type | ||||||
|  | 
 | ||||||
|  |         for (const imagesKey in images) { | ||||||
|  |             const mapping = | ||||||
|  |                 { | ||||||
|  |                     k: new Tag("bicycle_parking", imagesKey), | ||||||
|  |                     txt: new Combine([ | ||||||
|  |                         to[imagesKey], | ||||||
|  |                         to.eg, | ||||||
|  |                         toImg(images[imagesKey]) | ||||||
|  |                     ]) | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |             mappings.push(mapping); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return mappings; | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| export default class ParkingType extends TagRenderingOptions { | export default class ParkingType extends TagRenderingOptions { | ||||||
|     constructor() { |     constructor() { | ||||||
|         const images = { | 
 | ||||||
|             stands: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Bike_racks_at_north-west_of_Westfield_-_geograph.org.uk_-_1041057.jpg/100px-Bike_racks_at_north-west_of_Westfield_-_geograph.org.uk_-_1041057.jpg", |  | ||||||
|             loops: "https://wiki.openstreetmap.org/w/images/thumb/c/c2/Bike-parking-wheelbender.jpg/100px-Bike-parking-wheelbender.jpg", |  | ||||||
|             handlebar: "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Bicycle_parking_handlebar_holder.jpg/100px-Bicycle_parking_handlebar_holder.jpg", |  | ||||||
|             shed: "https://wiki.openstreetmap.org/w/images/thumb/b/b2/Bike-shelter.jpg/100px-Bike-shelter.jpg", |  | ||||||
|             rack: "https://wiki.openstreetmap.org/w/images/thumb/4/41/Triton_Bike_Rack.png/100px-Triton_Bike_Rack.png", |  | ||||||
|             double: "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Bicis_a_l%27estaci%C3%B3_de_Leiden.JPG/100px-Bicis_a_l%27estaci%C3%B3_de_Leiden.JPG" |  | ||||||
|         } |  | ||||||
|         const toImg = (url) => `<img src=${url}>` |  | ||||||
|         const to = Translations.t.cyclofix.parking.type |         const to = Translations.t.cyclofix.parking.type | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|         super({ |         super({ | ||||||
|             priority: 5, |             priority: 5, | ||||||
|             question: to.question.Render(), |             question: to.question, | ||||||
|             freeform: { |             freeform: { | ||||||
|                 key: "bicycle_parking", |                 key: "bicycle_parking", | ||||||
|                 extraTags: new Tag("fixme", "Freeform bicycle_parking= tag used: possibly a wrong value"), |                 extraTags: new Tag("fixme", "Freeform bicycle_parking= tag used: possibly a wrong value"), | ||||||
|                 template: to.template.txt, |                 template: to.template.txt, | ||||||
|                 renderTemplate: to.render.txt, |                 renderTemplate: to.render.txt, | ||||||
|                 placeholder: Translations.t.cyclofix.freeFormPlaceholder.txt, |                 placeholder: Translations.t.cyclofix.freeFormPlaceholder, | ||||||
|             }, |             }, | ||||||
|             mappings: [ |             mappings: ParkingTypeHelper.GenerateMappings() | ||||||
|                 {k: new Tag("bicycle_parking", "stands"), txt: `${to.stands.Render()}, bijvoorbeeld: ${toImg(images.stands)}`}, | 
 | ||||||
|                 {k: new Tag("bicycle_parking", "wall_loops"), txt: `${to.loops.Render()}, bijvoorbeeld: ${toImg(images.loops)}`}, |  | ||||||
|                 {k: new Tag("bicycle_parking", "handlebar_holder"), txt: `${to.handlebar.Render()}, bijvoorbeeld: ${toImg(images.handlebar)}`}, |  | ||||||
|                 {k: new Tag("bicycle_parking", "shed"), txt: `${to.shed.Render()}, bijvoorbeeld: ${toImg(images.shed)}`}, |  | ||||||
|                 {k: new Tag("bicycle_parking", "rack"), txt: `${to.rack.Render()}, bijvoorbeeld: ${toImg(images.rack)}`}, |  | ||||||
|                 {k: new Tag("bicycle_parking", "two-tier"), txt: `${to.double.Render()}, bijvoorbeeld: ${toImg(images.double)}`} |  | ||||||
|             ] |  | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -7,11 +7,11 @@ export default class PumpManometer extends TagRenderingOptions { | ||||||
|     constructor() { |     constructor() { | ||||||
|         const to = Translations.t.cyclofix.station.manometer |         const to = Translations.t.cyclofix.station.manometer | ||||||
|         super({ |         super({ | ||||||
|             question: to.question.Render(), |             question: to.question, | ||||||
|             mappings: [ |             mappings: [ | ||||||
|                 {k: new Tag("manometer", "yes"), txt: to.yes.Render()}, |                 {k: new Tag("manometer", "yes"), txt: to.yes}, | ||||||
|                 {k: new Tag("manometer", "no"), txt: to.no.Render()}, |                 {k: new Tag("manometer", "no"), txt: to.no}, | ||||||
|                 {k: new Tag("manometer", "broken"), txt: to.broken.Render()} |                 {k: new Tag("manometer", "broken"), txt: to.broken} | ||||||
|             ] |             ] | ||||||
|         });    |         });    | ||||||
|     }    |     }    | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ import {InputElementWrapper} from "../UI/Input/InputElementWrapper"; | ||||||
| import {FixedInputElement} from "../UI/Input/FixedInputElement"; | import {FixedInputElement} from "../UI/Input/FixedInputElement"; | ||||||
| import {RadioButton} from "../UI/Input/RadioButton"; | import {RadioButton} from "../UI/Input/RadioButton"; | ||||||
| import Translations from "../UI/i18n/Translations"; | import Translations from "../UI/i18n/Translations"; | ||||||
|  | import Locale from "../UI/i18n/Locale"; | ||||||
| 
 | 
 | ||||||
| export class TagRenderingOptions implements TagDependantUIElementConstructor { | export class TagRenderingOptions implements TagDependantUIElementConstructor { | ||||||
| 
 | 
 | ||||||
|  | @ -29,7 +30,7 @@ export class TagRenderingOptions implements TagDependantUIElementConstructor { | ||||||
|             tagsPreprocessor?: (tags: any) => any; |             tagsPreprocessor?: (tags: any) => any; | ||||||
|             template: string; |             template: string; | ||||||
|             renderTemplate: string; |             renderTemplate: string; | ||||||
|             placeholder?: string; |             placeholder?: string | UIElement; | ||||||
|             extraTags?: TagsFilter |             extraTags?: TagsFilter | ||||||
|         }; |         }; | ||||||
|         mappings?: { k: TagsFilter; txt: string | UIElement; priority?: number, substitute?: boolean }[] |         mappings?: { k: TagsFilter; txt: string | UIElement; priority?: number, substitute?: boolean }[] | ||||||
|  | @ -78,7 +79,7 @@ export class TagRenderingOptions implements TagDependantUIElementConstructor { | ||||||
|         freeform?: { |         freeform?: { | ||||||
|             key: string, template: string, |             key: string, template: string, | ||||||
|             renderTemplate: string |             renderTemplate: string | ||||||
|             placeholder?: string, |             placeholder?: string | UIElement, | ||||||
|             extraTags?: TagsFilter, |             extraTags?: TagsFilter, | ||||||
|         }, |         }, | ||||||
|          |          | ||||||
|  | @ -148,7 +149,7 @@ class TagRendering extends UIElement implements TagDependantUIElement { | ||||||
|         key: string, template: string, |         key: string, template: string, | ||||||
|         renderTemplate: string, |         renderTemplate: string, | ||||||
| 
 | 
 | ||||||
|         placeholder?: string, |         placeholder?: string | UIElement, | ||||||
|         extraTags?: TagsFilter |         extraTags?: TagsFilter | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -172,13 +173,14 @@ class TagRendering extends UIElement implements TagDependantUIElement { | ||||||
|         freeform?: { |         freeform?: { | ||||||
|             key: string, template: string, |             key: string, template: string, | ||||||
|             renderTemplate: string |             renderTemplate: string | ||||||
|             placeholder?: string, |             placeholder?: string | UIElement, | ||||||
|             extraTags?: TagsFilter, |             extraTags?: TagsFilter, | ||||||
|         }, |         }, | ||||||
|         tagsPreprocessor?: ((tags: any) => any), |         tagsPreprocessor?: ((tags: any) => any), | ||||||
|         mappings?: { k: TagsFilter, txt: string | UIElement, priority?: number, substitute?: boolean }[] |         mappings?: { k: TagsFilter, txt: string | UIElement, priority?: number, substitute?: boolean }[] | ||||||
|     }) { |     }) { | ||||||
|         super(tags); |         super(tags); | ||||||
|  |         this.ListenTo(Locale.language); | ||||||
|         const self = this; |         const self = this; | ||||||
|         this.ListenTo(this._questionSkipped); |         this.ListenTo(this._questionSkipped); | ||||||
|         this.ListenTo(this._editMode); |         this.ListenTo(this._editMode); | ||||||
|  | @ -264,13 +266,13 @@ class TagRendering extends UIElement implements TagDependantUIElement { | ||||||
| 
 | 
 | ||||||
|         const cancelContents = this._editMode.map((isEditing) => { |         const cancelContents = this._editMode.map((isEditing) => { | ||||||
|             if (isEditing) { |             if (isEditing) { | ||||||
|                 return "<span class='skip-button'>Cancel</span>"; |                 return "<span class='skip-button'>"+Translations.t.general.cancel.R()+"</span>"; | ||||||
|             } else { |             } else { | ||||||
|                 return "<span class='skip-button'>Skip this question</span>"; |                 return "<span class='skip-button'>"+Translations.t.general.skip.R()+"</span>"; | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         // And at last, set up the skip button
 |         // And at last, set up the skip button
 | ||||||
|         this._skipButton = new VariableUiElement(cancelContents).onClick(cancel); |         this._skipButton = new VariableUiElement(cancelContents).onClick(cancel)    ; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -278,7 +280,7 @@ class TagRendering extends UIElement implements TagDependantUIElement { | ||||||
|         freeform?: { |         freeform?: { | ||||||
|             key: string, template: string, |             key: string, template: string, | ||||||
|             renderTemplate: string |             renderTemplate: string | ||||||
|             placeholder?: string, |             placeholder?: string | UIElement, | ||||||
|             extraTags?: TagsFilter, |             extraTags?: TagsFilter, | ||||||
|         }, |         }, | ||||||
|         mappings?: { k: TagsFilter, txt: string | UIElement, priority?: number, substitute?: boolean }[] |         mappings?: { k: TagsFilter, txt: string | UIElement, priority?: number, substitute?: boolean }[] | ||||||
|  |  | ||||||
|  | @ -2,18 +2,30 @@ import {UIElement} from "../UIElement"; | ||||||
| import Translations from "../i18n/Translations"; | import Translations from "../i18n/Translations"; | ||||||
| 
 | 
 | ||||||
| export default class Combine extends UIElement { | export default class Combine extends UIElement { | ||||||
|     private uiElements: UIElement[]; |     private uiElements: (string | UIElement)[]; | ||||||
| 
 | 
 | ||||||
|     constructor(uiElements: (string | UIElement)[]) { |     constructor(uiElements: (string | UIElement)[]) { | ||||||
|         super(undefined); |         super(undefined); | ||||||
|         this.uiElements = uiElements.map(Translations.W); |         this.uiElements = uiElements; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     InnerRender(): string { |     InnerRender(): string { | ||||||
|         let elements = ""; |         let elements = ""; | ||||||
|         for (const element of this.uiElements) { |         for (const element of this.uiElements) { | ||||||
|  |             if (element instanceof UIElement) { | ||||||
|                 elements += element.Render(); |                 elements += element.Render(); | ||||||
|  |             } else { | ||||||
|  |                 elements += element; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         return elements; |         return elements; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     protected InnerUpdate(htmlElement: HTMLElement) { | ||||||
|  |         for (const element of this.uiElements) { | ||||||
|  |             if (element instanceof UIElement) { | ||||||
|  |                 element.Update(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,11 +1,13 @@ | ||||||
| /** |  | ||||||
|  * Keeps 'messagebox' and 'messageboxmobile' in sync, shows a 'close' button on the latter one |  | ||||||
|  */ |  | ||||||
| import {UIEventSource} from "./UIEventSource"; | import {UIEventSource} from "./UIEventSource"; | ||||||
| import {UIElement} from "./UIElement"; | import {UIElement} from "./UIElement"; | ||||||
| import {VariableUiElement} from "./Base/VariableUIElement"; | import {VariableUiElement} from "./Base/VariableUIElement"; | ||||||
|  | import Translations from "./i18n/Translations"; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Handles the full screen popup on mobile | ||||||
|  |  */ | ||||||
|  | export class FullScreenMessageBoxHandler { | ||||||
|      |      | ||||||
| export class MessageBoxHandler { |  | ||||||
|     private _uielement: UIEventSource<UIElement>; |     private _uielement: UIEventSource<UIElement>; | ||||||
| 
 | 
 | ||||||
|     constructor(uielement: UIEventSource<UIElement>, |     constructor(uielement: UIEventSource<UIElement>, | ||||||
|  | @ -22,13 +24,13 @@ export class MessageBoxHandler { | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         new VariableUiElement(new UIEventSource<string>("<h2>Return to the map</h2>")) |         Translations.t.general.returnToTheMap | ||||||
|             .onClick(() => { |             .onClick(() => { | ||||||
|                 console.log("Clicked 'return to the map'") |                 console.log("Clicked 'return to the map'") | ||||||
|                 uielement.setData(undefined); |                 uielement.setData(undefined); | ||||||
|                 onClear(); |                 onClear(); | ||||||
|             }) |             }) | ||||||
|             .AttachTo("to-the-map"); |             .AttachTo("to-the-map-h2"); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import {UIEventSource} from "./UIEventSource"; | import {UIEventSource} from "./UIEventSource"; | ||||||
| import {UIElement} from "./UIElement"; | import {UIElement} from "./UIElement"; | ||||||
|  | import Translations from "./i18n/Translations"; | ||||||
| 
 | 
 | ||||||
| export class SaveButton extends UIElement { | export class SaveButton extends UIElement { | ||||||
|     private _value: UIEventSource<any>; |     private _value: UIEventSource<any>; | ||||||
|  | @ -17,9 +18,9 @@ export class SaveButton extends UIElement { | ||||||
|             this._value.data === null |             this._value.data === null | ||||||
|             || this._value.data === "" |             || this._value.data === "" | ||||||
|         ) { |         ) { | ||||||
|             return "<span class='save-non-active'>Opslaan</span>" |             return "<span class='save-non-active'>"+Translations.t.general.save.Render()+"</span>" | ||||||
|         } |         } | ||||||
|         return "<span class='save'>Save</span>"; |         return "<span class='save'>"+Translations.t.general.save.Render()+"</span>"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | @ -13,10 +13,6 @@ export abstract class UIElement { | ||||||
|         this.id = "ui-element-" + UIElement.nextId; |         this.id = "ui-element-" + UIElement.nextId; | ||||||
|         this._source = source; |         this._source = source; | ||||||
|         UIElement.nextId++; |         UIElement.nextId++; | ||||||
|         if (UIElement.nextId % 100 == 0) { |  | ||||||
| 
 |  | ||||||
|             console.log(UIElement.nextId) |  | ||||||
|         } |  | ||||||
|         this.ListenTo(source); |         this.ListenTo(source); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -97,8 +93,7 @@ export abstract class UIElement { | ||||||
|     AttachTo(divId: string) { |     AttachTo(divId: string) { | ||||||
|         let element = document.getElementById(divId); |         let element = document.getElementById(divId); | ||||||
|         if (element === null) { |         if (element === null) { | ||||||
|             console.log("SEVERE: could not attach UIElement to ", divId); |             throw "SEVERE: could not attach UIElement to " + divId; | ||||||
|             return; |  | ||||||
|         } |         } | ||||||
|         element.innerHTML = this.Render(); |         element.innerHTML = this.Render(); | ||||||
|         this.Update(); |         this.Update(); | ||||||
|  |  | ||||||
|  | @ -30,6 +30,4 @@ export default class Translation extends UIElement { | ||||||
|         return new Translation(this.translations).Render(); |         return new Translation(this.translations).Render(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -36,13 +36,15 @@ export default class Translations { | ||||||
|                         nl: 'Van welk type is deze fietsenparking?', |                         nl: 'Van welk type is deze fietsenparking?', | ||||||
|                         fr: 'TODO: fr' |                         fr: 'TODO: fr' | ||||||
|                     }), |                     }), | ||||||
|  |                     eg: new T({en: ", for example", nl: ", bijvoorbeeld"}), | ||||||
|                     stands: new T({en: 'Staple racks', nl: 'Nietjes', fr: 'TODO: fr'}), |                     stands: new T({en: 'Staple racks', nl: 'Nietjes', fr: 'TODO: fr'}), | ||||||
|                     loops: new T({en: 'Wheel rack/loops', nl: 'Wielrek/lussen', fr: 'TODO: fr'}), |                     wall_loops: new T({en: 'Wheel rack/loops', nl: 'Wielrek/lussen', fr: 'TODO: fr'}), | ||||||
|                     handlebar: new T({en: 'Handlebar holder', nl: 'Stuurhouder', fr: 'TODO: fr'}), |                     handlebar_holder: new T({en: 'Handlebar holder', nl: 'Stuurhouder', fr: 'TODO: fr'}), | ||||||
|                     shed: new T({en: 'Shed', nl: 'Schuur', fr: 'TODO: fr'}), |                     shed: new T({en: 'Shed', nl: 'Schuur', fr: 'TODO: fr'}), | ||||||
|                     rack: new T({en: 'Rack', nl: 'Rek', fr: 'TODO: fr'}), |                     rack: new T({en: 'Rack', nl: 'Rek', fr: 'TODO: fr'}), | ||||||
|                     double: new T({en: 'Two-tiered', nl: 'Dubbel (twee verdiepingen)', fr: 'TODO: fr'}), |                     "two-tier": new T({en: 'Two-tiered', nl: 'Dubbel (twee verdiepingen)', fr: 'TODO: fr'}), | ||||||
|                 }, |                 }, | ||||||
|  | 
 | ||||||
|                 operator: { |                 operator: { | ||||||
|                     render: new T({ |                     render: new T({ | ||||||
|                         en: 'This bike parking is operated by {operator}', |                         en: 'This bike parking is operated by {operator}', | ||||||
|  | @ -293,9 +295,15 @@ export default class Translations { | ||||||
|             ready: new T({en: 'Done!', nl: 'Klaar!', fr: 'TODO: fr'}), |             ready: new T({en: 'Done!', nl: 'Klaar!', fr: 'TODO: fr'}), | ||||||
|         }, |         }, | ||||||
|         general: { |         general: { | ||||||
|             loginWithOpenStreetMap: new T({en: "Login with OpenStreetMap", nl: "Aanmelden met OpenStreetMap"}) |             loginWithOpenStreetMap: new T({en: "Login with OpenStreetMap", nl: "Aanmelden met OpenStreetMap"}), | ||||||
| 
 |             getStarted: new T({ | ||||||
|             , |                 en: "<span class='activate-osm-authentication'>Login with OpenStreetMap</span> or <a href='https://www.openstreetmap.org/user/new' target='_blank'>make a free account to get started</a>", | ||||||
|  |                 nl: "<span class='activate-osm-authentication'>Meld je aan met je OpenStreetMap-account</span> of <a href='https://www.openstreetmap.org/user/new' target='_blank'>maak snel en gratis een account om te beginnen/a>", | ||||||
|  |             }), | ||||||
|  |             welcomeBack: new T({ | ||||||
|  |                 en: "You are logged in, welcome back!", | ||||||
|  |                 nl: "Je bent aangemeld. Welkom terug!" | ||||||
|  |             }), | ||||||
|             search: { |             search: { | ||||||
|                 search: new Translation({ |                 search: new Translation({ | ||||||
|                     en: "Search a location", |                     en: "Search a location", | ||||||
|  | @ -314,7 +322,23 @@ export default class Translations { | ||||||
|                     nl: "Niet gelukt..." |                     nl: "Niet gelukt..." | ||||||
|                 }) |                 }) | ||||||
| 
 | 
 | ||||||
|             } |             }, | ||||||
|  |             returnToTheMap: new T({ | ||||||
|  |                 en: "Return to the map", | ||||||
|  |                 nl: "Naar de kaart" | ||||||
|  |             }), | ||||||
|  |             save: new T({ | ||||||
|  |                 en: "Save", | ||||||
|  |                 nl: "Opslaan" | ||||||
|  |             }), | ||||||
|  |             cancel: new T({ | ||||||
|  |                 en: "Cancel", | ||||||
|  |                 nl: "Annuleren" | ||||||
|  |             }), | ||||||
|  |             skip: new T({ | ||||||
|  |                 en: "Skip this question", | ||||||
|  |                 nl: "Vraag overslaan" | ||||||
|  |             }) | ||||||
|         }    |         }    | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,9 +17,14 @@ | ||||||
| <body> | <body> | ||||||
| <div id="messagesboxmobilewrapper"> | <div id="messagesboxmobilewrapper"> | ||||||
|     <div id="messagesboxmobile-scroll"> |     <div id="messagesboxmobile-scroll"> | ||||||
|     <div id="messagesboxmobile">    </div> |         <div id="messagesboxmobile"></div> | ||||||
|  |     </div> | ||||||
|  |     <div id="to-the-map"> | ||||||
|  |         <h2 id="to-the-map-h2"> | ||||||
|  |             Loading... If this message persists, check if javascript is enabled and if no extension (uMatrix) is | ||||||
|  |             blocking it. | ||||||
|  |         </h2> | ||||||
|     </div> |     </div> | ||||||
|     <div id="to-the-map">Loading... If this message persists, check if javascript is enabled and if no extension (uMatrix) is blocking it.</div> |  | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <div id="topleft-tools"> | <div id="topleft-tools"> | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								index.ts
									
										
									
									
									
								
							
							
						
						
									
										38
									
								
								index.ts
									
										
									
									
									
								
							|  | @ -11,7 +11,7 @@ import {Tag, TagUtils} from "./Logic/TagsFilter"; | ||||||
| import {FilteredLayer} from "./Logic/FilteredLayer"; | import {FilteredLayer} from "./Logic/FilteredLayer"; | ||||||
| import {LayerUpdater} from "./Logic/LayerUpdater"; | import {LayerUpdater} from "./Logic/LayerUpdater"; | ||||||
| import {UIElement} from "./UI/UIElement"; | import {UIElement} from "./UI/UIElement"; | ||||||
| import {MessageBoxHandler} from "./UI/MessageBoxHandler"; | import {FullScreenMessageBoxHandler} from "./UI/FullScreenMessageBoxHandler"; | ||||||
| import {Overpass} from "./Logic/Overpass"; | import {Overpass} from "./Logic/Overpass"; | ||||||
| import {FeatureInfoBox} from "./UI/FeatureInfoBox"; | import {FeatureInfoBox} from "./UI/FeatureInfoBox"; | ||||||
| import {GeoLocationHandler} from "./Logic/GeoLocationHandler"; | import {GeoLocationHandler} from "./Logic/GeoLocationHandler"; | ||||||
|  | @ -25,7 +25,7 @@ import {All} from "./Customizations/Layouts/All"; | ||||||
| import Translations from "./UI/i18n/Translations"; | import Translations from "./UI/i18n/Translations"; | ||||||
| import Translation from "./UI/i18n/Translation"; | import Translation from "./UI/i18n/Translation"; | ||||||
| import Locale from "./UI/i18n/Locale"; | import Locale from "./UI/i18n/Locale"; | ||||||
| import {Layout} from "./Customizations/Layout"; | import {Layout, WelcomeMessage} from "./Customizations/Layout"; | ||||||
| import {DropDown} from "./UI/Input/DropDown"; | import {DropDown} from "./UI/Input/DropDown"; | ||||||
| import {FixedInputElement} from "./UI/Input/FixedInputElement"; | import {FixedInputElement} from "./UI/Input/FixedInputElement"; | ||||||
| import {FixedUiElement} from "./UI/Base/FixedUiElement"; | import {FixedUiElement} from "./UI/Base/FixedUiElement"; | ||||||
|  | @ -135,6 +135,7 @@ const osmConnection = new OsmConnection(dryRun); | ||||||
| 
 | 
 | ||||||
| Locale.language.syncWith(osmConnection.GetPreference("language")); | Locale.language.syncWith(osmConnection.GetPreference("language")); | ||||||
| 
 | 
 | ||||||
|  | // @ts-ignore
 | ||||||
| window.setLanguage = function (language: string) { | window.setLanguage = function (language: string) { | ||||||
|     Locale.language.setData(language) |     Locale.language.setData(language) | ||||||
| } | } | ||||||
|  | @ -265,29 +266,18 @@ new SearchAndGo(bm).AttachTo("searchbox"); | ||||||
| 
 | 
 | ||||||
| new CollapseButton("messagesbox") | new CollapseButton("messagesbox") | ||||||
|     .AttachTo("collapseButton"); |     .AttachTo("collapseButton"); | ||||||
| 
 | new WelcomeMessage(layoutToUse, osmConnection).AttachTo("messagesbox"); | ||||||
| var generateWelcomeMessage = () => { | fullScreenMessage.setData( | ||||||
|     return new VariableUiElement( |     new WelcomeMessage(layoutToUse, osmConnection) | ||||||
|         osmConnection.userDetails.map((userdetails) => { | ); | ||||||
|             var login = layoutToUse.gettingStartedPlzLogin.Render(); |  | ||||||
|             if (userdetails.loggedIn) { |  | ||||||
|                 login = layoutToUse.welcomeBackMessage.Render(); |  | ||||||
|             } |  | ||||||
|             return "<div id='welcomeMessage'>" + |  | ||||||
|                 layoutToUse.welcomeMessage.Render() + login + layoutToUse.welcomeTail.Render() + |  | ||||||
|                 "</div>"; |  | ||||||
|         }), |  | ||||||
|         function () { |  | ||||||
|             osmConnection.registerActivateOsmAUthenticationClass() |  | ||||||
|         }).ListenTo(Locale.language); |  | ||||||
| } |  | ||||||
| generateWelcomeMessage().AttachTo("messagesbox"); |  | ||||||
| fullScreenMessage.setData(generateWelcomeMessage()); |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| var messageBox = new MessageBoxHandler(fullScreenMessage, () => { | new FullScreenMessageBoxHandler(fullScreenMessage, () => { | ||||||
|     selectedElement.setData(undefined) |     selectedElement.setData(undefined) | ||||||
| }); | }).update(); | ||||||
|  | 
 | ||||||
|  | // fullScreenMessage.setData(generateWelcomeMessage());
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| new CenterMessageBox( | new CenterMessageBox( | ||||||
|     minZoom, |     minZoom, | ||||||
|  | @ -310,4 +300,6 @@ new GeoLocationHandler(bm).AttachTo("geolocate-button"); | ||||||
| // --------------- Send a ping to start various action --------
 | // --------------- Send a ping to start various action --------
 | ||||||
| 
 | 
 | ||||||
| locationControl.ping(); | locationControl.ping(); | ||||||
| messageBox.update(); | 
 | ||||||
|  | 
 | ||||||
|  | window.setTimeout(() => {Locale.language.setData("nl")}, 5000) | ||||||
							
								
								
									
										4
									
								
								test.ts
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								test.ts
									
										
									
									
									
								
							|  | @ -1,5 +1,7 @@ | ||||||
| import {DropDown} from "./UI/Input/DropDown"; | import {DropDown} from "./UI/Input/DropDown"; | ||||||
| import Locale from "./UI/i18n/Locale"; | import Locale from "./UI/i18n/Locale"; | ||||||
|  | import Combine from "./UI/Base/Combine"; | ||||||
|  | import Translations from "./UI/i18n/Translations"; | ||||||
| 
 | 
 | ||||||
| console.log("Hello world") | console.log("Hello world") | ||||||
| 
 | 
 | ||||||
|  | @ -7,3 +9,5 @@ let languagePicker = new DropDown("", ["en", "nl"].map(lang => { | ||||||
|         return {value: lang, shown: lang} |         return {value: lang, shown: lang} | ||||||
|     } |     } | ||||||
| ), Locale.language).AttachTo("maindiv"); | ), Locale.language).AttachTo("maindiv"); | ||||||
|  | 
 | ||||||
|  | new Combine(["abc",Translations.t.cyclofix.title, Translations.t.cyclofix.title]).AttachTo("extradiv"); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue