Add countrycoder endpoint to connect sources
This commit is contained in:
parent
ae7cc95727
commit
bed8fb0bf9
1 changed files with 139 additions and 117 deletions
|
@ -3,7 +3,11 @@ import { FixedUiElement } from "./Base/FixedUiElement"
|
||||||
import BaseUIElement from "./BaseUIElement"
|
import BaseUIElement from "./BaseUIElement"
|
||||||
import Title from "./Base/Title"
|
import Title from "./Base/Title"
|
||||||
import Table from "./Base/Table"
|
import Table from "./Base/Table"
|
||||||
import { RenderingSpecification, SpecialVisualization, SpecialVisualizationState } from "./SpecialVisualization"
|
import {
|
||||||
|
RenderingSpecification,
|
||||||
|
SpecialVisualization,
|
||||||
|
SpecialVisualizationState,
|
||||||
|
} from "./SpecialVisualization"
|
||||||
import { HistogramViz } from "./Popup/HistogramViz"
|
import { HistogramViz } from "./Popup/HistogramViz"
|
||||||
import { MinimapViz } from "./Popup/MinimapViz"
|
import { MinimapViz } from "./Popup/MinimapViz"
|
||||||
import { ShareLinkViz } from "./Popup/ShareLinkViz"
|
import { ShareLinkViz } from "./Popup/ShareLinkViz"
|
||||||
|
@ -114,7 +118,7 @@ class NearbyImageVis implements SpecialVisualization {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const isOpen = args[0] === "open"
|
const isOpen = args[0] === "open"
|
||||||
const readonly = args[1] === "readonly"
|
const readonly = args[1] === "readonly"
|
||||||
|
@ -181,7 +185,7 @@ class StealViz implements SpecialVisualization {
|
||||||
selectedElement: otherFeature,
|
selectedElement: otherFeature,
|
||||||
state,
|
state,
|
||||||
layer,
|
layer,
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (elements.length === 1) {
|
if (elements.length === 1) {
|
||||||
|
@ -189,8 +193,8 @@ class StealViz implements SpecialVisualization {
|
||||||
}
|
}
|
||||||
return new Combine(elements).SetClass("flex flex-col")
|
return new Combine(elements).SetClass("flex flex-col")
|
||||||
},
|
},
|
||||||
[state.indexedFeatures.featuresById],
|
[state.indexedFeatures.featuresById]
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +233,7 @@ export class QuestionViz implements SpecialVisualization {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const labels = args[0]
|
const labels = args[0]
|
||||||
?.split(";")
|
?.split(";")
|
||||||
|
@ -265,38 +269,38 @@ export default class SpecialVisualizations {
|
||||||
viz.docs,
|
viz.docs,
|
||||||
viz.args.length > 0
|
viz.args.length > 0
|
||||||
? new Table(
|
? new Table(
|
||||||
["name", "default", "description"],
|
["name", "default", "description"],
|
||||||
viz.args.map((arg) => {
|
viz.args.map((arg) => {
|
||||||
let defaultArg = arg.defaultValue ?? "_undefined_"
|
let defaultArg = arg.defaultValue ?? "_undefined_"
|
||||||
if (defaultArg == "") {
|
if (defaultArg == "") {
|
||||||
defaultArg = "_empty string_"
|
defaultArg = "_empty string_"
|
||||||
}
|
}
|
||||||
return [arg.name, defaultArg, arg.doc]
|
return [arg.name, defaultArg, arg.doc]
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
: undefined,
|
: undefined,
|
||||||
new Title("Example usage of " + viz.funcName, 4),
|
new Title("Example usage of " + viz.funcName, 4),
|
||||||
new FixedUiElement(
|
new FixedUiElement(
|
||||||
viz.example ??
|
viz.example ??
|
||||||
"`{" +
|
"`{" +
|
||||||
viz.funcName +
|
viz.funcName +
|
||||||
"(" +
|
"(" +
|
||||||
viz.args.map((arg) => arg.defaultValue).join(",") +
|
viz.args.map((arg) => arg.defaultValue).join(",") +
|
||||||
")}`",
|
")}`"
|
||||||
).SetClass("literal-code"),
|
).SetClass("literal-code"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
public static constructSpecification(
|
public static constructSpecification(
|
||||||
template: string,
|
template: string,
|
||||||
extraMappings: SpecialVisualization[] = [],
|
extraMappings: SpecialVisualization[] = []
|
||||||
): RenderingSpecification[] {
|
): RenderingSpecification[] {
|
||||||
return SpecialVisualisationUtils.constructSpecification(template, extraMappings)
|
return SpecialVisualisationUtils.constructSpecification(template, extraMappings)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HelpMessage() {
|
public static HelpMessage() {
|
||||||
const helpTexts = SpecialVisualizations.specialVisualizations.map((viz) =>
|
const helpTexts = SpecialVisualizations.specialVisualizations.map((viz) =>
|
||||||
SpecialVisualizations.DocumentationFor(viz),
|
SpecialVisualizations.DocumentationFor(viz)
|
||||||
)
|
)
|
||||||
|
|
||||||
return new Combine([
|
return new Combine([
|
||||||
|
@ -330,10 +334,10 @@ export default class SpecialVisualizations {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
" ",
|
" "
|
||||||
),
|
)
|
||||||
).SetClass("code"),
|
).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"),
|
]).SetClass("flex flex-col"),
|
||||||
...helpTexts,
|
...helpTexts,
|
||||||
]).SetClass("flex flex-col")
|
]).SetClass("flex flex-col")
|
||||||
|
@ -342,20 +346,20 @@ export default class SpecialVisualizations {
|
||||||
// noinspection JSUnusedGlobalSymbols
|
// noinspection JSUnusedGlobalSymbols
|
||||||
public static renderExampleOfSpecial(
|
public static renderExampleOfSpecial(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
s: SpecialVisualization,
|
s: SpecialVisualization
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const examples =
|
const examples =
|
||||||
s.structuredExamples === undefined
|
s.structuredExamples === undefined
|
||||||
? []
|
? []
|
||||||
: s.structuredExamples().map((e) => {
|
: s.structuredExamples().map((e) => {
|
||||||
return s.constr(
|
return s.constr(
|
||||||
state,
|
state,
|
||||||
new UIEventSource<Record<string, string>>(e.feature.properties),
|
new UIEventSource<Record<string, string>>(e.feature.properties),
|
||||||
e.args,
|
e.args,
|
||||||
e.feature,
|
e.feature,
|
||||||
undefined,
|
undefined
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
return new Combine([new Title(s.funcName), s.docs, ...examples])
|
return new Combine([new Title(s.funcName), s.docs, ...examples])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,7 +399,7 @@ export default class SpecialVisualizations {
|
||||||
assignTo: state.userRelatedState.language,
|
assignTo: state.userRelatedState.language,
|
||||||
availableLanguages: state.layout.language,
|
availableLanguages: state.layout.language,
|
||||||
preferredLanguages: state.osmConnection.userDetails.map(
|
preferredLanguages: state.osmConnection.userDetails.map(
|
||||||
(ud) => ud.languages,
|
(ud) => ud.languages
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -420,7 +424,7 @@ export default class SpecialVisualizations {
|
||||||
|
|
||||||
constr(
|
constr(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
tagSource
|
tagSource
|
||||||
|
@ -430,7 +434,7 @@ export default class SpecialVisualizations {
|
||||||
return new SplitRoadWizard(<WayId>id, state)
|
return new SplitRoadWizard(<WayId>id, state)
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -444,7 +448,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
if (feature.geometry.type !== "Point") {
|
if (feature.geometry.type !== "Point") {
|
||||||
return undefined
|
return undefined
|
||||||
|
@ -467,7 +471,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
if (!layer.deletion) {
|
if (!layer.deletion) {
|
||||||
return undefined
|
return undefined
|
||||||
|
@ -495,7 +499,7 @@ export default class SpecialVisualizations {
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
|
const [lon, lat] = GeoOperations.centerpointCoordinates(feature)
|
||||||
return new SvelteUIElement(CreateNewNote, {
|
return new SvelteUIElement(CreateNewNote, {
|
||||||
|
@ -559,7 +563,7 @@ export default class SpecialVisualizations {
|
||||||
.map((tags) => tags[args[0]])
|
.map((tags) => tags[args[0]])
|
||||||
.map((wikidata) => {
|
.map((wikidata) => {
|
||||||
wikidata = Utils.NoEmpty(
|
wikidata = Utils.NoEmpty(
|
||||||
wikidata?.split(";")?.map((wd) => wd.trim()) ?? [],
|
wikidata?.split(";")?.map((wd) => wd.trim()) ?? []
|
||||||
)[0]
|
)[0]
|
||||||
const entry = Wikidata.LoadWikidataEntry(wikidata)
|
const entry = Wikidata.LoadWikidataEntry(wikidata)
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
|
@ -569,9 +573,9 @@ export default class SpecialVisualizations {
|
||||||
}
|
}
|
||||||
const response = <WikidataResponse>e["success"]
|
const response = <WikidataResponse>e["success"]
|
||||||
return Translation.fromMap(response.labels)
|
return Translation.fromMap(response.labels)
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
}),
|
})
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
new MapillaryLinkVis(),
|
new MapillaryLinkVis(),
|
||||||
|
@ -585,7 +589,7 @@ export default class SpecialVisualizations {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
_,
|
_,
|
||||||
__,
|
__,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
) => new SvelteUIElement(AllTagsPanel, { tags, layer }),
|
) => new SvelteUIElement(AllTagsPanel, { tags, layer }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -607,7 +611,7 @@ export default class SpecialVisualizations {
|
||||||
return new ImageCarousel(
|
return new ImageCarousel(
|
||||||
AllImageProviders.LoadImagesFor(tags, imagePrefixes),
|
AllImageProviders.LoadImagesFor(tags, imagePrefixes),
|
||||||
tags,
|
tags,
|
||||||
state,
|
state
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -663,7 +667,7 @@ export default class SpecialVisualizations {
|
||||||
{
|
{
|
||||||
nameKey: nameKey,
|
nameKey: nameKey,
|
||||||
fallbackName,
|
fallbackName,
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
return new SvelteUIElement(StarsBarIcon, {
|
return new SvelteUIElement(StarsBarIcon, {
|
||||||
score: reviews.average,
|
score: reviews.average,
|
||||||
|
@ -696,7 +700,7 @@ export default class SpecialVisualizations {
|
||||||
{
|
{
|
||||||
nameKey: nameKey,
|
nameKey: nameKey,
|
||||||
fallbackName,
|
fallbackName,
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
return new SvelteUIElement(ReviewForm, { reviews, state, tags, feature, layer })
|
return new SvelteUIElement(ReviewForm, { reviews, state, tags, feature, layer })
|
||||||
},
|
},
|
||||||
|
@ -728,7 +732,7 @@ export default class SpecialVisualizations {
|
||||||
{
|
{
|
||||||
nameKey: nameKey,
|
nameKey: nameKey,
|
||||||
fallbackName,
|
fallbackName,
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer })
|
return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer })
|
||||||
},
|
},
|
||||||
|
@ -753,7 +757,7 @@ export default class SpecialVisualizations {
|
||||||
doc: "Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__",
|
doc: "Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
needsUrls: [Constants.countryCoderEndpoint],
|
||||||
example:
|
example:
|
||||||
"A normal opening hours table can be invoked with `{opening_hours_table()}`. A table for e.g. conditional access with opening hours can be `{opening_hours_table(access:conditional, no @ &LPARENS, &RPARENS)}`",
|
"A normal opening hours table can be invoked with `{opening_hours_table()}`. A table for e.g. conditional access with opening hours can be `{opening_hours_table(access:conditional, no @ &LPARENS, &RPARENS)}`",
|
||||||
constr: (state, tagSource: UIEventSource<any>, args) => {
|
constr: (state, tagSource: UIEventSource<any>, args) => {
|
||||||
|
@ -786,7 +790,7 @@ export default class SpecialVisualizations {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
const keyToUse = args[0]
|
const keyToUse = args[0]
|
||||||
const prefix = args[1]
|
const prefix = args[1]
|
||||||
|
@ -823,17 +827,17 @@ export default class SpecialVisualizations {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
const allUnits: Unit[] = [].concat(
|
const allUnits: Unit[] = [].concat(
|
||||||
...(state?.layout?.layers?.map((lyr) => lyr.units) ?? []),
|
...(state?.layout?.layers?.map((lyr) => lyr.units) ?? [])
|
||||||
)
|
)
|
||||||
const unit = allUnits.filter((unit) =>
|
const unit = allUnits.filter((unit) =>
|
||||||
unit.isApplicableToKey(key),
|
unit.isApplicableToKey(key)
|
||||||
)[0]
|
)[0]
|
||||||
if (unit === undefined) {
|
if (unit === undefined) {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
const getCountry = () => tagSource.data._country
|
const getCountry = () => tagSource.data._country
|
||||||
return unit.asHumanLongValue(value, getCountry)
|
return unit.asHumanLongValue(value, getCountry)
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -850,7 +854,7 @@ export default class SpecialVisualizations {
|
||||||
new Combine([
|
new Combine([
|
||||||
t.downloadFeatureAsGeojson.SetClass("font-bold text-lg"),
|
t.downloadFeatureAsGeojson.SetClass("font-bold text-lg"),
|
||||||
t.downloadGeoJsonHelper.SetClass("subtle"),
|
t.downloadGeoJsonHelper.SetClass("subtle"),
|
||||||
]).SetClass("flex flex-col"),
|
]).SetClass("flex flex-col")
|
||||||
)
|
)
|
||||||
.onClick(() => {
|
.onClick(() => {
|
||||||
console.log("Exporting as Geojson")
|
console.log("Exporting as Geojson")
|
||||||
|
@ -863,7 +867,7 @@ export default class SpecialVisualizations {
|
||||||
title + "_mapcomplete_export.geojson",
|
title + "_mapcomplete_export.geojson",
|
||||||
{
|
{
|
||||||
mimetype: "application/vnd.geo+json",
|
mimetype: "application/vnd.geo+json",
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.SetClass("w-full")
|
.SetClass("w-full")
|
||||||
|
@ -899,7 +903,7 @@ export default class SpecialVisualizations {
|
||||||
constr: (state) => {
|
constr: (state) => {
|
||||||
return new SubtleButton(
|
return new SubtleButton(
|
||||||
Svg.delete_icon_svg().SetStyle("height: 1.5rem"),
|
Svg.delete_icon_svg().SetStyle("height: 1.5rem"),
|
||||||
Translations.t.general.removeLocationHistory,
|
Translations.t.general.removeLocationHistory
|
||||||
).onClick(() => {
|
).onClick(() => {
|
||||||
state.historicalUserLocations.features.setData([])
|
state.historicalUserLocations.features.setData([])
|
||||||
state.selectedElement.setData(undefined)
|
state.selectedElement.setData(undefined)
|
||||||
|
@ -937,10 +941,10 @@ export default class SpecialVisualizations {
|
||||||
.filter((c) => c.text !== "")
|
.filter((c) => c.text !== "")
|
||||||
.map(
|
.map(
|
||||||
(c, i) =>
|
(c, i) =>
|
||||||
new NoteCommentElement(c, state, i, comments.length),
|
new NoteCommentElement(c, state, i, comments.length)
|
||||||
),
|
)
|
||||||
).SetClass("flex flex-col")
|
).SetClass("flex flex-col")
|
||||||
}),
|
})
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -974,7 +978,7 @@ export default class SpecialVisualizations {
|
||||||
tagsSource: UIEventSource<Record<string, string>>,
|
tagsSource: UIEventSource<Record<string, string>>,
|
||||||
_: string[],
|
_: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
) =>
|
) =>
|
||||||
new VariableUiElement(
|
new VariableUiElement(
|
||||||
tagsSource.map((tags) => {
|
tagsSource.map((tags) => {
|
||||||
|
@ -992,7 +996,7 @@ export default class SpecialVisualizations {
|
||||||
feature,
|
feature,
|
||||||
layer,
|
layer,
|
||||||
}).SetClass("px-1")
|
}).SetClass("px-1")
|
||||||
}),
|
})
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1008,8 +1012,8 @@ export default class SpecialVisualizations {
|
||||||
let challenge = Stores.FromPromise(
|
let challenge = Stores.FromPromise(
|
||||||
Utils.downloadJsonCached(
|
Utils.downloadJsonCached(
|
||||||
`${Maproulette.defaultEndpoint}/challenge/${parentId}`,
|
`${Maproulette.defaultEndpoint}/challenge/${parentId}`,
|
||||||
24 * 60 * 60 * 1000,
|
24 * 60 * 60 * 1000
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
|
@ -1034,7 +1038,7 @@ export default class SpecialVisualizations {
|
||||||
} else {
|
} else {
|
||||||
return [title, new List(listItems)]
|
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.",
|
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.",
|
||||||
|
@ -1048,15 +1052,15 @@ export default class SpecialVisualizations {
|
||||||
"\n" +
|
"\n" +
|
||||||
"```json\n" +
|
"```json\n" +
|
||||||
"{\n" +
|
"{\n" +
|
||||||
" \"id\": \"mark_duplicate\",\n" +
|
' "id": "mark_duplicate",\n' +
|
||||||
" \"render\": {\n" +
|
' "render": {\n' +
|
||||||
" \"special\": {\n" +
|
' "special": {\n' +
|
||||||
" \"type\": \"maproulette_set_status\",\n" +
|
' "type": "maproulette_set_status",\n' +
|
||||||
" \"message\": {\n" +
|
' "message": {\n' +
|
||||||
" \"en\": \"Mark as not found or false positive\"\n" +
|
' "en": "Mark as not found or false positive"\n' +
|
||||||
" },\n" +
|
" },\n" +
|
||||||
" \"status\": \"2\",\n" +
|
' "status": "2",\n' +
|
||||||
" \"image\": \"close\"\n" +
|
' "image": "close"\n' +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
" }\n" +
|
" }\n" +
|
||||||
"}\n" +
|
"}\n" +
|
||||||
|
@ -1088,12 +1092,19 @@ export default class SpecialVisualizations {
|
||||||
{
|
{
|
||||||
name: "ask_feedback",
|
name: "ask_feedback",
|
||||||
doc: "If not an empty string, this will be used as question to ask some additional feedback. A text field will be added",
|
doc: "If not an empty string, this will be used as question to ask some additional feedback. A text field will be added",
|
||||||
defaultValue: ""
|
defaultValue: "",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
constr: (state, tagsSource, args) => {
|
constr: (state, tagsSource, args) => {
|
||||||
let [message, image, message_closed, statusToSet, maproulette_id_key, askFeedback] = args
|
let [
|
||||||
|
message,
|
||||||
|
image,
|
||||||
|
message_closed,
|
||||||
|
statusToSet,
|
||||||
|
maproulette_id_key,
|
||||||
|
askFeedback,
|
||||||
|
] = args
|
||||||
if (image === "") {
|
if (image === "") {
|
||||||
image = "confirm"
|
image = "confirm"
|
||||||
}
|
}
|
||||||
|
@ -1109,7 +1120,7 @@ export default class SpecialVisualizations {
|
||||||
message_closed,
|
message_closed,
|
||||||
statusToSet,
|
statusToSet,
|
||||||
maproulette_id_key,
|
maproulette_id_key,
|
||||||
askFeedback
|
askFeedback,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1129,8 +1140,8 @@ export default class SpecialVisualizations {
|
||||||
const fsBboxed = new BBoxFeatureSourceForLayer(fs, bbox)
|
const fsBboxed = new BBoxFeatureSourceForLayer(fs, bbox)
|
||||||
return new StatisticsPanel(fsBboxed)
|
return new StatisticsPanel(fsBboxed)
|
||||||
},
|
},
|
||||||
[state.mapProperties.bounds],
|
[state.mapProperties.bounds]
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1196,7 +1207,7 @@ export default class SpecialVisualizations {
|
||||||
constr(
|
constr(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[]
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
let [text, href, classnames, download, ariaLabel] = args
|
let [text, href, classnames, download, ariaLabel] = args
|
||||||
if (download === "") {
|
if (download === "") {
|
||||||
|
@ -1208,13 +1219,16 @@ export default class SpecialVisualizations {
|
||||||
(tags) =>
|
(tags) =>
|
||||||
new SvelteUIElement(Link, {
|
new SvelteUIElement(Link, {
|
||||||
text: Utils.SubstituteKeys(text, tags),
|
text: Utils.SubstituteKeys(text, tags),
|
||||||
href: Utils.SubstituteKeys(href, tags).replaceAll(/ /g, "%20") /* Chromium based browsers eat the spaces */,
|
href: Utils.SubstituteKeys(href, tags).replaceAll(
|
||||||
|
/ /g,
|
||||||
|
"%20"
|
||||||
|
) /* Chromium based browsers eat the spaces */,
|
||||||
classnames,
|
classnames,
|
||||||
download: Utils.SubstituteKeys(download, tags),
|
download: Utils.SubstituteKeys(download, tags),
|
||||||
ariaLabel: Utils.SubstituteKeys(ariaLabel, tags),
|
ariaLabel: Utils.SubstituteKeys(ariaLabel, tags),
|
||||||
newTab,
|
newTab,
|
||||||
}),
|
})
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1236,7 +1250,7 @@ export default class SpecialVisualizations {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
" ",
|
" "
|
||||||
) +
|
) +
|
||||||
"\n```",
|
"\n```",
|
||||||
args: [
|
args: [
|
||||||
|
@ -1260,7 +1274,7 @@ export default class SpecialVisualizations {
|
||||||
featureTags: UIEventSource<Record<string, string>>,
|
featureTags: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
) {
|
) {
|
||||||
const [key, tr, classesRaw] = args
|
const [key, tr, classesRaw] = args
|
||||||
let classes = classesRaw ?? ""
|
let classes = classesRaw ?? ""
|
||||||
|
@ -1285,7 +1299,7 @@ export default class SpecialVisualizations {
|
||||||
elements.push(subsTr)
|
elements.push(subsTr)
|
||||||
}
|
}
|
||||||
return elements
|
return elements
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1305,7 +1319,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
tagSource.map((tags) => {
|
tagSource.map((tags) => {
|
||||||
|
@ -1317,7 +1331,7 @@ export default class SpecialVisualizations {
|
||||||
console.error("Cannot create a translation for", v, "due to", e)
|
console.error("Cannot create a translation for", v, "due to", e)
|
||||||
return JSON.stringify(v)
|
return JSON.stringify(v)
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1337,7 +1351,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const key = argument[0]
|
const key = argument[0]
|
||||||
const validator = new FediverseValidator()
|
const validator = new FediverseValidator()
|
||||||
|
@ -1347,7 +1361,7 @@ export default class SpecialVisualizations {
|
||||||
.map((fediAccount) => {
|
.map((fediAccount) => {
|
||||||
fediAccount = validator.reformat(fediAccount)
|
fediAccount = validator.reformat(fediAccount)
|
||||||
const [_, username, host] = fediAccount.match(
|
const [_, username, host] = fediAccount.match(
|
||||||
FediverseValidator.usernameAtServer,
|
FediverseValidator.usernameAtServer
|
||||||
)
|
)
|
||||||
|
|
||||||
const normalLink = new SvelteUIElement(Link, {
|
const normalLink = new SvelteUIElement(Link, {
|
||||||
|
@ -1359,10 +1373,10 @@ export default class SpecialVisualizations {
|
||||||
const loggedInContributorMastodon =
|
const loggedInContributorMastodon =
|
||||||
state.userRelatedState?.preferencesAsTags?.data?.[
|
state.userRelatedState?.preferencesAsTags?.data?.[
|
||||||
"_mastodon_link"
|
"_mastodon_link"
|
||||||
]
|
]
|
||||||
console.log(
|
console.log(
|
||||||
"LoggedinContributorMastodon",
|
"LoggedinContributorMastodon",
|
||||||
loggedInContributorMastodon,
|
loggedInContributorMastodon
|
||||||
)
|
)
|
||||||
if (!loggedInContributorMastodon) {
|
if (!loggedInContributorMastodon) {
|
||||||
return normalLink
|
return normalLink
|
||||||
|
@ -1378,7 +1392,7 @@ export default class SpecialVisualizations {
|
||||||
newTab: true,
|
newTab: true,
|
||||||
}).SetClass("button"),
|
}).SetClass("button"),
|
||||||
])
|
])
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1398,7 +1412,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
return new FixedUiElement("{" + args[0] + "}")
|
return new FixedUiElement("{" + args[0] + "}")
|
||||||
},
|
},
|
||||||
|
@ -1419,7 +1433,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const key = argument[0] ?? "value"
|
const key = argument[0] ?? "value"
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
|
@ -1437,12 +1451,12 @@ export default class SpecialVisualizations {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return new FixedUiElement(
|
return new FixedUiElement(
|
||||||
"Could not parse this tag: " +
|
"Could not parse this tag: " +
|
||||||
JSON.stringify(value) +
|
JSON.stringify(value) +
|
||||||
" due to " +
|
" due to " +
|
||||||
e,
|
e
|
||||||
).SetClass("alert")
|
).SetClass("alert")
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1463,7 +1477,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const giggityUrl = argument[0]
|
const giggityUrl = argument[0]
|
||||||
return new SvelteUIElement(Giggity, { tags: tagSource, state, giggityUrl })
|
return new SvelteUIElement(Giggity, { tags: tagSource, state, giggityUrl })
|
||||||
|
@ -1479,12 +1493,12 @@ export default class SpecialVisualizations {
|
||||||
_: UIEventSource<Record<string, string>>,
|
_: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const tags = (<ThemeViewState>(
|
const tags = (<ThemeViewState>(
|
||||||
state
|
state
|
||||||
)).geolocation.currentUserLocation.features.map(
|
)).geolocation.currentUserLocation.features.map(
|
||||||
(features) => features[0]?.properties,
|
(features) => features[0]?.properties
|
||||||
)
|
)
|
||||||
return new Combine([
|
return new Combine([
|
||||||
new SvelteUIElement(OrientationDebugPanel, {}),
|
new SvelteUIElement(OrientationDebugPanel, {}),
|
||||||
|
@ -1506,7 +1520,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
return new SvelteUIElement(MarkAsFavourite, {
|
return new SvelteUIElement(MarkAsFavourite, {
|
||||||
tags: tagSource,
|
tags: tagSource,
|
||||||
|
@ -1526,7 +1540,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
return new SvelteUIElement(MarkAsFavouriteMini, {
|
return new SvelteUIElement(MarkAsFavouriteMini, {
|
||||||
tags: tagSource,
|
tags: tagSource,
|
||||||
|
@ -1546,7 +1560,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
return new SvelteUIElement(DirectionIndicator, { state, feature })
|
return new SvelteUIElement(DirectionIndicator, { state, feature })
|
||||||
},
|
},
|
||||||
|
@ -1561,7 +1575,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
tagSource
|
tagSource
|
||||||
|
@ -1583,9 +1597,9 @@ export default class SpecialVisualizations {
|
||||||
`${window.location.protocol}//${window.location.host}${window.location.pathname}?${layout}lat=${lat}&lon=${lon}&z=15` +
|
`${window.location.protocol}//${window.location.host}${window.location.pathname}?${layout}lat=${lat}&lon=${lon}&z=15` +
|
||||||
`#${id}`
|
`#${id}`
|
||||||
return new Img(new Qr(url).toImageElement(75)).SetStyle(
|
return new Img(new Qr(url).toImageElement(75)).SetStyle(
|
||||||
"width: 75px",
|
"width: 75px"
|
||||||
)
|
)
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1605,7 +1619,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
|
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
|
@ -1616,11 +1630,11 @@ export default class SpecialVisualizations {
|
||||||
})
|
})
|
||||||
.mapD((value) => {
|
.mapD((value) => {
|
||||||
const dir = GeoOperations.bearingToHuman(
|
const dir = GeoOperations.bearingToHuman(
|
||||||
GeoOperations.parseBearing(value),
|
GeoOperations.parseBearing(value)
|
||||||
)
|
)
|
||||||
console.log("Human dir", dir)
|
console.log("Human dir", dir)
|
||||||
return Translations.t.general.visualFeedback.directionsAbsolute[dir]
|
return Translations.t.general.visualFeedback.directionsAbsolute[dir]
|
||||||
}),
|
})
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1655,7 +1669,7 @@ export default class SpecialVisualizations {
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig,
|
layer: LayerConfig
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const url = args[0]
|
const url = args[0]
|
||||||
const postprocessVelopark = args[2] === "velopark"
|
const postprocessVelopark = args[2] === "velopark"
|
||||||
|
@ -1673,13 +1687,21 @@ export default class SpecialVisualizations {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
funcName: "login_button",
|
funcName: "login_button",
|
||||||
args: [
|
args: [],
|
||||||
],
|
|
||||||
docs: "Show a login button",
|
docs: "Show a login button",
|
||||||
needsUrls: [],
|
needsUrls: [],
|
||||||
constr(state: SpecialVisualizationState, tagSource: UIEventSource<Record<string, string>>, args: string[], feature: Feature, layer: LayerConfig): BaseUIElement {
|
constr(
|
||||||
return new Toggle(undefined,
|
state: SpecialVisualizationState,
|
||||||
new SvelteUIElement(LoginButton), state.osmConnection.isLoggedIn)
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
|
args: string[],
|
||||||
|
feature: Feature,
|
||||||
|
layer: LayerConfig
|
||||||
|
): BaseUIElement {
|
||||||
|
return new Toggle(
|
||||||
|
undefined,
|
||||||
|
new SvelteUIElement(LoginButton),
|
||||||
|
state.osmConnection.isLoggedIn
|
||||||
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -1693,7 +1715,7 @@ export default class SpecialVisualizations {
|
||||||
throw (
|
throw (
|
||||||
"Invalid special visualisation found: funcName is undefined for " +
|
"Invalid special visualisation found: funcName is undefined for " +
|
||||||
invalid.map((sp) => sp.i).join(", ") +
|
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…
Reference in a new issue