chore: automated housekeeping...

This commit is contained in:
Pieter Vander Vennet 2024-11-07 11:19:15 +01:00
parent a2dd79c4ec
commit 7b792af261
101 changed files with 2196 additions and 22043 deletions

View file

@ -13,7 +13,7 @@
/**
* Default: 50
*/
export let zIndex : string = "z-50"
export let zIndex: string = "z-50"
const shared =
"in-page normal-background dark:bg-gray-800 rounded-lg border-gray-200 dark:border-gray-700 border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 shadow-md"
@ -21,7 +21,7 @@
if (fullscreen) {
defaultClass = shared
}
let dialogClass = "fixed top-0 start-0 end-0 h-modal inset-0 w-full p-4 flex "+zIndex
let dialogClass = "fixed top-0 start-0 end-0 h-modal inset-0 w-full p-4 flex " + zIndex
if (fullscreen) {
dialogClass += " h-full-child"
}

View file

@ -47,7 +47,7 @@
{resource.resolved?.description}
{#if resource.languageCodes?.indexOf($language) >= 0}
<div class="thanks w-fit">
<Tr t={availableTranslation}/>
<Tr t={availableTranslation} />
</div>
{/if}
</div>

View file

@ -23,7 +23,14 @@
let isDisplayed: UIEventSource<boolean> = filteredLayer.isDisplayed
let isDebugging = state?.featureSwitches?.featureSwitchIsDebugging ?? new ImmutableStore(false)
let showTags = state?.userRelatedState?.showTags?.map(s => (s === "yes" && state?.userRelatedState?.osmConnection?.userDetails?.data?.csCount >= Constants.userJourney.tagsVisibleAt) || s === "always" || s === "full")
let showTags = state?.userRelatedState?.showTags?.map(
(s) =>
(s === "yes" &&
state?.userRelatedState?.osmConnection?.userDetails?.data?.csCount >=
Constants.userJourney.tagsVisibleAt) ||
s === "always" ||
s === "full"
)
/**
* Gets a UIEventSource as boolean for the given option, to be used with a checkbox
@ -33,7 +40,7 @@
return state.sync(
(f) => f === 0,
[],
(b) => (b ? 0 : undefined),
(b) => (b ? 0 : undefined)
)
}
@ -72,7 +79,6 @@
<span class="subtle">
{filter.options[0].osmTags.asHumanString()}
</span>
</Checkbox>
{/if}
@ -89,7 +95,7 @@
{/if}
<Tr t={option.question} />
{#if $showTags && option.osmTags !== undefined}
&nbsp;({option.osmTags.asHumanString()})
&nbsp;({option.osmTags.asHumanString()})
{/if}
</option>
{/each}

View file

@ -37,12 +37,12 @@
if (!shown) {
previewedImage.set(undefined)
}
}),
})
)
onDestroy(
previewedImage.addCallbackAndRun((previewedImage) => {
showBigPreview.set(previewedImage?.id === image.id)
}),
})
)
function highlight(entered: boolean = true) {
@ -129,8 +129,6 @@
<MagnifyingGlassPlusIcon class="h-8 w-8 cursor-zoom-in pl-3 pb-3" color="white" />
</div>
{/if}
</div>
<div class="absolute bottom-0 left-0">
<ImageAttribution {image} {attributionFormat} />

View file

@ -23,11 +23,13 @@
export let state: SpecialVisualizationState
export let tags: UIEventSource<Record<string, string>>
let showDeleteDialog = new UIEventSource(false)
onDestroy(showDeleteDialog.addCallbackAndRunD(shown => {
if (shown) {
state.previewedImage.set(undefined)
}
}))
onDestroy(
showDeleteDialog.addCallbackAndRunD((shown) => {
if (shown) {
state.previewedImage.set(undefined)
}
})
)
let reportReason = new UIEventSource<ReportReason>(REPORT_REASONS[0])
let reportFreeText = new UIEventSource<string>(undefined)
@ -58,12 +60,10 @@
async function unlink() {
await state?.changes?.applyAction(
new ChangeTagAction(tags.data.id,
new Tag(image.key, ""),
tags.data, {
changeType: "delete-image",
theme: state.theme.id,
}),
new ChangeTagAction(tags.data.id, new Tag(image.key, ""), tags.data, {
changeType: "delete-image",
theme: state.theme.id,
})
)
}
@ -72,23 +72,21 @@
const placeholder = t.placeholder.current
</script>
<Popup shown={showDeleteDialog}>
<Tr slot="header" t={tu.title} />
<div class="flex flex-col sm:flex-row gap-x-4">
<div class="flex flex-col gap-x-4 sm:flex-row">
<img class="w-32 sm:w-64" src={image.url} />
<div>
<div class="flex flex-col justify-between h-full">
<div class="flex h-full flex-col justify-between">
<Tr t={tu.explanation} />
{#if $reported}
<Tr cls="thanks p-2" t={t.deletionRequested} />
{:else if image.provider.name === "panoramax"}
<div class="my-4">
<AccordionSingle noBorder>
<div slot="header" class="text-sm flex">Report inappropriate picture</div>
<div class="interactive p-2 flex flex-col">
<div slot="header" class="flex text-sm">Report inappropriate picture</div>
<div class="interactive flex flex-col p-2">
<h3>
<Tr t={t.title} />
</h3>
@ -118,71 +116,57 @@
placeholder={$placeholder}
/>
<button class="primary self-end" class:disabled={$reportReason === "other" && !$reportFreeText}
on:click={() => requestDeletion()}>
<button
class="primary self-end"
class:disabled={$reportReason === "other" && !$reportFreeText}
on:click={() => requestDeletion()}
>
<Tr t={t.requestDeletion} />
</button>
</div>
</AccordionSingle>
</div>
{/if}
</div>
</div>
</div>
<div slot="footer" class="flex justify-end flex-wrap">
<div slot="footer" class="flex flex-wrap justify-end">
<button on:click={() => showDeleteDialog.set(false)}>
<Tr t={Translations.t.general.cancel} />
</button>
<NextButton clss={"primary "+($reported ? "disabled" : "") } on:click={() => unlink()}>
<TrashIcon class="w-6 h-6 mr-2" />
<NextButton clss={"primary " + ($reported ? "disabled" : "")} on:click={() => unlink()}>
<TrashIcon class="mr-2 h-6 w-6" />
<Tr t={tu.button} />
</NextButton>
</div>
</Popup>
<div
class="w-fit shrink-0 relative"
style="scroll-snap-align: start"
>
<div class="relative bg-gray-200 max-w-max flex items-center">
<div class="relative w-fit shrink-0" style="scroll-snap-align: start">
<div class="relative flex max-w-max items-center bg-gray-200">
<AttributedImage
imgClass="carousel-max-height"
{image}
{state}
previewedImage={state?.previewedImage}
>
<svelte:fragment slot="dot-menu-actions">
<button on:click={() => ImageProvider.offerImageAsDownload(image)}>
<DownloadIcon />
<Tr t={Translations.t.general.download.downloadImage} />
</button>
<button
on:click={() => showDeleteDialog.set(true)}
class="flex items-center"
>
<button on:click={() => showDeleteDialog.set(true)} class="flex items-center">
<TrashIcon />
<Tr t={tu.button} />
</button>
</svelte:fragment>
</AttributedImage>
</div>
</div>
<style>
:global(.carousel-max-height) {
max-height: var(--image-carousel-height);
}
:global(.carousel-max-height) {
max-height: var(--image-carousel-height);
}
</style>

View file

@ -7,14 +7,10 @@
export let images: Store<ProvidedImage[]>
export let state: SpecialVisualizationState
export let tags: Store<Record<string, string>>
</script>
<div class="flex w-full space-x-2 overflow-x-auto" style="scroll-snap-type: x proximity">
{#each $images as image (image.url)}
<DeletableImage {image} {state} {tags}/>
<DeletableImage {image} {state} {tags} />
{/each}
</div>

View file

@ -19,7 +19,6 @@
export let clss: string = undefined
let isLoaded = new UIEventSource(false)
</script>
<div class={twMerge("relative h-full w-full", clss)}>
@ -36,12 +35,11 @@
<slot name="dot-menu-actions">
<button
class="no-image-background pointer-events-auto flex items-center"
on:click={() => ImageProvider.offerImageAsDownload(image)}
on:click={() => ImageProvider.offerImageAsDownload(image)}
>
<DownloadIcon class="h-6 w-6 px-2 opacity-100" />
<Tr t={Translations.t.general.download.downloadImage} />
</button>
</slot>
</DotMenu>
<div

View file

@ -18,11 +18,11 @@ export default class FediverseValidator extends Validator {
*/
public static extractServer(handle: string): { server: string; username: string } {
const match = handle?.match(this.usernameAtServer)
if(!match){
if (!match) {
return undefined
}
const [_, username, server] = match
return {username, server}
return { username, server }
}
/**
@ -36,7 +36,7 @@ export default class FediverseValidator extends Validator {
const url = new URL(s)
const path = url.pathname
if (path.match(/^\/@?\w+$/)) {
return `${path.substring(1)}@${url.hostname}`;
return `${path.substring(1)}@${url.hostname}`
}
} catch (e) {
// Nothing to do here

View file

@ -1,5 +1,4 @@
<script lang="ts">
import ArrowDownTray from "@babeard/svelte-heroicons/mini/ArrowDownTray"
import Tr from "../Base/Tr.svelte"
import Translations from "../i18n/Translations"
@ -20,23 +19,21 @@
export let extension: string
export let maintext: Translation
export let helpertext: Translation
export let construct: (feature: Feature, title: string) => (Blob | string)
export let construct: (feature: Feature, title: string) => Blob | string
function exportGpx() {
console.log("Exporting as GPX!")
const tgs = tags.data
const title = layer.title?.GetRenderValue(tgs)?.Subs(tgs)?.txt ?? "gpx_track"
const data = construct(feature, title)
Utils.offerContentsAsDownloadableFile(data, title + "_mapcomplete_export."+extension, {
Utils.offerContentsAsDownloadableFile(data, title + "_mapcomplete_export." + extension, {
mimetype,
})
}
</script>
<button class="w-full" on:click={() => exportGpx()}>
<ArrowDownTray class="w-11 h-11 mr-2"/>
<div class="flex flex-col items-start w-full">
<ArrowDownTray class="mr-2 h-11 w-11" />
<div class="flex w-full flex-col items-start">
<Tr t={maintext} cls="font-bold text-lg" />
<Tr t={helpertext} cls="subtle text-start" />
</div>

View file

@ -9,23 +9,25 @@
export let tags: Store<Record<string, string>>
export let state: SpecialVisualizationState
const validator = new FediverseValidator()
const userinfo = tags.mapD(t => t[key]).mapD(fediAccount => {
return FediverseValidator.extractServer(validator.reformat(fediAccount))
})
const homeLocation: Store<string> = state.userRelatedState?.preferencesAsTags.mapD(prefs => prefs["_mastodon_link"])
.mapD(userhandle => FediverseValidator.extractServer(validator.reformat(userhandle))?.server)
const userinfo = tags
.mapD((t) => t[key])
.mapD((fediAccount) => {
return FediverseValidator.extractServer(validator.reformat(fediAccount))
})
const homeLocation: Store<string> = state.userRelatedState?.preferencesAsTags
.mapD((prefs) => prefs["_mastodon_link"])
.mapD((userhandle) => FediverseValidator.extractServer(validator.reformat(userhandle))?.server)
</script>
<div class="flex flex-col w-full">
<a href={ "https://" + $userinfo.server + "/@" + $userinfo.username} target="_blank">@{$userinfo.username}
@{$userinfo.server} </a>
{#if $homeLocation !== undefined}
<a target="_blank" href={"https://"+$homeLocation+"/"}>
<Tr t={ Translations.t.validation.fediverse.onYourServer} />
<div class="flex w-full flex-col">
<a href={"https://" + $userinfo.server + "/@" + $userinfo.username} target="_blank">
@{$userinfo.username}
@{$userinfo.server}
</a>
{/if}
{#if $homeLocation !== undefined}
<a target="_blank" href={"https://" + $homeLocation + "/"}>
<Tr t={Translations.t.validation.fediverse.onYourServer} />
</a>
{/if}
</div>

View file

@ -554,10 +554,7 @@
</div>
</Popup>
<div
class="sticky bottom-0 flex flex-wrap justify-between"
style="z-index: 11"
>
<div class="sticky bottom-0 flex flex-wrap justify-between" style="z-index: 11">
{#if $settableKeys && $isKnown && !matchesEmpty}
<button class="as-link small text-sm" on:click={() => unknownModal.set(true)}>
<Tr t={Translations.t.unknown.markUnknown} />

View file

@ -2,7 +2,11 @@ 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"
@ -120,7 +124,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"
@ -187,7 +191,7 @@ class StealViz implements SpecialVisualization {
selectedElement: otherFeature,
state,
layer,
}),
})
)
}
if (elements.length === 1) {
@ -195,8 +199,8 @@ class StealViz implements SpecialVisualization {
}
return new Combine(elements).SetClass("flex flex-col")
},
[state.indexedFeatures.featuresById],
),
[state.indexedFeatures.featuresById]
)
)
}
@ -248,11 +252,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, {
@ -293,7 +297,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(";")
@ -325,7 +329,7 @@ export default class SpecialVisualizations {
for (const specialVisualization of SpecialVisualizations.specialVisualizations) {
SpecialVisualizations.specialVisualisationsDict.set(
specialVisualization.funcName,
specialVisualization,
specialVisualization
)
}
}
@ -345,15 +349,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>",
@ -362,18 +366,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([
@ -406,10 +410,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()
@ -447,10 +451,10 @@ export default class SpecialVisualizations {
assignTo: state.userRelatedState.language,
availableLanguages: languages,
preferredLanguages: state.osmConnection.userDetails.map(
(ud) => ud.languages,
(ud) => ud.languages
),
})
}),
})
)
},
},
@ -489,7 +493,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 })
},
@ -501,7 +505,7 @@ export default class SpecialVisualizations {
constr(
state: SpecialVisualizationState,
tagSource: UIEventSource<Record<string, string>>,
tagSource: UIEventSource<Record<string, string>>
): BaseUIElement {
return new VariableUiElement(
tagSource
@ -511,7 +515,7 @@ export default class SpecialVisualizations {
return new SvelteUIElement(SplitRoadWizard, { id, state })
}
return undefined
}),
})
)
},
},
@ -525,7 +529,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
@ -548,7 +552,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
if (!layer.deletion) {
return undefined
@ -574,7 +578,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
) {
if (feature.geometry.type !== "LineString") {
return undefined
@ -582,10 +586,13 @@ export default class SpecialVisualizations {
const t = Translations.t.general.download
return new SvelteUIElement(ExportFeatureButton, {
tags, feature, layer,
tags,
feature,
layer,
mimetype: "{gpx=application/gpx+xml}",
extension: "gpx",
construct: (feature: Feature<LineString>, title: string) => GeoOperations.toGpx(feature, title),
construct: (feature: Feature<LineString>, title: string) =>
GeoOperations.toGpx(feature, title),
helpertext: t.downloadGpxHelper,
maintext: t.downloadFeatureAsGpx,
})
@ -603,7 +610,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, {
@ -666,7 +673,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(
@ -676,9 +683,9 @@ export default class SpecialVisualizations {
}
const response = <WikidataResponse>e["success"]
return Translation.fromMap(response.labels)
}),
})
)
}),
})
),
},
new MapillaryLinkVis(),
@ -692,7 +699,7 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
_,
__,
layer: LayerConfig,
layer: LayerConfig
) => new SvelteUIElement(AllTagsPanel, { tags, layer }),
},
{
@ -775,7 +782,7 @@ export default class SpecialVisualizations {
nameKey: nameKey,
fallbackName,
},
state.featureSwitchIsTesting,
state.featureSwitchIsTesting
)
return new SvelteUIElement(StarsBarIcon, {
score: reviews.average,
@ -809,7 +816,7 @@ export default class SpecialVisualizations {
nameKey: nameKey,
fallbackName,
},
state.featureSwitchIsTesting,
state.featureSwitchIsTesting
)
return new SvelteUIElement(ReviewForm, { reviews, state, tags, feature, layer })
},
@ -840,7 +847,7 @@ export default class SpecialVisualizations {
nameKey: nameKey,
fallbackName,
},
state.featureSwitchIsTesting,
state.featureSwitchIsTesting
)
return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer })
},
@ -866,7 +873,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(
@ -874,14 +881,14 @@ export default class SpecialVisualizations {
tagSource,
args,
feature,
layer,
layer
),
SpecialVisualizations.specialVisualisationsDict["list_reviews"].constr(
state,
tagSource,
args,
feature,
layer,
layer
),
])
},
@ -899,7 +906,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 })
@ -956,7 +963,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]
@ -993,17 +1000,17 @@ export default class SpecialVisualizations {
return undefined
}
const allUnits: Unit[] = [].concat(
...(state?.theme?.layers?.map((lyr) => lyr.units) ?? []),
...(state?.theme?.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)
}),
})
)
},
},
@ -1015,10 +1022,13 @@ export default class SpecialVisualizations {
constr: (state, tags, args, feature, layer) => {
const t = Translations.t.general.download
return new SvelteUIElement(ExportFeatureButton, {
tags, feature, layer,
tags,
feature,
layer,
mimetype: "application/vnd.geo+json",
extension: "geojson",
construct: (feature: Feature<LineString>) => JSON.stringify(feature, null, " "),
construct: (feature: Feature<LineString>) =>
JSON.stringify(feature, null, " "),
maintext: t.downloadFeatureAsGeojson,
helpertext: t.downloadGeoJsonHelper,
})
@ -1054,7 +1064,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)
@ -1095,10 +1105,10 @@ export default class SpecialVisualizations {
new SvelteUIElement(NoteCommentElement, {
comment,
state,
}),
),
})
)
).SetClass("flex flex-col")
}),
})
),
},
{
@ -1131,7 +1141,7 @@ export default class SpecialVisualizations {
tagsSource: UIEventSource<Record<string, string>>,
_: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
) =>
new VariableUiElement(
tagsSource.map((tags) => {
@ -1151,7 +1161,7 @@ export default class SpecialVisualizations {
})
.SetClass("px-1")
.setSpan()
}),
})
),
},
{
@ -1167,8 +1177,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(
@ -1193,7 +1203,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.",
@ -1207,15 +1217,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" +
@ -1291,7 +1301,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) => {
@ -1301,8 +1311,8 @@ export default class SpecialVisualizations {
const fsBboxed = new BBoxFeatureSourceForLayer(fs, bbox)
return new StatisticsPanel(fsBboxed)
},
[state.mapProperties.bounds],
),
[state.mapProperties.bounds]
)
)
},
},
@ -1372,7 +1382,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 === "") {
@ -1410,7 +1420,7 @@ export default class SpecialVisualizations {
},
},
null,
" ",
" "
) +
"\n```",
args: [
@ -1434,7 +1444,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 ?? ""
@ -1452,7 +1462,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
}
@ -1468,7 +1478,7 @@ export default class SpecialVisualizations {
elements.push(subsTr)
}
return elements
}),
})
)
},
},
@ -1488,7 +1498,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) => {
@ -1500,7 +1510,7 @@ export default class SpecialVisualizations {
console.error("Cannot create a translation for", v, "due to", e)
return JSON.stringify(v)
}
}),
})
)
},
},
@ -1520,11 +1530,10 @@ export default class SpecialVisualizations {
tags: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const key = argument[0]
return new SvelteUIElement(FediverseLink, { key, tags, state })
},
},
{
@ -1543,7 +1552,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
args: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
return new FixedUiElement("{" + args[0] + "}")
},
@ -1564,7 +1573,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(
@ -1582,12 +1591,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")
}
}),
})
)
},
},
@ -1608,7 +1617,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 })
@ -1624,12 +1633,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, {}),
@ -1651,7 +1660,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,
@ -1671,7 +1680,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,
@ -1691,7 +1700,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 })
},
@ -1704,7 +1713,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 })
},
@ -1723,7 +1732,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(
@ -1734,11 +1743,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]
}),
})
)
},
},
@ -1768,7 +1777,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"
@ -1794,12 +1803,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
)
},
},
@ -1837,7 +1846,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"
@ -1864,11 +1873,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
@ -1878,7 +1887,7 @@ export default class SpecialVisualizations {
console.error(e)
throw e
}
})(),
})()
)
}
return Stores.FromPromiseWithErr(
@ -1887,27 +1896,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(
@ -1922,7 +1931,7 @@ export default class SpecialVisualizations {
collapsed: isClosed,
}),
undefined,
url.map((url) => !!url),
url.map((url) => !!url)
)
},
},
@ -1942,7 +1951,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]
@ -1964,7 +1973,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.theme.getMatchingLayer(tags)
@ -1982,7 +1991,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 })
},
@ -2002,7 +2011,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",
@ -2027,7 +2036,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())
@ -2050,7 +2059,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 = {
@ -2090,7 +2099,7 @@ export default class SpecialVisualizations {
tagSource: UIEventSource<Record<string, string>>,
argument: string[],
feature: Feature,
layer: LayerConfig,
layer: LayerConfig
): BaseUIElement {
const text = argument[0]
return new SubtleButton(undefined, text).onClick(() => {
@ -2112,7 +2121,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'
)
}