forked from MapComplete/MapComplete
		
	Make imageCarousel fit in with other elements (to make images optional or lower in the popup), add ghost bike popup
This commit is contained in:
		
							parent
							
								
									5970883adc
								
							
						
					
					
						commit
						54a01dfbef
					
				
					 15 changed files with 289 additions and 57 deletions
				
			
		|  | @ -2,7 +2,7 @@ import {LayerDefinition} from "../LayerDefinition"; | ||||||
| import {And, Or, Tag} from "../../Logic/TagsFilter"; | import {And, Or, Tag} from "../../Logic/TagsFilter"; | ||||||
| import {OperatorTag} from "../Questions/OperatorTag"; | import {OperatorTag} from "../Questions/OperatorTag"; | ||||||
| import * as L from "leaflet"; | import * as L from "leaflet"; | ||||||
| import FixedName from "../Questions/FixedName"; | import FixedText from "../Questions/FixedText"; | ||||||
| import { BikeParkingType } from "../Questions/BikeParkingType"; | import { BikeParkingType } from "../Questions/BikeParkingType"; | ||||||
| 
 | 
 | ||||||
| export class BikeParkings extends LayerDefinition { | export class BikeParkings extends LayerDefinition { | ||||||
|  | @ -26,7 +26,7 @@ export class BikeParkings extends LayerDefinition { | ||||||
| 
 | 
 | ||||||
|         this.minzoom = 13; |         this.minzoom = 13; | ||||||
|         this.style = this.generateStyleFunction(); |         this.style = this.generateStyleFunction(); | ||||||
|         this.title = new FixedName("fietsparking"); |         this.title = new FixedText("fietsparking"); | ||||||
|         this.elementsToShow = [ |         this.elementsToShow = [ | ||||||
|             new OperatorTag(), |             new OperatorTag(), | ||||||
|             new BikeParkingType() |             new BikeParkingType() | ||||||
|  |  | ||||||
|  | @ -3,7 +3,8 @@ import {And, Or, Tag} from "../../Logic/TagsFilter"; | ||||||
| import {OperatorTag} from "../Questions/OperatorTag"; | import {OperatorTag} from "../Questions/OperatorTag"; | ||||||
| import * as L from "leaflet"; | import * as L from "leaflet"; | ||||||
| import { PumpManual } from "../Questions/PumpManual"; | import { PumpManual } from "../Questions/PumpManual"; | ||||||
| import FixedName from "../Questions/FixedName"; | import FixedText from "../Questions/FixedText"; | ||||||
|  | import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; | ||||||
| 
 | 
 | ||||||
| export class BikePumps extends LayerDefinition { | export class BikePumps extends LayerDefinition { | ||||||
| 
 | 
 | ||||||
|  | @ -14,24 +15,25 @@ export class BikePumps extends LayerDefinition { | ||||||
| 
 | 
 | ||||||
|         this.overpassFilter = new Or([ |         this.overpassFilter = new Or([ | ||||||
|             new And([ |             new And([ | ||||||
|                 new Tag("amenity", "compressed_air"), |                 new Tag("amenity", "bicycle_repair_station"), | ||||||
|                 new Tag("bicycle", "yes"), |                 new Tag("service:bicycle:pump", "yes"), | ||||||
|             ]) |             ]) | ||||||
|             ] |             ] | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         this.newElementTags = [ |         this.newElementTags = [ | ||||||
|             new Tag("amenity", "compressed_air"), |             new Tag("amenity", "bicycle_repair_station"), | ||||||
|             new Tag("bicycle", "yes"), |             new Tag("service:bicycle:pump", "yes"), | ||||||
|             // new Tag("fixme", "Toegevoegd met MapComplete, geometry nog uit te tekenen")
 |             // new Tag("fixme", "Toegevoegd met MapComplete, geometry nog uit te tekenen")
 | ||||||
|         ]; |         ]; | ||||||
|         this.maxAllowedOverlapPercentage = 10; |         this.maxAllowedOverlapPercentage = 10; | ||||||
| 
 | 
 | ||||||
|         this.minzoom = 13; |         this.minzoom = 13; | ||||||
|         this.style = this.generateStyleFunction(); |         this.style = this.generateStyleFunction(); | ||||||
|         this.title = new FixedName("pomp"); |         this.title = new FixedText("Pomp"); | ||||||
|         this.elementsToShow = [ |         this.elementsToShow = [ | ||||||
|  |             new ImageCarouselWithUploadConstructor(), | ||||||
|             // new NameQuestion(),
 |             // new NameQuestion(),
 | ||||||
|             // new AccessTag(),
 |             // new AccessTag(),
 | ||||||
|             new OperatorTag(), |             new OperatorTag(), | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ import {TagRenderingOptions} from "../TagRendering"; | ||||||
| import {NameQuestion} from "../Questions/NameQuestion"; | import {NameQuestion} from "../Questions/NameQuestion"; | ||||||
| import {NameInline} from "../Questions/NameInline"; | import {NameInline} from "../Questions/NameInline"; | ||||||
| import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; | import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; | ||||||
|  | import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; | ||||||
| 
 | 
 | ||||||
| export class Bos extends LayerDefinition { | export class Bos extends LayerDefinition { | ||||||
| 
 | 
 | ||||||
|  | @ -33,6 +34,7 @@ export class Bos extends LayerDefinition { | ||||||
|         this.style = this.generateStyleFunction(); |         this.style = this.generateStyleFunction(); | ||||||
|         this.title = new NameInline("bos"); |         this.title = new NameInline("bos"); | ||||||
|         this.elementsToShow = [ |         this.elementsToShow = [ | ||||||
|  |             new ImageCarouselWithUploadConstructor(), | ||||||
|             new NameQuestion(), |             new NameQuestion(), | ||||||
|             new AccessTag(), |             new AccessTag(), | ||||||
|             new OperatorTag(), |             new OperatorTag(), | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								Customizations/Layers/GhostBike.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Customizations/Layers/GhostBike.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | import {LayerDefinition} from "../LayerDefinition"; | ||||||
|  | import {Tag} from "../../Logic/TagsFilter"; | ||||||
|  | import {FixedUiElement} from "../../UI/Base/FixedUiElement"; | ||||||
|  | import {TagRenderingOptions} from "../TagRendering"; | ||||||
|  | import FixedText from "../Questions/FixedText"; | ||||||
|  | import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; | ||||||
|  | import L from "leaflet"; | ||||||
|  | 
 | ||||||
|  | export class GhostBike extends LayerDefinition { | ||||||
|  |     constructor() { | ||||||
|  |         super(); | ||||||
|  |         this.name = "ghost bike"; | ||||||
|  |         this.overpassFilter = new Tag("memorial", "ghost_bike") | ||||||
|  |         this.title = new FixedText("Ghost bike"); | ||||||
|  | 
 | ||||||
|  |         this.elementsToShow = [ | ||||||
|  |             new FixedText("A <b>ghost bike</b> is a memorial for a cyclist who died in a traffic accident," + | ||||||
|  |                 " in the form of a white bicycle placed permanently near the accident location."), | ||||||
|  |             new ImageCarouselWithUploadConstructor(), | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         ]; | ||||||
|  | 
 | ||||||
|  |         this.style =  (tags: any) => { | ||||||
|  |             return { | ||||||
|  |                 color: "#000000", | ||||||
|  |                 icon: L.icon({ | ||||||
|  |                     iconUrl: 'assets/ghost_bike.svg', | ||||||
|  |                     iconSize: [40, 40], | ||||||
|  |                     iconAnchor: [20, 20], | ||||||
|  |                 }) | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -6,6 +6,7 @@ import {OperatorTag} from "../Questions/OperatorTag"; | ||||||
| import {NameQuestion} from "../Questions/NameQuestion"; | import {NameQuestion} from "../Questions/NameQuestion"; | ||||||
| import {NameInline} from "../Questions/NameInline"; | import {NameInline} from "../Questions/NameInline"; | ||||||
| import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; | import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; | ||||||
|  | import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; | ||||||
| 
 | 
 | ||||||
| export class NatureReserves extends LayerDefinition { | export class NatureReserves extends LayerDefinition { | ||||||
|      |      | ||||||
|  | @ -23,6 +24,7 @@ export class NatureReserves extends LayerDefinition { | ||||||
|         this.title =  new NameInline("natuurreservaat"); |         this.title =  new NameInline("natuurreservaat"); | ||||||
|         this.style = this.generateStyleFunction(); |         this.style = this.generateStyleFunction(); | ||||||
|         this.elementsToShow = [ |         this.elementsToShow = [ | ||||||
|  |             new ImageCarouselWithUploadConstructor(), | ||||||
|             new NameQuestion(), |             new NameQuestion(), | ||||||
|             new AccessTag(), |             new AccessTag(), | ||||||
|             new OperatorTag(), |             new OperatorTag(), | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ import {TagRenderingOptions} from "../TagRendering"; | ||||||
| import {NameQuestion} from "../Questions/NameQuestion"; | import {NameQuestion} from "../Questions/NameQuestion"; | ||||||
| import {NameInline} from "../Questions/NameInline"; | import {NameInline} from "../Questions/NameInline"; | ||||||
| import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; | import {DescriptionQuestion} from "../Questions/DescriptionQuestion"; | ||||||
|  | import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; | ||||||
| 
 | 
 | ||||||
| export class Park extends LayerDefinition { | export class Park extends LayerDefinition { | ||||||
| 
 | 
 | ||||||
|  | @ -58,6 +59,7 @@ export class Park extends LayerDefinition { | ||||||
|         this.style = this.generateStyleFunction(); |         this.style = this.generateStyleFunction(); | ||||||
|         this.title = new NameInline("park"); |         this.title = new NameInline("park"); | ||||||
|         this.elementsToShow = [ |         this.elementsToShow = [ | ||||||
|  |             new ImageCarouselWithUploadConstructor(), | ||||||
|             new NameQuestion(), |             new NameQuestion(), | ||||||
|             this.accessByDefault, |             this.accessByDefault, | ||||||
|             this.operatorByDefault, |             this.operatorByDefault, | ||||||
|  |  | ||||||
|  | @ -2,13 +2,14 @@ import {Layout} from "../Layout"; | ||||||
| import {GrbToFix} from "../Layers/GrbToFix"; | import {GrbToFix} from "../Layers/GrbToFix"; | ||||||
| import { BikePumps } from "../Layers/BikePumps"; | import { BikePumps } from "../Layers/BikePumps"; | ||||||
| import { BikeParkings } from "../Layers/BikeParkings"; | import { BikeParkings } from "../Layers/BikeParkings"; | ||||||
|  | import {GhostBike} from "../Layers/GhostBike"; | ||||||
| 
 | 
 | ||||||
| export default class Cyclofix extends Layout { | export default class Cyclofix extends Layout { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super( |         super( | ||||||
|             "pomp", |             "pomp", | ||||||
|             "Grb import fix tool", |             "Grb import fix tool", | ||||||
|             [new BikePumps(), new BikeParkings()], |             [new BikePumps(), new BikeParkings(), new GhostBike()], | ||||||
|             15, |             15, | ||||||
|             51.2083, |             51.2083, | ||||||
|             3.2279, |             3.2279, | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| import { TagRenderingOptions } from "../TagRendering"; | import { TagRenderingOptions } from "../TagRendering"; | ||||||
| 
 | 
 | ||||||
| export default class FixedName extends TagRenderingOptions { | export default class FixedText extends TagRenderingOptions { | ||||||
|     constructor(category: string) { |     constructor(category: string) { | ||||||
|         super({ |         super({ | ||||||
|             mappings: [ |             mappings: [ | ||||||
|  | @ -13,7 +13,6 @@ export class UserDetails { | ||||||
|     public osmConnection: OsmConnection; |     public osmConnection: OsmConnection; | ||||||
|     public dryRun: boolean; |     public dryRun: boolean; | ||||||
|     home: { lon: number; lat: number }; |     home: { lon: number; lat: number }; | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class OsmConnection { | export class OsmConnection { | ||||||
|  | @ -121,6 +120,27 @@ export class OsmConnection { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public preferences = new UIEventSource<any>({}); |     public preferences = new UIEventSource<any>({}); | ||||||
|  |     public preferenceSources : any = {} | ||||||
|  |      | ||||||
|  |     public GetPreference(key: string) : UIEventSource<string>{ | ||||||
|  |         if(this.preferenceSources[key] !== undefined){ | ||||||
|  |             return this.preferenceSources[key]; | ||||||
|  |         } | ||||||
|  |         const pref = new UIEventSource<string>(undefined); | ||||||
|  |         pref.addCallback((v) => { | ||||||
|  |             this.SetPreference(key, v); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         this.preferences.addCallback((prefs) => { | ||||||
|  |             if (prefs[key] !== undefined) { | ||||||
|  |                 pref.setData(prefs[key]); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |          | ||||||
|  |         this.preferenceSources[key] = pref; | ||||||
|  |         return pref; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     private UpdatePreferences() { |     private UpdatePreferences() { | ||||||
|         const self = this; |         const self = this; | ||||||
|         this.auth.xhr({ |         this.auth.xhr({ | ||||||
|  | @ -142,7 +162,7 @@ export class OsmConnection { | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     public SetPreference(k:string, v:string) { |     private SetPreference(k:string, v:string) { | ||||||
|         if(!this.userDetails.data.loggedIn){ |         if(!this.userDetails.data.loggedIn){ | ||||||
|             console.log("Not saving preference: user not logged in"); |             console.log("Not saving preference: user not logged in"); | ||||||
|             return; |             return; | ||||||
|  |  | ||||||
|  | @ -94,3 +94,6 @@ Trash icon by Dave Gandy, CC-BY-SA | ||||||
|  	 |  	 | ||||||
| https://commons.wikimedia.org/wiki/File:Home-icon.svg | https://commons.wikimedia.org/wiki/File:Home-icon.svg | ||||||
| Home icon by Timothy Miller, CC-BY-SA 3.0 | Home icon by Timothy Miller, CC-BY-SA 3.0 | ||||||
|  | 
 | ||||||
|  | https://commons.wikimedia.org/wiki/File:Map_icons_by_Scott_de_Jonge_-_bicycle-store.svg | ||||||
|  | Bicycle logo,  	Scott de Jonge | ||||||
|  | @ -15,29 +15,25 @@ import {TagDependantUIElement} from "../Customizations/UIElementConstructor"; | ||||||
| export class FeatureInfoBox extends UIElement { | export class FeatureInfoBox extends UIElement { | ||||||
| 
 | 
 | ||||||
|     private _tagsES: UIEventSource<any>; |     private _tagsES: UIEventSource<any>; | ||||||
|  |     private _changes: Changes; | ||||||
|  |     private _userDetails: UIEventSource<UserDetails>; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     private _title: UIElement; |     private _title: UIElement; | ||||||
|     private _osmLink: UIElement; |     private _osmLink: UIElement; | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     private _questions: QuestionPicker; |  | ||||||
| 
 |  | ||||||
|     private _changes: Changes; |  | ||||||
|     private _userDetails: UIEventSource<UserDetails>; |  | ||||||
|     private _imageElement: ImageCarousel; |  | ||||||
|     private _pictureUploader: UIElement; |  | ||||||
|     private _wikipedialink: UIElement; |     private _wikipedialink: UIElement; | ||||||
|     private _infoboxes: TagDependantUIElement[]; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |      | ||||||
|  |     private _infoboxes: TagDependantUIElement[]; | ||||||
|  |     private _questions: QuestionPicker; | ||||||
|  | 
 | ||||||
|     constructor( |     constructor( | ||||||
|         tagsES: UIEventSource<any>, |         tagsES: UIEventSource<any>, | ||||||
|         title: TagRenderingOptions, |         title: TagRenderingOptions, | ||||||
|         elementsToShow: TagRenderingOptions[], |         elementsToShow: TagRenderingOptions[], | ||||||
|         changes: Changes, |         changes: Changes, | ||||||
|         userDetails: UIEventSource<UserDetails>, |         userDetails: UIEventSource<UserDetails> | ||||||
|         preferedPictureLicense: UIEventSource<string> |  | ||||||
|     ) { |     ) { | ||||||
|         super(tagsES); |         super(tagsES); | ||||||
|         this._tagsES = tagsES; |         this._tagsES = tagsES; | ||||||
|  | @ -45,9 +41,9 @@ export class FeatureInfoBox extends UIElement { | ||||||
|         this._userDetails = userDetails; |         this._userDetails = userDetails; | ||||||
|         this.ListenTo(userDetails); |         this.ListenTo(userDetails); | ||||||
| 
 | 
 | ||||||
|         this._imageElement = new ImageCarousel(this._tagsES, changes); |          | ||||||
| 
 |  | ||||||
|         this._infoboxes = []; |         this._infoboxes = []; | ||||||
|  |         elementsToShow = elementsToShow ?? [] | ||||||
|         for (const tagRenderingOption of elementsToShow) { |         for (const tagRenderingOption of elementsToShow) { | ||||||
|             this._infoboxes.push( |             this._infoboxes.push( | ||||||
|                 tagRenderingOption.construct(this._tagsES, this._changes)); |                 tagRenderingOption.construct(this._tagsES, this._changes)); | ||||||
|  | @ -60,11 +56,9 @@ export class FeatureInfoBox extends UIElement { | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         this._title = new TagRenderingOptions(title.options).construct(this._tagsES, this._changes); |         this._title = new TagRenderingOptions(title.options).construct(this._tagsES, this._changes); | ||||||
| 
 |  | ||||||
|         this._osmLink =new OsmLink().construct(this._tagsES, this._changes); |         this._osmLink =new OsmLink().construct(this._tagsES, this._changes); | ||||||
|         this._wikipedialink = new WikipediaLink().construct(this._tagsES, this._changes); |         this._wikipedialink = new WikipediaLink().construct(this._tagsES, this._changes); | ||||||
|         this._pictureUploader = new OsmImageUploadHandler(tagsES, userDetails, preferedPictureLicense, |      | ||||||
|             changes, this._imageElement.slideshow).getUI(); |  | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -110,10 +104,6 @@ export class FeatureInfoBox extends UIElement { | ||||||
|             "</div>" + |             "</div>" + | ||||||
| 
 | 
 | ||||||
|             "<div class='infoboxcontents'>" + |             "<div class='infoboxcontents'>" + | ||||||
| 
 |  | ||||||
|             this._imageElement.Render() + |  | ||||||
|             this._pictureUploader.Render() + |  | ||||||
| 
 |  | ||||||
|             new VerticalCombine(info, "infobox-information ").Render() + |             new VerticalCombine(info, "infobox-information ").Render() + | ||||||
| 
 | 
 | ||||||
|             questionsHtml + |             questionsHtml + | ||||||
|  | @ -126,8 +116,6 @@ export class FeatureInfoBox extends UIElement { | ||||||
| 
 | 
 | ||||||
|     Activate() { |     Activate() { | ||||||
|         super.Activate(); |         super.Activate(); | ||||||
|         this._imageElement.Activate(); |  | ||||||
|         this._pictureUploader.Activate(); |  | ||||||
|         for (const infobox of this._infoboxes) { |         for (const infobox of this._infoboxes) { | ||||||
|             infobox.Activate(); |             infobox.Activate(); | ||||||
|         } |         } | ||||||
|  | @ -135,8 +123,6 @@ export class FeatureInfoBox extends UIElement { | ||||||
| 
 | 
 | ||||||
|     Update() { |     Update() { | ||||||
|         super.Update(); |         super.Update(); | ||||||
|         this._imageElement.Update(); |  | ||||||
|         this._pictureUploader.Update(); |  | ||||||
|         this._title.Update(); |         this._title.Update(); | ||||||
|         for (const infobox of this._infoboxes) { |         for (const infobox of this._infoboxes) { | ||||||
|             infobox.Update(); |             infobox.Update(); | ||||||
|  |  | ||||||
|  | @ -8,8 +8,29 @@ import {Changes} from "../../Logic/Changes"; | ||||||
| import {VariableUiElement} from "../Base/VariableUIElement"; | import {VariableUiElement} from "../Base/VariableUIElement"; | ||||||
| import {ConfirmDialog} from "../ConfirmDialog"; | import {ConfirmDialog} from "../ConfirmDialog"; | ||||||
| import {UserDetails} from "../../Logic/OsmConnection"; | import {UserDetails} from "../../Logic/OsmConnection"; | ||||||
|  | import {TagDependantUIElement, TagDependantUIElementConstructor} from "../../Customizations/UIElementConstructor"; | ||||||
|  | 
 | ||||||
|  | export class ImageCarouselConstructor implements TagDependantUIElementConstructor{ | ||||||
|  |     IsKnown(properties: any): boolean { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IsQuestioning(properties: any): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Priority(): number { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     construct(tags: UIEventSource<any>, changes: Changes): TagDependantUIElement { | ||||||
|  |         return new ImageCarousel(tags, changes); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class ImageCarousel extends TagDependantUIElement { | ||||||
| 
 | 
 | ||||||
| export class ImageCarousel extends UIElement { |  | ||||||
| 
 | 
 | ||||||
|     private readonly searcher: ImageSearcher; |     private readonly searcher: ImageSearcher; | ||||||
| 
 | 
 | ||||||
|  | @ -98,6 +119,18 @@ export class ImageCarousel extends UIElement { | ||||||
|             "</span>"; |             "</span>"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     IsKnown(): boolean { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IsQuestioning(): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Priority(): number { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     InnerUpdate(htmlElement: HTMLElement) { |     InnerUpdate(htmlElement: HTMLElement) { | ||||||
|         super.InnerUpdate(htmlElement); |         super.InnerUpdate(htmlElement); | ||||||
|         this._deleteButton.Update(); |         this._deleteButton.Update(); | ||||||
|  |  | ||||||
							
								
								
									
										71
									
								
								UI/Image/ImageCarouselWithUpload.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								UI/Image/ImageCarouselWithUpload.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,71 @@ | ||||||
|  | import {TagDependantUIElement, TagDependantUIElementConstructor} from "../../Customizations/UIElementConstructor"; | ||||||
|  | import {ImageCarousel} from "./ImageCarousel"; | ||||||
|  | import {OsmImageUploadHandler} from "../../Logic/OsmImageUploadHandler"; | ||||||
|  | import {UIEventSource} from "../UIEventSource"; | ||||||
|  | import {Changes} from "../../Logic/Changes"; | ||||||
|  | import {UserDetails} from "../../Logic/OsmConnection"; | ||||||
|  | import {ImageUploadFlow} from "../ImageUploadFlow"; | ||||||
|  | 
 | ||||||
|  | export class ImageCarouselWithUploadConstructor implements TagDependantUIElementConstructor{ | ||||||
|  |     IsKnown(properties: any): boolean { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IsQuestioning(properties: any): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Priority(): number { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     construct(tags: UIEventSource<any>, changes: Changes): TagDependantUIElement { | ||||||
|  |         return new ImageCarouselWithUpload(tags, changes); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class ImageCarouselWithUpload extends TagDependantUIElement { | ||||||
|  |     private _imageElement: ImageCarousel; | ||||||
|  |     private _pictureUploader: ImageUploadFlow; | ||||||
|  | 
 | ||||||
|  |     constructor(tags: UIEventSource<any>, changes: Changes) { | ||||||
|  |         super(tags); | ||||||
|  |         this._imageElement = new ImageCarousel(tags, changes); | ||||||
|  |         const userDetails = changes.login.userDetails; | ||||||
|  |         const license = changes.login.GetPreference( "mapcomplete-pictures-license"); | ||||||
|  |         this._pictureUploader = new OsmImageUploadHandler(tags, | ||||||
|  |             userDetails, license, | ||||||
|  |             changes, this._imageElement.slideshow).getUI(); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected InnerRender(): string { | ||||||
|  |         return this._imageElement.Render() + | ||||||
|  |             this._pictureUploader.Render(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Activate() { | ||||||
|  |         super.Activate(); | ||||||
|  |         this._imageElement.Activate(); | ||||||
|  |         this._pictureUploader.Activate(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Update() { | ||||||
|  |         super.Update(); | ||||||
|  |         this._imageElement.Update(); | ||||||
|  |         this._pictureUploader.Update(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IsKnown(): boolean { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     IsQuestioning(): boolean { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     Priority(): number { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										92
									
								
								assets/ghost_bike.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								assets/ghost_bike.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <svg | ||||||
|  |    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||||
|  |    xmlns:cc="http://creativecommons.org/ns#" | ||||||
|  |    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||||
|  |    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||||
|  |    version="2" | ||||||
|  |    width="50" | ||||||
|  |    height="50" | ||||||
|  |    viewBox="0 0 50 50" | ||||||
|  |    id="svg4" | ||||||
|  |    sodipodi:docname="ghost_bike.svg" | ||||||
|  |    inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> | ||||||
|  |   <metadata | ||||||
|  |      id="metadata10"> | ||||||
|  |     <rdf:RDF> | ||||||
|  |       <cc:Work | ||||||
|  |          rdf:about=""> | ||||||
|  |         <dc:format>image/svg+xml</dc:format> | ||||||
|  |         <dc:type | ||||||
|  |            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||||
|  |         <dc:title></dc:title> | ||||||
|  |       </cc:Work> | ||||||
|  |     </rdf:RDF> | ||||||
|  |   </metadata> | ||||||
|  |   <defs | ||||||
|  |      id="defs8" /> | ||||||
|  |   <sodipodi:namedview | ||||||
|  |      pagecolor="#ffffff" | ||||||
|  |      bordercolor="#666666" | ||||||
|  |      borderopacity="1" | ||||||
|  |      objecttolerance="10" | ||||||
|  |      gridtolerance="10" | ||||||
|  |      guidetolerance="10" | ||||||
|  |      inkscape:pageopacity="0" | ||||||
|  |      inkscape:pageshadow="2" | ||||||
|  |      inkscape:window-width="1920" | ||||||
|  |      inkscape:window-height="1001" | ||||||
|  |      id="namedview6" | ||||||
|  |      showgrid="false" | ||||||
|  |      inkscape:zoom="4.72" | ||||||
|  |      inkscape:cx="-40.53625" | ||||||
|  |      inkscape:cy="33.532739" | ||||||
|  |      inkscape:window-x="0" | ||||||
|  |      inkscape:window-y="0" | ||||||
|  |      inkscape:window-maximized="1" | ||||||
|  |      inkscape:current-layer="layer1" /> | ||||||
|  |   <g | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer2" | ||||||
|  |      inkscape:label="background" | ||||||
|  |      sodipodi:insensitive="true"> | ||||||
|  |     <ellipse | ||||||
|  |        style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:50;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | ||||||
|  |        id="path839" | ||||||
|  |        cx="25" | ||||||
|  |        cy="24.894068" | ||||||
|  |        rx="25" | ||||||
|  |        ry="25.105932" /> | ||||||
|  |   </g> | ||||||
|  |   <g | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer1" | ||||||
|  |      inkscape:label="bicycle"> | ||||||
|  |     <path | ||||||
|  |        d="m 37.198846,28.51624 c -0.865699,0 -1.688316,0.177789 -2.435717,0.497127 l -2.103385,-3.60434 1.58506,-2.71676 c 0.215399,-0.370622 0.09027,-0.846552 -0.279675,-1.063319 -0.162747,-0.09437 -0.343955,-0.265316 -0.515591,-0.237279 l -0.134709,-0.158644 h -3.109265 c -0.428746,0 -0.776803,0.596963 -0.776803,1.02571 0,0.429429 0.348057,1.025708 0.776803,1.025708 h 2.015176 l -0.90741,1.367611 h -9.079572 l 1.813452,-3.419029 h 0.718681 c 0.428746,0 0.776802,-0.254375 0.776802,-0.683806 0,-0.42943 -0.348056,-0.683806 -0.776802,-0.683806 h -3.886069 c -0.428061,0 -0.776803,0.254376 -0.776803,0.683806 0,0.429431 0.348057,0.683806 0.776803,0.683806 h 1.366929 l -4.368835,7.634691 c -0.748084,-0.319337 -1.572071,-0.423959 -2.437085,-0.423959 -3.432704,0 -6.2157926,2.820014 -6.2157926,6.252718 0,3.433389 2.7830886,6.234257 6.2164776,6.234257 3.433388,0 6.216478,-2.774199 6.216478,-6.207588 0,-2.010389 -0.958697,-3.788967 -2.441187,-4.926136 l 1.663699,-2.848735 4.768861,8.17558 0.01847,0.02598 0.02051,0.03077 0.01572,0.02325 0.06154,0.07111 0.0076,0.0089 0.0212,0.01915 0.02188,0.01777 0.06017,0.04787 0.0253,0.01641 0.01983,0.01298 0.0082,0.0048 0.0027,0.0027 0.06564,0.03214 0.0076,0.0033 0.01573,0.0082 0.0054,0.0014 0.04992,0.01778 0.0465,0.01505 0.0095,0.0027 0.01709,0.0027 0.03008,0.0062 0.139496,0.01436 6.84e-4,0.04239 0.0027,0.04034 h 4.712106 c 0.384299,2.735223 2.9937,5.398646 6.16314,5.398646 3.433388,0 6.216478,-2.804288 6.216478,-6.237676 6.83e-4,-3.432704 -2.782407,-6.236991 -6.215794,-6.236991 z m -17.095143,6.216477 c 0,2.575896 -2.086974,4.662872 -4.662187,4.662872 -2.575213,0 -4.662188,-2.087659 -4.662188,-4.662872 0,-2.574528 2.086975,-4.661503 4.662188,-4.661503 0.579183,0 1.131698,0.110088 1.643185,0.30361 l -2.314683,3.96744 c -0.216082,0.369938 -0.09027,0.845868 0.280362,1.063319 0.123084,0.07111 0.257794,0.10531 0.390451,0.10531 0.267369,0 0.527215,-0.13813 0.672182,-0.384984 l 2.315367,-3.970175 c 1.022972,0.855441 1.675323,2.140312 1.675323,3.576987 z m 6.216477,-1.708146 -4.086422,-7.004905 h 8.173529 z m 5.438991,-5.938853 1.664383,2.918483 c -1.286923,0.987416 -2.17587,2.169715 -2.38785,4.221133 h -3.362956 z m 2.452811,4.338747 1.634979,2.800869 H 32.60709 c 0.187363,-1.367612 0.769965,-2.102702 1.604892,-2.800869 z m 2.986864,8.01352 c -2.309212,0 -4.222501,-1.793624 -4.592439,-3.84504 h 4.590387 l 0.0033,-0.04035 0.138811,-0.03624 0.03145,-0.01572 0.129239,-0.04513 0.01436,-0.01089 0.07727,-0.03966 0.01847,-0.01436 0.06907,-0.04992 0.05334,-0.04513 0.05197,-0.05675 0.0465,-0.05813 0.03898,-0.06292 0.03556,-0.06496 0.02667,-0.07111 0.0212,-0.07111 0.01164,-0.07111 0.0089,-0.08411 0.002,-0.02394 -0.0033,-0.04377 -0.0095,-0.0848 -0.01573,-0.07248 -0.02257,-0.07111 -0.03556,-0.07726 -0.01847,-0.04035 -2.314683,-3.96744 c 0.512856,-0.193517 1.064686,-0.30361 1.643186,-0.30361 2.575896,0 4.662871,2.108172 4.662871,4.682701 6.83e-4,2.575896 -2.086975,4.684753 -4.662871,4.684753 z" | ||||||
|  |        id="path2" | ||||||
|  |        style="fill:#ffffff;fill-opacity:1;stroke-width:0.6838057" | ||||||
|  |        inkscape:connector-curvature="0" /> | ||||||
|  |     <g | ||||||
|  |        id="g861" | ||||||
|  |        transform="translate(-10.037321,-26.552854)"> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path842" | ||||||
|  |          d="M 25.018397,35.018924 V 47.003785" | ||||||
|  |          style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |       <path | ||||||
|  |          inkscape:connector-curvature="0" | ||||||
|  |          id="path842-3" | ||||||
|  |          d="M 28.86857,39.213625 H 20.748791" | ||||||
|  |          style="fill:none;stroke:#ffffff;stroke-width:1.64621139;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> | ||||||
|  |     </g> | ||||||
|  |   </g> | ||||||
|  |   <g | ||||||
|  |      inkscape:groupmode="layer" | ||||||
|  |      id="layer3" | ||||||
|  |      inkscape:label="cross" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 5.7 KiB | 
							
								
								
									
										22
									
								
								index.ts
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								index.ts
									
										
									
									
									
								
							|  | @ -102,7 +102,6 @@ const leftMessage = new UIEventSource<() => UIElement>(undefined); | ||||||
| 
 | 
 | ||||||
| const selectedElement = new UIEventSource<any>(undefined); | const selectedElement = new UIEventSource<any>(undefined); | ||||||
| 
 | 
 | ||||||
| const preferedPictureLicense = new UIEventSource<string>(undefined); |  | ||||||
| 
 | 
 | ||||||
| const locationControl = new UIEventSource<{ lat: number, lon: number, zoom: number }>({ | const locationControl = new UIEventSource<{ lat: number, lon: number, zoom: number }>({ | ||||||
|     zoom: questSetToRender.startzoom, |     zoom: questSetToRender.startzoom, | ||||||
|  | @ -137,21 +136,6 @@ const bm = new Basemap("leafletDiv", locationControl, new VariableUiElement( | ||||||
| )); | )); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| // ------------- Tie together user settings and UI -----------
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| const picturesPrefName = "mapcomplete-pictures-license"; |  | ||||||
| preferedPictureLicense.addCallback((license) => { |  | ||||||
|     osmConnection.SetPreference(picturesPrefName, license); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| osmConnection.preferences.addCallback((prefs) => { |  | ||||||
|     if (prefs[picturesPrefName] !== undefined) { |  | ||||||
|         preferedPictureLicense.setData(prefs[picturesPrefName]); |  | ||||||
|     } |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // ------------- Setup the layers -------------------------------
 | // ------------- Setup the layers -------------------------------
 | ||||||
| 
 | 
 | ||||||
| const addButtons: { | const addButtons: { | ||||||
|  | @ -175,8 +159,7 @@ for (const layer of questSetToRender.layers) { | ||||||
|             layer.title, |             layer.title, | ||||||
|             layer.elementsToShow, |             layer.elementsToShow, | ||||||
|             changes, |             changes, | ||||||
|             osmConnection.userDetails, |             osmConnection.userDetails | ||||||
|             preferedPictureLicense |  | ||||||
|         ) |         ) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -228,8 +211,7 @@ selectedElement.addCallback((data) => { | ||||||
|                     layer.title, |                     layer.title, | ||||||
|                     layer.elementsToShow, |                     layer.elementsToShow, | ||||||
|                     changes, |                     changes, | ||||||
|                     osmConnection.userDetails, |                     osmConnection.userDetails | ||||||
|                     preferedPictureLicense |  | ||||||
|                 )); |                 )); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue