forked from MapComplete/MapComplete
		
	Refactoring: fix #2190, refactor noteCommentElement into svelte
This commit is contained in:
		
							parent
							
								
									565f1041fc
								
							
						
					
					
						commit
						1a3bb7bb27
					
				
					 3 changed files with 232 additions and 243 deletions
				
			
		
							
								
								
									
										103
									
								
								src/UI/Popup/Notes/NoteCommentElement.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/UI/Popup/Notes/NoteCommentElement.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,103 @@ | |||
| <script lang="ts"> | ||||
|   import type { SpecialVisualizationState } from "../../SpecialVisualization" | ||||
|   import Translations from "../../i18n/Translations" | ||||
|   import Note from "../../../assets/svg/Note.svelte" | ||||
|   import Resolved from "../../../assets/svg/Resolved.svelte" | ||||
|   import Speech_bubble from "../../../assets/svg/Speech_bubble.svelte" | ||||
|   import { ImmutableStore, Stores } from "../../../Logic/UIEventSource" | ||||
|   import { Utils } from "../../../Utils" | ||||
|   import Img from "../../Base/Img" | ||||
|   import { SlideShow } from "../../Image/SlideShow" | ||||
|   import ToSvelte from "../../Base/ToSvelte.svelte" | ||||
|   import Tr from "../../Base/Tr.svelte" | ||||
| 
 | ||||
|   export let comment: { | ||||
|     date: string | ||||
|     uid: number | ||||
|     user: string | ||||
|     user_url: string | ||||
|     action: "closed" | "opened" | "reopened" | "commented" | ||||
|     text: string | ||||
|     html: string | ||||
|     highlighted: boolean | ||||
|   } | ||||
|   export let state: SpecialVisualizationState = undefined | ||||
| 
 | ||||
|   const t = Translations.t.notes | ||||
| 
 | ||||
|   // Info about the user who made the comment | ||||
|   let userinfo = Stores.FromPromise( | ||||
|     Utils.downloadJsonCached<{ user: { img: { href: string } } }>( | ||||
|       "https://api.openstreetmap.org/api/0.6/user/" + comment.uid, | ||||
|       24 * 60 * 60 * 1000, | ||||
|     ), | ||||
|   ) | ||||
| 
 | ||||
|   const htmlElement = document.createElement("div") | ||||
|   htmlElement.innerHTML = Utils.purify(comment.html) | ||||
|   let images: string[] = Array.from(htmlElement.getElementsByTagName("a")) | ||||
|     .map((link) => link.href) | ||||
|     .filter((link) => { | ||||
|       link = link.toLowerCase() | ||||
|       const lastDotIndex = link.lastIndexOf(".") | ||||
|       const extension = link.substring(lastDotIndex + 1, link.length) | ||||
|       return Utils.imageExtensions.has(extension) | ||||
|     }) | ||||
|     .filter((link) => !link.startsWith("https://wiki.openstreetmap.org/wiki/File:")) | ||||
| 
 | ||||
| 
 | ||||
|   let imgStore = new ImmutableStore( | ||||
|     images.map((i) => | ||||
|       new Img(i).SetClass("w-full block cursor-pointer") | ||||
|         .onClick(() => | ||||
|           state?.previewedImage?.setData( | ||||
|             <any>{ | ||||
|               url_hd: i, | ||||
|               url: i, | ||||
|             }), | ||||
|         ))) | ||||
| 
 | ||||
| 
 | ||||
| </script> | ||||
| 
 | ||||
| <div class="flex flex-col py-2 my-2 border-gray-500 border-b" class:border-interactive={comment.highlighted}> | ||||
| 
 | ||||
|   <div class="flex"> | ||||
| 
 | ||||
|     <!-- Action icon, e.g. 'created', 'commented', 'closed' --> | ||||
|     {#if comment.action === "opened" || comment.action === "reopened"} | ||||
|       <Note class="shrink-0 mr-4 w-6" /> | ||||
|     {:else if comment.action === "closed"} | ||||
|       <Resolved class="shrink-0 mr-4 w-6" /> | ||||
|     {:else} | ||||
|       <Speech_bubble class="shrink-0 mr-4 w-6" /> | ||||
|     {/if} | ||||
|     <div class="flex flex-col gap-y-2"> | ||||
|       {@html comment.html} | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   {#if images.length > 0} | ||||
|     <ToSvelte | ||||
|       construct={() => new SlideShow(imgStore) .SetClass("mb-1").SetStyle("min-width: 50px; background: grey;")} /> | ||||
|   {/if} | ||||
| 
 | ||||
| 
 | ||||
|   <div class="flex justify-end items-center subtle pt-4 pb-2"> | ||||
|     <!-- commenter info --> | ||||
| 
 | ||||
|     {#if $userinfo?.user?.img?.href} | ||||
|       <img alt="avatar" aria-hidden="true" src={$userinfo?.user?.img?.href} class="rounded-full w-8 h-8 mr-4" /> | ||||
|     {/if} | ||||
| 
 | ||||
|     <span class="mr-2"> | ||||
|   {#if comment.user === undefined} | ||||
|     <Tr t={t.anonymous} /> | ||||
|   {:else} | ||||
|     <a href={comment.user_url} target="_blank">{comment.user}</a> | ||||
|       {/if} | ||||
|       {comment.date} | ||||
|       </span> | ||||
| 
 | ||||
|   </div> | ||||
| </div> | ||||
|  | @ -1,117 +1,7 @@ | |||
| import Combine from "../../Base/Combine" | ||||
| import BaseUIElement from "../../BaseUIElement" | ||||
| import Link from "../../Base/Link" | ||||
| import { FixedUiElement } from "../../Base/FixedUiElement" | ||||
| import Translations from "../../i18n/Translations" | ||||
| import { Utils } from "../../../Utils" | ||||
| import Img from "../../Base/Img" | ||||
| import { SlideShow } from "../../Image/SlideShow" | ||||
| import { Store, Stores, UIEventSource } from "../../../Logic/UIEventSource" | ||||
| import { VariableUiElement } from "../../Base/VariableUIElement" | ||||
| import { SpecialVisualizationState } from "../../SpecialVisualization" | ||||
| import SvelteUIElement from "../../Base/SvelteUIElement" | ||||
| import Note from "../../../assets/svg/Note.svelte" | ||||
| import Resolved from "../../../assets/svg/Resolved.svelte" | ||||
| import Speech_bubble from "../../../assets/svg/Speech_bubble.svelte" | ||||
| import { Store, UIEventSource } from "../../../Logic/UIEventSource" | ||||
| 
 | ||||
| export default class NoteCommentElement extends Combine { | ||||
|     constructor( | ||||
|         comment: { | ||||
|             date: string | ||||
|             uid: number | ||||
|             user: string | ||||
|             user_url: string | ||||
|             action: "closed" | "opened" | "reopened" | "commented" | ||||
|             text: string | ||||
|             html: string | ||||
|             highlighted: boolean | ||||
|         }, | ||||
|         state?: SpecialVisualizationState, | ||||
|         index?: number, | ||||
|         totalNumberOfComments?: number | ||||
|     ) { | ||||
|         const t = Translations.t.notes | ||||
| export default class NoteCommentElement { | ||||
| 
 | ||||
|         let actionIcon: BaseUIElement | ||||
|         if (comment.action === "opened" || comment.action === "reopened") { | ||||
|             actionIcon = new SvelteUIElement(Note) | ||||
|         } else if (comment.action === "closed") { | ||||
|             actionIcon = new SvelteUIElement(Resolved) | ||||
|         } else { | ||||
|             actionIcon = new SvelteUIElement(Speech_bubble) | ||||
|         } | ||||
| 
 | ||||
|         let user: BaseUIElement | ||||
|         if (comment.user === undefined) { | ||||
|             user = t.anonymous | ||||
|         } else { | ||||
|             user = new Link(comment.user, comment.user_url ?? "", true) | ||||
|         } | ||||
| 
 | ||||
|         const userinfo = Stores.FromPromise( | ||||
|             Utils.downloadJsonCached<{ user: { img: { href: string } } }>( | ||||
|                 "https://api.openstreetmap.org/api/0.6/user/" + comment.uid, | ||||
|                 24 * 60 * 60 * 1000 | ||||
|             ) | ||||
|         ) | ||||
|         const userImg = new VariableUiElement( | ||||
|             userinfo.map((userinfo) => { | ||||
|                 const href = userinfo?.user?.img?.href | ||||
|                 if (href !== undefined) { | ||||
|                     return new Img(href).SetClass("rounded-full w-8 h-8 mr-4") | ||||
|                 } | ||||
|                 return undefined | ||||
|             }) | ||||
|         ) | ||||
| 
 | ||||
|         const htmlElement = document.createElement("div") | ||||
|         htmlElement.innerHTML = Utils.purify(comment.html) | ||||
|         const images = Array.from(htmlElement.getElementsByTagName("a")) | ||||
|             .map((link) => link.href) | ||||
|             .filter((link) => { | ||||
|                 link = link.toLowerCase() | ||||
|                 const lastDotIndex = link.lastIndexOf(".") | ||||
|                 const extension = link.substring(lastDotIndex + 1, link.length) | ||||
|                 return Utils.imageExtensions.has(extension) | ||||
|             }) | ||||
|             .filter((link) => !link.startsWith("https://wiki.openstreetmap.org/wiki/File:")) | ||||
|         let imagesEl: BaseUIElement = undefined | ||||
|         if (images.length > 0) { | ||||
|             const imageEls = images.map((i) => | ||||
|                 new Img(i) | ||||
|                     .SetClass("w-full block cursor-pointer") | ||||
|                     .onClick(() => | ||||
|                         state?.previewedImage?.setData(<any>{ | ||||
|                             url_hd: i, | ||||
|                             url: i, | ||||
|                         }) | ||||
|                     ) | ||||
|                     .SetStyle("min-width: 50px; background: grey;") | ||||
|             ) | ||||
|             imagesEl = new SlideShow(new UIEventSource<BaseUIElement[]>(imageEls)).SetClass("mb-1") | ||||
|         } | ||||
| 
 | ||||
|         super([ | ||||
|             new Combine([ | ||||
|                 actionIcon.SetClass("mr-4 w-6").SetStyle("flex-shrink: 0"), | ||||
|                 new FixedUiElement(comment.html).SetClass("flex flex-col").SetStyle("margin: 0"), | ||||
|             ]).SetClass("flex"), | ||||
|             imagesEl, | ||||
|             new Combine([userImg, user.SetClass("mr-2"), comment.date]).SetClass( | ||||
|                 "flex justify-end items-center subtle" | ||||
|             ), | ||||
|         ]) | ||||
|         this.SetClass("flex flex-col pb-2 mb-2 border-gray-500 border-b") | ||||
|         if (comment.highlighted) { | ||||
|             this.SetClass("focus") | ||||
|             if (index + 2 === totalNumberOfComments) { | ||||
|                 console.log("Scrolling into view") | ||||
|                 requestAnimationFrame(() => { | ||||
|                     this.ScrollIntoView() | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Adds the comment to the _visualisation_ of the given note; doesn't _actually_ upload | ||||
|  |  | |||
|  | @ -2,11 +2,7 @@ import Combine from "./Base/Combine" | |||
| import { FixedUiElement } from "./Base/FixedUiElement" | ||||
| import BaseUIElement from "./BaseUIElement" | ||||
| import Title from "./Base/Title" | ||||
| import { | ||||
|     RenderingSpecification, | ||||
|     SpecialVisualization, | ||||
|     SpecialVisualizationState, | ||||
| } from "./SpecialVisualization" | ||||
| import { RenderingSpecification, SpecialVisualization, SpecialVisualizationState } from "./SpecialVisualization" | ||||
| import { HistogramViz } from "./Popup/HistogramViz" | ||||
| import MinimapViz from "./Popup/MinimapViz.svelte" | ||||
| import { ShareLinkViz } from "./Popup/ShareLinkViz" | ||||
|  | @ -27,7 +23,6 @@ import { Translation } from "./i18n/Translation" | |||
| import Translations from "./i18n/Translations" | ||||
| import OpeningHoursVisualization from "./OpeningHours/OpeningHoursVisualization" | ||||
| import { SubtleButton } from "./Base/SubtleButton" | ||||
| import NoteCommentElement from "./Popup/Notes/NoteCommentElement" | ||||
| import List from "./Base/List" | ||||
| import StatisticsPanel from "./BigComponents/StatisticsPanel" | ||||
| import AutoApplyButton from "./Popup/AutoApplyButton" | ||||
|  | @ -101,6 +96,7 @@ import QrCode from "./Popup/QrCode.svelte" | |||
| import ClearCaches from "./Popup/ClearCaches.svelte" | ||||
| import GroupedView from "./Popup/GroupedView.svelte" | ||||
| import { QuestionableTagRenderingConfigJson } from "../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson" | ||||
| import NoteCommentElement from "./Popup/Notes/NoteCommentElement.svelte" | ||||
| 
 | ||||
| class NearbyImageVis implements SpecialVisualization { | ||||
|     // Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
 | ||||
|  | @ -126,7 +122,7 @@ class NearbyImageVis implements SpecialVisualization { | |||
|         tags: UIEventSource<Record<string, string>>, | ||||
|         args: string[], | ||||
|         feature: Feature, | ||||
|         layer: LayerConfig | ||||
|         layer: LayerConfig, | ||||
|     ): SvelteUIElement { | ||||
|         const isOpen = args[0] === "open" | ||||
|         const readonly = args[1] === "readonly" | ||||
|  | @ -193,7 +189,7 @@ class StealViz implements SpecialVisualization { | |||
|                                 selectedElement: otherFeature, | ||||
|                                 state, | ||||
|                                 layer, | ||||
|                             }) | ||||
|                             }), | ||||
|                         ) | ||||
|                     } | ||||
|                     if (elements.length === 1) { | ||||
|  | @ -201,8 +197,8 @@ class StealViz implements SpecialVisualization { | |||
|                     } | ||||
|                     return new Combine(elements).SetClass("flex flex-col") | ||||
|                 }, | ||||
|                 [state.indexedFeatures.featuresById] | ||||
|             ) | ||||
|                 [state.indexedFeatures.featuresById], | ||||
|             ), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|  | @ -254,11 +250,11 @@ class CloseNoteViz implements SpecialVisualization { | |||
|     public constr( | ||||
|         state: SpecialVisualizationState, | ||||
|         tags: UIEventSource<Record<string, string>>, | ||||
|         args: string[] | ||||
|         args: string[], | ||||
|     ): SvelteUIElement { | ||||
|         const { text, icon, idkey, comment, minZoom, zoomButton } = Utils.ParseVisArgs( | ||||
|             this.args, | ||||
|             args | ||||
|             args, | ||||
|         ) | ||||
| 
 | ||||
|         return new SvelteUIElement(CloseNoteButton, { | ||||
|  | @ -299,7 +295,7 @@ export class QuestionViz implements SpecialVisualization { | |||
|         tags: UIEventSource<Record<string, string>>, | ||||
|         args: string[], | ||||
|         feature: Feature, | ||||
|         layer: LayerConfig | ||||
|         layer: LayerConfig, | ||||
|     ): SvelteUIElement { | ||||
|         const labels = args[0] | ||||
|             ?.split(";") | ||||
|  | @ -331,7 +327,7 @@ export default class SpecialVisualizations { | |||
|         for (const specialVisualization of SpecialVisualizations.specialVisualizations) { | ||||
|             SpecialVisualizations.specialVisualisationsDict.set( | ||||
|                 specialVisualization.funcName, | ||||
|                 specialVisualization | ||||
|                 specialVisualization, | ||||
|             ) | ||||
|         } | ||||
|     } | ||||
|  | @ -351,15 +347,15 @@ export default class SpecialVisualizations { | |||
|             viz.docs, | ||||
|             viz.args.length > 0 | ||||
|                 ? MarkdownUtils.table( | ||||
|                       ["name", "default", "description"], | ||||
|                       viz.args.map((arg) => { | ||||
|                           let defaultArg = arg.defaultValue ?? "_undefined_" | ||||
|                           if (defaultArg == "") { | ||||
|                               defaultArg = "_empty string_" | ||||
|                           } | ||||
|                           return [arg.name, defaultArg, arg.doc] | ||||
|                       }) | ||||
|                   ) | ||||
|                     ["name", "default", "description"], | ||||
|                     viz.args.map((arg) => { | ||||
|                         let defaultArg = arg.defaultValue ?? "_undefined_" | ||||
|                         if (defaultArg == "") { | ||||
|                             defaultArg = "_empty string_" | ||||
|                         } | ||||
|                         return [arg.name, defaultArg, arg.doc] | ||||
|                     }), | ||||
|                 ) | ||||
|                 : undefined, | ||||
|             "#### Example usage of " + viz.funcName, | ||||
|             "<code>" + example + "</code>", | ||||
|  | @ -368,18 +364,18 @@ export default class SpecialVisualizations { | |||
| 
 | ||||
|     public static constructSpecification( | ||||
|         template: string, | ||||
|         extraMappings: SpecialVisualization[] = [] | ||||
|         extraMappings: SpecialVisualization[] = [], | ||||
|     ): RenderingSpecification[] { | ||||
|         return SpecialVisualisationUtils.constructSpecification( | ||||
|             template, | ||||
|             SpecialVisualizations.specialVisualisationsDict, | ||||
|             extraMappings | ||||
|             extraMappings, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     public static HelpMessage(): string { | ||||
|         const helpTexts: string[] = SpecialVisualizations.specialVisualizations.map((viz) => | ||||
|             SpecialVisualizations.DocumentationFor(viz) | ||||
|             SpecialVisualizations.DocumentationFor(viz), | ||||
|         ) | ||||
| 
 | ||||
|         const firstPart = new Combine([ | ||||
|  | @ -412,10 +408,10 @@ export default class SpecialVisualizations { | |||
|                         }, | ||||
|                     }, | ||||
|                     null, | ||||
|                     "  " | ||||
|                 ) | ||||
|                     "  ", | ||||
|                 ), | ||||
|             ).SetClass("code"), | ||||
|             'In other words: use `{ "before": ..., "after": ..., "special": {"type": ..., "argname": ...argvalue...}`. The args are in the `special` block; an argvalue can be a string, a translation or another value. (Refer to class `RewriteSpecial` in case of problems)', | ||||
|             "In other words: use `{ \"before\": ..., \"after\": ..., \"special\": {\"type\": ..., \"argname\": ...argvalue...}`. The args are in the `special` block; an argvalue can be a string, a translation or another value. (Refer to class `RewriteSpecial` in case of problems)", | ||||
|         ]) | ||||
|             .SetClass("flex flex-col") | ||||
|             .AsMarkdown() | ||||
|  | @ -453,10 +449,10 @@ export default class SpecialVisualizations { | |||
|                                 assignTo: state.userRelatedState.language, | ||||
|                                 availableLanguages: languages, | ||||
|                                 preferredLanguages: state.osmConnection.userDetails.map( | ||||
|                                     (ud) => ud.languages | ||||
|                                     (ud) => ud.languages, | ||||
|                                 ), | ||||
|                             }) | ||||
|                         }) | ||||
|                         }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -495,7 +491,7 @@ export default class SpecialVisualizations { | |||
|                     state: SpecialVisualizationState, | ||||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     args: string[], | ||||
|                     feature: Feature | ||||
|                     feature: Feature, | ||||
|                 ): SvelteUIElement { | ||||
|                     return new SvelteUIElement(MinimapViz, { state, args, feature, tagSource }) | ||||
|                 }, | ||||
|  | @ -507,7 +503,7 @@ export default class SpecialVisualizations { | |||
| 
 | ||||
|                 constr( | ||||
|                     state: SpecialVisualizationState, | ||||
|                     tagSource: UIEventSource<Record<string, string>> | ||||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                 ): BaseUIElement { | ||||
|                     return new VariableUiElement( | ||||
|                         tagSource | ||||
|  | @ -517,7 +513,7 @@ export default class SpecialVisualizations { | |||
|                                     return new SvelteUIElement(SplitRoadWizard, { id, state }) | ||||
|                                 } | ||||
|                                 return undefined | ||||
|                             }) | ||||
|                             }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -531,7 +527,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     if (feature.geometry.type !== "Point") { | ||||
|                         return undefined | ||||
|  | @ -554,7 +550,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     if (!layer.deletion) { | ||||
|                         return undefined | ||||
|  | @ -582,7 +578,7 @@ export default class SpecialVisualizations { | |||
|                     state: SpecialVisualizationState, | ||||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature | ||||
|                     feature: Feature, | ||||
|                 ): BaseUIElement { | ||||
|                     const [lon, lat] = GeoOperations.centerpointCoordinates(feature) | ||||
|                     return new SvelteUIElement(CreateNewNote, { | ||||
|  | @ -645,7 +641,7 @@ export default class SpecialVisualizations { | |||
|                             .map((tags) => tags[args[0]]) | ||||
|                             .map((wikidata) => { | ||||
|                                 wikidata = Utils.NoEmpty( | ||||
|                                     wikidata?.split(";")?.map((wd) => wd.trim()) ?? [] | ||||
|                                     wikidata?.split(";")?.map((wd) => wd.trim()) ?? [], | ||||
|                                 )[0] | ||||
|                                 const entry = Wikidata.LoadWikidataEntry(wikidata) | ||||
|                                 return new VariableUiElement( | ||||
|  | @ -655,9 +651,9 @@ export default class SpecialVisualizations { | |||
|                                         } | ||||
|                                         const response = <WikidataResponse>e["success"] | ||||
|                                         return Translation.fromMap(response.labels) | ||||
|                                     }) | ||||
|                                     }), | ||||
|                                 ) | ||||
|                             }) | ||||
|                             }), | ||||
|                     ), | ||||
|             }, | ||||
|             new MapillaryLinkVis(), | ||||
|  | @ -671,7 +667,7 @@ export default class SpecialVisualizations { | |||
|                     tags: UIEventSource<Record<string, string>>, | ||||
|                     _, | ||||
|                     __, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ) => new SvelteUIElement(AllTagsPanel, { tags, layer }), | ||||
|             }, | ||||
|             { | ||||
|  | @ -693,7 +689,7 @@ export default class SpecialVisualizations { | |||
|                     return new ImageCarousel( | ||||
|                         AllImageProviders.LoadImagesFor(tags, imagePrefixes), | ||||
|                         tags, | ||||
|                         state | ||||
|                         state, | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -714,7 +710,7 @@ export default class SpecialVisualizations { | |||
|                     }, | ||||
|                 ], | ||||
|                 constr: (state, tags, args) => { | ||||
|                         const targetKey = args[0] === "" ? undefined : args[0] | ||||
|                     const targetKey = args[0] === "" ? undefined : args[0] | ||||
|                     return new SvelteUIElement(UploadImage, { | ||||
|                         state, | ||||
|                         tags, | ||||
|  | @ -750,7 +746,7 @@ export default class SpecialVisualizations { | |||
|                             nameKey: nameKey, | ||||
|                             fallbackName, | ||||
|                         }, | ||||
|                         state.featureSwitchIsTesting | ||||
|                         state.featureSwitchIsTesting, | ||||
|                     ) | ||||
|                     return new SvelteUIElement(StarsBarIcon, { | ||||
|                         score: reviews.average, | ||||
|  | @ -784,7 +780,7 @@ export default class SpecialVisualizations { | |||
|                             nameKey: nameKey, | ||||
|                             fallbackName, | ||||
|                         }, | ||||
|                         state.featureSwitchIsTesting | ||||
|                         state.featureSwitchIsTesting, | ||||
|                     ) | ||||
|                     return new SvelteUIElement(ReviewForm, { reviews, state, tags, feature, layer }) | ||||
|                 }, | ||||
|  | @ -815,7 +811,7 @@ export default class SpecialVisualizations { | |||
|                             nameKey: nameKey, | ||||
|                             fallbackName, | ||||
|                         }, | ||||
|                         state.featureSwitchIsTesting | ||||
|                         state.featureSwitchIsTesting, | ||||
|                     ) | ||||
|                     return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer }) | ||||
|                 }, | ||||
|  | @ -841,7 +837,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     args: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new Combine([ | ||||
|                         SpecialVisualizations.specialVisualisationsDict["create_review"].constr( | ||||
|  | @ -849,14 +845,14 @@ export default class SpecialVisualizations { | |||
|                             tagSource, | ||||
|                             args, | ||||
|                             feature, | ||||
|                             layer | ||||
|                             layer, | ||||
|                         ), | ||||
|                         SpecialVisualizations.specialVisualisationsDict["list_reviews"].constr( | ||||
|                             state, | ||||
|                             tagSource, | ||||
|                             args, | ||||
|                             feature, | ||||
|                             layer | ||||
|                             layer, | ||||
|                         ), | ||||
|                     ]) | ||||
|                 }, | ||||
|  | @ -874,7 +870,7 @@ export default class SpecialVisualizations { | |||
|                 constr( | ||||
|                     state: SpecialVisualizationState, | ||||
|                     _: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[] | ||||
|                     argument: string[], | ||||
|                 ): BaseUIElement { | ||||
|                     const [text] = argument | ||||
|                     return new SvelteUIElement(ImportReviewIdentity, { state, text }) | ||||
|  | @ -931,7 +927,7 @@ export default class SpecialVisualizations { | |||
|                 constr( | ||||
|                     state: SpecialVisualizationState, | ||||
|                     tags: UIEventSource<Record<string, string>>, | ||||
|                     args: string[] | ||||
|                     args: string[], | ||||
|                 ): SvelteUIElement { | ||||
|                     const keyToUse = args[0] | ||||
|                     const prefix = args[1] | ||||
|  | @ -968,17 +964,17 @@ export default class SpecialVisualizations { | |||
|                                     return undefined | ||||
|                                 } | ||||
|                                 const allUnits: Unit[] = [].concat( | ||||
|                                     ...(state?.layout?.layers?.map((lyr) => lyr.units) ?? []) | ||||
|                                     ...(state?.layout?.layers?.map((lyr) => lyr.units) ?? []), | ||||
|                                 ) | ||||
|                                 const unit = allUnits.filter((unit) => | ||||
|                                     unit.isApplicableToKey(key) | ||||
|                                     unit.isApplicableToKey(key), | ||||
|                                 )[0] | ||||
|                                 if (unit === undefined) { | ||||
|                                     return value | ||||
|                                 } | ||||
|                                 const getCountry = () => tagSource.data._country | ||||
|                                 return unit.asHumanLongValue(value, getCountry) | ||||
|                             }) | ||||
|                             }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -995,7 +991,7 @@ export default class SpecialVisualizations { | |||
|                         new Combine([ | ||||
|                             t.downloadFeatureAsGeojson.SetClass("font-bold text-lg"), | ||||
|                             t.downloadGeoJsonHelper.SetClass("subtle"), | ||||
|                         ]).SetClass("flex flex-col") | ||||
|                         ]).SetClass("flex flex-col"), | ||||
|                     ) | ||||
|                         .onClick(() => { | ||||
|                             console.log("Exporting as Geojson") | ||||
|  | @ -1008,7 +1004,7 @@ export default class SpecialVisualizations { | |||
|                                 title + "_mapcomplete_export.geojson", | ||||
|                                 { | ||||
|                                     mimetype: "application/vnd.geo+json", | ||||
|                                 } | ||||
|                                 }, | ||||
|                             ) | ||||
|                         }) | ||||
|                         .SetClass("w-full") | ||||
|  | @ -1044,7 +1040,7 @@ export default class SpecialVisualizations { | |||
|                 constr: (state) => { | ||||
|                     return new SubtleButton( | ||||
|                         new SvelteUIElement(Trash).SetClass("h-6"), | ||||
|                         Translations.t.general.removeLocationHistory | ||||
|                         Translations.t.general.removeLocationHistory, | ||||
|                     ).onClick(() => { | ||||
|                         state.historicalUserLocations.features.setData([]) | ||||
|                         state.selectedElement.setData(undefined) | ||||
|  | @ -1081,11 +1077,11 @@ export default class SpecialVisualizations { | |||
|                                     comments | ||||
|                                         .filter((c) => c.text !== "") | ||||
|                                         .map( | ||||
|                                             (c, i) => | ||||
|                                                 new NoteCommentElement(c, state, i, comments.length) | ||||
|                                         ) | ||||
|                                             (comment) => | ||||
|                                                 new SvelteUIElement(NoteCommentElement, { comment, state }), | ||||
|                                         ), | ||||
|                                 ).SetClass("flex flex-col") | ||||
|                             }) | ||||
|                             }), | ||||
|                     ), | ||||
|             }, | ||||
|             { | ||||
|  | @ -1103,7 +1099,7 @@ export default class SpecialVisualizations { | |||
|                 constr: (state, tags, args, feature, layer) => { | ||||
|                     const id = tags.data[args[0] ?? "id"] | ||||
|                     tags = state.featureProperties.getStore(id) | ||||
|                     return new SvelteUIElement(UploadImage, { state, tags, layer  }) | ||||
|                     return new SvelteUIElement(UploadImage, { state, tags, layer }) | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|  | @ -1118,7 +1114,7 @@ export default class SpecialVisualizations { | |||
|                     tagsSource: UIEventSource<Record<string, string>>, | ||||
|                     _: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ) => | ||||
|                     new VariableUiElement( | ||||
|                         tagsSource.map((tags) => { | ||||
|  | @ -1138,7 +1134,7 @@ export default class SpecialVisualizations { | |||
|                             }) | ||||
|                                 .SetClass("px-1") | ||||
|                                 .setSpan() | ||||
|                         }) | ||||
|                         }), | ||||
|                     ), | ||||
|             }, | ||||
|             { | ||||
|  | @ -1154,8 +1150,8 @@ export default class SpecialVisualizations { | |||
|                     const challenge = Stores.FromPromise( | ||||
|                         Utils.downloadJsonCached<MaprouletteTask>( | ||||
|                             `${Maproulette.defaultEndpoint}/challenge/${parentId}`, | ||||
|                             24 * 60 * 60 * 1000 | ||||
|                         ) | ||||
|                             24 * 60 * 60 * 1000, | ||||
|                         ), | ||||
|                     ) | ||||
| 
 | ||||
|                     return new VariableUiElement( | ||||
|  | @ -1180,7 +1176,7 @@ export default class SpecialVisualizations { | |||
|                             } else { | ||||
|                                 return [title, new List(listItems)] | ||||
|                             } | ||||
|                         }) | ||||
|                         }), | ||||
|                     ) | ||||
|                 }, | ||||
|                 docs: "Fetches the metadata of MapRoulette campaign that this task is part of and shows those details (namely `title`, `description` and `instruction`).\n\nThis reads the property `mr_challengeId` to detect the parent campaign.", | ||||
|  | @ -1194,15 +1190,15 @@ export default class SpecialVisualizations { | |||
|                     "\n" + | ||||
|                     "```json\n" + | ||||
|                     "{\n" + | ||||
|                     '   "id": "mark_duplicate",\n' + | ||||
|                     '   "render": {\n' + | ||||
|                     '      "special": {\n' + | ||||
|                     '         "type": "maproulette_set_status",\n' + | ||||
|                     '         "message": {\n' + | ||||
|                     '            "en": "Mark as not found or false positive"\n' + | ||||
|                     "   \"id\": \"mark_duplicate\",\n" + | ||||
|                     "   \"render\": {\n" + | ||||
|                     "      \"special\": {\n" + | ||||
|                     "         \"type\": \"maproulette_set_status\",\n" + | ||||
|                     "         \"message\": {\n" + | ||||
|                     "            \"en\": \"Mark as not found or false positive\"\n" + | ||||
|                     "         },\n" + | ||||
|                     '         "status": "2",\n' + | ||||
|                     '         "image": "close"\n' + | ||||
|                     "         \"status\": \"2\",\n" + | ||||
|                     "         \"image\": \"close\"\n" + | ||||
|                     "      }\n" + | ||||
|                     "   }\n" + | ||||
|                     "}\n" + | ||||
|  | @ -1278,7 +1274,7 @@ export default class SpecialVisualizations { | |||
|                                 (l) => | ||||
|                                     l.name !== null && | ||||
|                                     l.title && | ||||
|                                     state.perLayer.get(l.id) !== undefined | ||||
|                                     state.perLayer.get(l.id) !== undefined, | ||||
|                             ) | ||||
|                             .map( | ||||
|                                 (l) => { | ||||
|  | @ -1288,8 +1284,8 @@ export default class SpecialVisualizations { | |||
|                                     const fsBboxed = new BBoxFeatureSourceForLayer(fs, bbox) | ||||
|                                     return new StatisticsPanel(fsBboxed) | ||||
|                                 }, | ||||
|                                 [state.mapProperties.bounds] | ||||
|                             ) | ||||
|                                 [state.mapProperties.bounds], | ||||
|                             ), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1359,7 +1355,7 @@ export default class SpecialVisualizations { | |||
|                 constr( | ||||
|                     state: SpecialVisualizationState, | ||||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     args: string[] | ||||
|                     args: string[], | ||||
|                 ): SvelteUIElement { | ||||
|                     let [text, href, classnames, download, ariaLabel, icon] = args | ||||
|                     if (download === "") { | ||||
|  | @ -1397,7 +1393,7 @@ export default class SpecialVisualizations { | |||
|                             }, | ||||
|                         }, | ||||
|                         null, | ||||
|                         "  " | ||||
|                         "  ", | ||||
|                     ) + | ||||
|                     "\n```", | ||||
|                 args: [ | ||||
|  | @ -1421,7 +1417,7 @@ export default class SpecialVisualizations { | |||
|                     featureTags: UIEventSource<Record<string, string>>, | ||||
|                     args: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ) { | ||||
|                     const [key, tr, classesRaw] = args | ||||
|                     let classes = classesRaw ?? "" | ||||
|  | @ -1439,7 +1435,7 @@ export default class SpecialVisualizations { | |||
|                                     "Could not create a special visualization for multi(", | ||||
|                                     args.join(", ") + ")", | ||||
|                                     "no properties found for object", | ||||
|                                     feature.properties.id | ||||
|                                     feature.properties.id, | ||||
|                                 ) | ||||
|                                 return undefined | ||||
|                             } | ||||
|  | @ -1455,7 +1451,7 @@ export default class SpecialVisualizations { | |||
|                                 elements.push(subsTr) | ||||
|                             } | ||||
|                             return elements | ||||
|                         }) | ||||
|                         }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1475,7 +1471,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new VariableUiElement( | ||||
|                         tagSource.map((tags) => { | ||||
|  | @ -1487,7 +1483,7 @@ export default class SpecialVisualizations { | |||
|                                 console.error("Cannot create a translation for", v, "due to", e) | ||||
|                                 return JSON.stringify(v) | ||||
|                             } | ||||
|                         }) | ||||
|                         }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1507,7 +1503,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const key = argument[0] | ||||
|                     const validator = new FediverseValidator() | ||||
|  | @ -1517,7 +1513,7 @@ export default class SpecialVisualizations { | |||
|                             .map((fediAccount) => { | ||||
|                                 fediAccount = validator.reformat(fediAccount) | ||||
|                                 const [_, username, host] = fediAccount.match( | ||||
|                                     FediverseValidator.usernameAtServer | ||||
|                                     FediverseValidator.usernameAtServer, | ||||
|                                 ) | ||||
| 
 | ||||
|                                 const normalLink = new SvelteUIElement(Link, { | ||||
|  | @ -1529,10 +1525,10 @@ export default class SpecialVisualizations { | |||
|                                 const loggedInContributorMastodon = | ||||
|                                     state.userRelatedState?.preferencesAsTags?.data?.[ | ||||
|                                         "_mastodon_link" | ||||
|                                     ] | ||||
|                                         ] | ||||
|                                 console.log( | ||||
|                                     "LoggedinContributorMastodon", | ||||
|                                     loggedInContributorMastodon | ||||
|                                     loggedInContributorMastodon, | ||||
|                                 ) | ||||
|                                 if (!loggedInContributorMastodon) { | ||||
|                                     return normalLink | ||||
|  | @ -1548,7 +1544,7 @@ export default class SpecialVisualizations { | |||
|                                         newTab: true, | ||||
|                                     }).SetClass("button"), | ||||
|                                 ]) | ||||
|                             }) | ||||
|                             }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1568,7 +1564,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     args: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new FixedUiElement("{" + args[0] + "}") | ||||
|                 }, | ||||
|  | @ -1589,7 +1585,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const key = argument[0] ?? "value" | ||||
|                     return new VariableUiElement( | ||||
|  | @ -1607,12 +1603,12 @@ export default class SpecialVisualizations { | |||
|                             } catch (e) { | ||||
|                                 return new FixedUiElement( | ||||
|                                     "Could not parse this tag: " + | ||||
|                                         JSON.stringify(value) + | ||||
|                                         " due to " + | ||||
|                                         e | ||||
|                                     JSON.stringify(value) + | ||||
|                                     " due to " + | ||||
|                                     e, | ||||
|                                 ).SetClass("alert") | ||||
|                             } | ||||
|                         }) | ||||
|                         }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1633,7 +1629,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const giggityUrl = argument[0] | ||||
|                     return new SvelteUIElement(Giggity, { tags: tagSource, state, giggityUrl }) | ||||
|  | @ -1649,12 +1645,12 @@ export default class SpecialVisualizations { | |||
|                     _: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const tags = (<ThemeViewState>( | ||||
|                         state | ||||
|                     )).geolocation.currentUserLocation.features.map( | ||||
|                         (features) => features[0]?.properties | ||||
|                         (features) => features[0]?.properties, | ||||
|                     ) | ||||
|                     return new Combine([ | ||||
|                         new SvelteUIElement(OrientationDebugPanel, {}), | ||||
|  | @ -1676,7 +1672,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new SvelteUIElement(MarkAsFavourite, { | ||||
|                         tags: tagSource, | ||||
|  | @ -1696,7 +1692,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new SvelteUIElement(MarkAsFavouriteMini, { | ||||
|                         tags: tagSource, | ||||
|  | @ -1716,7 +1712,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new SvelteUIElement(DirectionIndicator, { state, feature }) | ||||
|                 }, | ||||
|  | @ -1729,7 +1725,7 @@ export default class SpecialVisualizations { | |||
|                     state: SpecialVisualizationState, | ||||
|                     tags: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature | ||||
|                     feature: Feature, | ||||
|                 ): SvelteUIElement { | ||||
|                     return new SvelteUIElement(QrCode, { state, tags, feature }) | ||||
|                 }, | ||||
|  | @ -1748,7 +1744,7 @@ export default class SpecialVisualizations { | |||
|                 constr( | ||||
|                     state: SpecialVisualizationState, | ||||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     args: string[] | ||||
|                     args: string[], | ||||
|                 ): BaseUIElement { | ||||
|                     const key = args[0] === "" ? "_direction:centerpoint" : args[0] | ||||
|                     return new VariableUiElement( | ||||
|  | @ -1759,11 +1755,11 @@ export default class SpecialVisualizations { | |||
|                             }) | ||||
|                             .mapD((value) => { | ||||
|                                 const dir = GeoOperations.bearingToHuman( | ||||
|                                     GeoOperations.parseBearing(value) | ||||
|                                     GeoOperations.parseBearing(value), | ||||
|                                 ) | ||||
|                                 console.log("Human dir", dir) | ||||
|                                 return Translations.t.general.visualFeedback.directionsAbsolute[dir] | ||||
|                             }) | ||||
|                             }), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1793,7 +1789,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     args: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const url = args[0] | ||||
|                     const readonly = args[3] === "yes" | ||||
|  | @ -1819,12 +1815,12 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     args: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new Toggle( | ||||
|                         undefined, | ||||
|                         new SvelteUIElement(LoginButton, { osmConnection: state.osmConnection }), | ||||
|                         state.osmConnection.isLoggedIn | ||||
|                         state.osmConnection.isLoggedIn, | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1862,7 +1858,7 @@ export default class SpecialVisualizations { | |||
|                     tags: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const key = argument[0] ?? "website" | ||||
|                     const useProxy = argument[1] !== "no" | ||||
|  | @ -1889,11 +1885,11 @@ export default class SpecialVisualizations { | |||
|                                             const features = | ||||
|                                                 await LinkedDataLoader.fetchVeloparkEntry( | ||||
|                                                     url, | ||||
|                                                     loadAll | ||||
|                                                     loadAll, | ||||
|                                                 ) | ||||
|                                             const feature = | ||||
|                                                 features.find( | ||||
|                                                     (f) => f.properties["ref:velopark"] === url | ||||
|                                                     (f) => f.properties["ref:velopark"] === url, | ||||
|                                                 ) ?? features[0] | ||||
|                                             const properties = feature.properties | ||||
|                                             properties["ref:velopark"] = url | ||||
|  | @ -1903,7 +1899,7 @@ export default class SpecialVisualizations { | |||
|                                             console.error(e) | ||||
|                                             throw e | ||||
|                                         } | ||||
|                                     })() | ||||
|                                     })(), | ||||
|                                 ) | ||||
|                             } | ||||
|                             return Stores.FromPromiseWithErr( | ||||
|  | @ -1912,27 +1908,27 @@ export default class SpecialVisualizations { | |||
|                                         return await LinkedDataLoader.fetchJsonLd( | ||||
|                                             url, | ||||
|                                             { country }, | ||||
|                                             useProxy ? "proxy" : "fetch-lod" | ||||
|                                             useProxy ? "proxy" : "fetch-lod", | ||||
|                                         ) | ||||
|                                     } catch (e) { | ||||
|                                         console.log( | ||||
|                                             "Could not get with proxy/download LOD, attempting to download directly. Error for ", | ||||
|                                             url, | ||||
|                                             "is", | ||||
|                                             e | ||||
|                                             e, | ||||
|                                         ) | ||||
|                                         return await LinkedDataLoader.fetchJsonLd( | ||||
|                                             url, | ||||
|                                             { country }, | ||||
|                                             "fetch-raw" | ||||
|                                             "fetch-raw", | ||||
|                                         ) | ||||
|                                     } | ||||
|                                 })() | ||||
|                                 })(), | ||||
|                             ) | ||||
|                         }) | ||||
| 
 | ||||
|                     externalData.addCallbackAndRunD((lod) => | ||||
|                         console.log("linked_data_from_website received the following data:", lod) | ||||
|                         console.log("linked_data_from_website received the following data:", lod), | ||||
|                     ) | ||||
| 
 | ||||
|                     return new Toggle( | ||||
|  | @ -1947,7 +1943,7 @@ export default class SpecialVisualizations { | |||
|                             collapsed: isClosed, | ||||
|                         }), | ||||
|                         undefined, | ||||
|                         url.map((url) => !!url) | ||||
|                         url.map((url) => !!url), | ||||
|                     ) | ||||
|                 }, | ||||
|             }, | ||||
|  | @ -1967,7 +1963,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const text = argument[0] | ||||
|                     const cssClasses = argument[1] | ||||
|  | @ -1989,7 +1985,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     const translation = tagSource.map((tags) => { | ||||
|                         const layer = state.layout.getMatchingLayer(tags) | ||||
|  | @ -2007,7 +2003,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): BaseUIElement { | ||||
|                     return new SvelteUIElement(PendingChangesIndicator, { state, compact: false }) | ||||
|                 }, | ||||
|  | @ -2027,7 +2023,7 @@ export default class SpecialVisualizations { | |||
|                     tagSource: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     feature: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): SvelteUIElement { | ||||
|                     return new SvelteUIElement<any, any, any>(ClearCaches, { | ||||
|                         msg: argument[0] ?? "Clear local caches", | ||||
|  | @ -2052,7 +2048,7 @@ export default class SpecialVisualizations { | |||
|                     tags: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     selectedElement: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): SvelteUIElement { | ||||
|                     const [header, labelsStr] = argument | ||||
|                     const labels = labelsStr.split(";").map((x) => x.trim()) | ||||
|  | @ -2075,7 +2071,7 @@ export default class SpecialVisualizations { | |||
|                     tags: UIEventSource<Record<string, string>>, | ||||
|                     argument: string[], | ||||
|                     selectedElement: Feature, | ||||
|                     layer: LayerConfig | ||||
|                     layer: LayerConfig, | ||||
|                 ): SvelteUIElement { | ||||
|                     const t = Translations.t.preset_type | ||||
|                     const question: QuestionableTagRenderingConfigJson = { | ||||
|  | @ -2101,22 +2097,22 @@ export default class SpecialVisualizations { | |||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 funcName:"clear_all", | ||||
|                 funcName: "clear_all", | ||||
|                 docs: "Clears all user preferences", | ||||
|                 needsUrls: [], | ||||
|                 args: [ | ||||
|                     { | ||||
|                         name: "text", | ||||
|                         doc: "Text to show on the button" | ||||
|                     } | ||||
|                         doc: "Text to show on the button", | ||||
|                     }, | ||||
|                 ], | ||||
|                 constr(state: SpecialVisualizationState, tagSource: UIEventSource<Record<string, string>>, argument: string[], feature: Feature, layer: LayerConfig): BaseUIElement { | ||||
|                     const text = argument[0] | ||||
|                     return new SubtleButton(undefined, text).onClick(() => { | ||||
|                         state.osmConnection.preferencesHandler.ClearPreferences() | ||||
|                     }) | ||||
|                 } | ||||
|             } | ||||
|                 }, | ||||
|             }, | ||||
|         ] | ||||
| 
 | ||||
|         specialVisualizations.push(new AutoApplyButton(specialVisualizations)) | ||||
|  | @ -2131,7 +2127,7 @@ export default class SpecialVisualizations { | |||
|                 "Invalid special visualisation found: funcName is undefined or doesn't match " + | ||||
|                 regex + | ||||
|                 invalid.map((sp) => sp.i).join(", ") + | ||||
|                 '. Did you perhaps type \n  funcName: "funcname" // type declaration uses COLON\ninstead of:\n  funcName = "funcName" // value definition uses EQUAL' | ||||
|                 ". Did you perhaps type \n  funcName: \"funcname\" // type declaration uses COLON\ninstead of:\n  funcName = \"funcName\" // value definition uses EQUAL" | ||||
|             ) | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue