Refactoring: reduce dependency on 'VariableUIElement' by having a 'TrDyn'-svelte component instead

This commit is contained in:
Pieter Vander Vennet 2025-09-01 00:58:39 +02:00
parent 42f07bc1f3
commit 2a2b8b77e8
8 changed files with 90 additions and 98 deletions

9
src/UI/Base/TrDyn.svelte Normal file
View file

@ -0,0 +1,9 @@
<script lang="ts">
import { Translation } from "../i18n/Translation"
import type { Store } from "../../Logic/UIEventSource"
import Tr from "./Tr.svelte"
export let t: Store<Translation>
</script>
<Tr t={$t} />

View file

@ -2,7 +2,7 @@ import {
SpecialVisualisationArg,
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationSvelte,
SpecialVisualizationSvelte
} from "../SpecialVisualization"
import { HistogramViz } from "./HistogramViz"
import { Store } from "../../Logic/UIEventSource"
@ -32,6 +32,8 @@ import Marker from "../Map/Marker.svelte"
import { twJoin } from "tailwind-merge"
import { Tag } from "../../Logic/Tags/Tag"
import { Lists } from "../../Utils/Lists"
import { Translation } from "../i18n/Translation"
import TrDyn from "../Base/TrDyn.svelte"
class DirectionIndicatorVis extends SpecialVisualizationSvelte {
funcName = "direction_indicator"
@ -46,7 +48,7 @@ class DirectionIndicatorVis extends SpecialVisualizationSvelte {
}
}
class DirectionAbsolute extends SpecialVisualization {
class DirectionAbsolute extends SpecialVisualizationSvelte {
funcName = "direction_absolute"
docs =
"Converts compass degrees (with 0° being north, 90° being east, ...) into a human readable, translated direction such as 'north', 'northeast'"
@ -65,24 +67,20 @@ class DirectionAbsolute extends SpecialVisualization {
]
group = "data"
constr({ tags, args }: SpecialVisualisationParams): BaseUIElement {
constr({ tags, args }: SpecialVisualisationParams): SvelteUIElement {
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
const offset = args[1] === "" ? 0 : Number(args[1])
return new VariableUiElement(
tags
.map((tags) => {
console.log("Direction value", tags[key], key)
return tags[key]
})
.mapD((value) => {
const dir = GeoOperations.bearingToHuman(
GeoOperations.parseBearing(value) + offset
)
console.log("Human dir", dir)
return Translations.t.general.visualFeedback.directionsAbsolute[dir]
})
)
const t: Store<Translation> = tags
.map((tags) => tags[key])
.mapD((value: string) => {
const dir = GeoOperations.bearingToHuman(
GeoOperations.parseBearing(value) + offset
)
return Translations.t.general.visualFeedback.directionsAbsolute[dir]
})
return new SvelteUIElement(TrDyn, { t })
}
}
@ -162,7 +160,7 @@ class OpeningHoursState extends SpecialVisualizationSvelte {
}
}
class Canonical extends SpecialVisualization {
class Canonical extends SpecialVisualizationSvelte {
group = "data"
funcName = "canonical"
@ -181,24 +179,23 @@ class Canonical extends SpecialVisualization {
constr({ state, tags, args }: SpecialVisualisationParams) {
const key = args[0]
return new VariableUiElement(
tags
.map((tags) => tags[key])
.map((value) => {
if (value === undefined) {
return undefined
}
const allUnits: Unit[] = [].concat(
...(state?.theme?.layers?.map((lyr) => lyr.units) ?? [])
)
const unit = allUnits.filter((unit) => unit.isApplicableToKey(key))[0]
if (unit === undefined) {
return value
}
const getCountry = () => tags.data._country
return unit.asHumanLongValue(value, getCountry)
})
)
const t: Store<Translation> = tags
.map((tags) => tags[key])
.map((value: string) => {
if (value === undefined) {
return undefined
}
const allUnits: Unit[] = [].concat(
...(state?.theme?.layers?.map((lyr) => lyr.units) ?? [])
)
const unit = allUnits.filter((unit) => unit.isApplicableToKey(key))[0]
if (unit === undefined) {
return Translations.T(value)
}
const getCountry = () => tags.data._country
return unit.asHumanLongValue(value, getCountry)
})
return new SvelteUIElement(TrDyn, { t })
}
}

View file

@ -1,13 +1,6 @@
import {
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationState,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { SpecialVisualisationParams, SpecialVisualization, SpecialVisualizationSvelte } from "../SpecialVisualization"
import SvelteUIElement from "../Base/SvelteUIElement"
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
import { Feature, GeoJSON } from "geojson"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import { ImmutableStore, Store } from "../../Logic/UIEventSource"
import Questionbox from "../Popup/TagRendering/Questionbox.svelte"
import MinimapViz from "../Popup/MinimapViz.svelte"
import SplitRoadWizard from "../Popup/SplitRoadWizard.svelte"
@ -19,11 +12,11 @@ import { ShareLinkViz } from "../Popup/ShareLinkViz"
import { GeoOperations } from "../../Logic/GeoOperations"
import AddNewPoint from "../Popup/AddNewPoint/AddNewPoint.svelte"
import BaseUIElement from "../BaseUIElement"
import { VariableUiElement } from "../Base/VariableUIElement"
import { Translation } from "../i18n/Translation"
import { FixedUiElement } from "../Base/FixedUiElement"
import { default as FeatureTitle } from "../Popup/Title.svelte"
import CreateCopy from "../Popup/AddNewPoint/CreateCopy.svelte"
import TrDyn from "../Base/TrDyn.svelte"
/**
* Thin wrapper around QuestionBox.svelte to include it into the special Visualisations
@ -105,7 +98,7 @@ class Minimap extends SpecialVisualizationSvelte {
example =
"`{minimap()}`, `{minimap(17, id, _list_of_embedded_feature_ids_calculated_by_calculated_tag):height:10rem; border: 2px solid black}`"
constr({ state, tags, args, feature, layer }: SpecialVisualisationParams): SvelteUIElement {
constr({ state, tags, args, feature }: SpecialVisualisationParams): SvelteUIElement {
const minzoom = Number(args[0] ?? 18)
const ids = args[1]?.split(";")?.map((s) => s.trim()) ?? ["id"]
const clss = args[2]
@ -263,18 +256,18 @@ class Translated extends SpecialVisualization {
]
constr({ tags, args }: SpecialVisualisationParams): BaseUIElement {
return new VariableUiElement(
tags.map((tags) => {
const v = tags[args[0] ?? "value"]
try {
const tr = typeof v === "string" ? JSON.parse(v) : v
return new Translation(tr).SetClass("font-bold")
} catch (e) {
console.error("Cannot create a translation for", v, "due to", e)
return JSON.stringify(v)
}
})
)
const t: Store<Translation> = tags.map((tags) => {
const v = tags[args[0] ?? "value"]
try {
const tr = typeof v === "string" ? JSON.parse(v) : v
return new Translation(tr)
} catch (e) {
console.error("Cannot create a translation for", v, "due to", e)
return new Translation({ "*": JSON.stringify(v) })
}
})
return new SvelteUIElement(TrDyn, { t })
}
}

View file

@ -1,21 +1,18 @@
import {
SpecialVisualisationParams,
SpecialVisualization,
SpecialVisualizationSvelte,
} from "../SpecialVisualization"
import { SpecialVisualisationParams, SpecialVisualizationSvelte } from "../SpecialVisualization"
import { ImmutableStore, Store } from "../../Logic/UIEventSource"
import SvelteUIElement from "../Base/SvelteUIElement"
import FediverseLink from "../Popup/FediverseLink.svelte"
import Wikidata, { WikidataResponse } from "../../Logic/Web/Wikidata"
import Wikipedia from "../../Logic/Web/Wikipedia"
import WikipediaPanel from "../Wikipedia/WikipediaPanel.svelte"
import { VariableUiElement } from "../Base/VariableUIElement"
import { Utils } from "../../Utils"
import { Translation } from "../i18n/Translation"
import { MapillaryLinkVis } from "../Popup/MapillaryLinkVis"
import SendEmail from "../Popup/SendEmail.svelte"
import DynLink from "../Base/DynLink.svelte"
import { Lists } from "../../Utils/Lists"
import TrDyn from "../Base/TrDyn.svelte"
import Translations from "../i18n/Translations"
class FediverseLinkVis extends SpecialVisualizationSvelte {
funcName = "fediverse_link"
@ -65,7 +62,7 @@ class WikipediaVis extends SpecialVisualizationSvelte {
}
}
class WikidatalabelVis extends SpecialVisualization {
class WikidatalabelVis extends SpecialVisualizationSvelte {
funcName = "wikidata_label"
group = "web_and_communication"
@ -84,25 +81,25 @@ class WikidatalabelVis extends SpecialVisualization {
"`{wikidata_label()}` is a basic example, `{wikipedia(name:etymology:wikidata)}` to show the label itself"
constr({ tags, args }: SpecialVisualisationParams) {
const id = tags
const id: Store<string> = tags
.map((tags) => tags[args[0]])
.map((wikidata) => {
const wikidataIds = Lists.noEmpty(
wikidata?.split(";")?.map((wd) => wd.trim()) ?? []
)
return wikidataIds?.[0]
return <string>(wikidataIds?.[0])
})
const entry = id.bind((id) => Wikidata.LoadWikidataEntry(id))
return new VariableUiElement(
entry.map((e) => {
if (e === undefined || e["success"] === undefined) {
return id.data
}
const response = <WikidataResponse>e["success"]
return Translation.fromMap(response.labels)
})
)
const entry: Store<{ success: WikidataResponse } | {
error: any
}> = id.bind((id) => Wikidata.LoadWikidataEntry(id))
const t: Store<Translation> = entry.map((e) => {
if (e === undefined || e["success"] === undefined) {
return Translations.T(id.data)
}
const response = <WikidataResponse>e["success"]
return Translation.fromMap(response.labels)
})
return new SvelteUIElement(TrDyn, { t })
}
}
@ -199,7 +196,7 @@ class LinkVis extends SpecialVisualizationSvelte {
}
}
export class WebAndCommunicationSpecialVisualisations {
public static initList(): SpecialVisualization[] {
public static initList(): SpecialVisualizationSvelte[] {
return [
new FediverseLinkVis(),
new WikipediaVis(),

View file

@ -1,8 +1,4 @@
import {
RenderingSpecification,
SpecialVisualization,
SpecialVisualizationSvelte,
} from "./SpecialVisualization"
import { RenderingSpecification, SpecialVisualization, SpecialVisualizationSvelte } from "./SpecialVisualization"
import { UploadToOsmViz } from "./Popup/UploadToOsmViz"
import { MultiApplyViz } from "./Popup/MultiApplyViz"
import AutoApplyButtonVis from "./Popup/AutoApplyButtonVis"
@ -15,8 +11,11 @@ import { UISpecialVisualisations } from "./SpecialVisualisations/UISpecialVisual
import { SettingsVisualisations } from "./SpecialVisualisations/SettingsVisualisations"
import { ReviewSpecialVisualisations } from "./SpecialVisualisations/ReviewSpecialVisualisations"
import { DataImportSpecialVisualisations } from "./SpecialVisualisations/DataImportSpecialVisualisations"
import TagrenderingManipulationSpecialVisualisations from "./SpecialVisualisations/TagrenderingManipulationSpecialVisualisations"
import { WebAndCommunicationSpecialVisualisations } from "./SpecialVisualisations/WebAndCommunicationSpecialVisualisations"
import TagrenderingManipulationSpecialVisualisations
from "./SpecialVisualisations/TagrenderingManipulationSpecialVisualisations"
import {
WebAndCommunicationSpecialVisualisations
} from "./SpecialVisualisations/WebAndCommunicationSpecialVisualisations"
import { DataVisualisations } from "./Popup/DataVisualisations"
import { DataExportVisualisations } from "./Popup/DataExportVisualisations"
import { Utils } from "../Utils"
@ -186,6 +185,7 @@ export default class SpecialVisualizations {
...SettingsVisualisations.initList(),
...DataImportSpecialVisualisations.initList(),
...DataExportVisualisations.initList(),
...WebAndCommunicationSpecialVisualisations.initList(),
new UploadToOsmViz(),
new MultiApplyViz(),
]
@ -195,7 +195,6 @@ export default class SpecialVisualizations {
...UISpecialVisualisations.initList(),
...ReviewSpecialVisualisations.initList(),
...TagrenderingManipulationSpecialVisualisations.initList(),
...WebAndCommunicationSpecialVisualisations.initList(),
...DataVisualisations.initList(),
...specialVisualizationsSv,
]