Merge develop
This commit is contained in:
parent
c62705c1dd
commit
c167094b65
12 changed files with 251 additions and 139 deletions
assets/layers/usersettings
src
Logic
Models/ThemeConfig
UI
index_theme.ts.template
|
@ -1465,13 +1465,51 @@
|
||||||
"#force-save-button": "yes"
|
"#force-save-button": "yes"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "debug-gps",
|
"id": "debug-gps-group",
|
||||||
"condition": "mapcomplete-show_debug=yes",
|
"condition": "mapcomplete-show_debug=yes",
|
||||||
|
"render": {
|
||||||
|
"special": {
|
||||||
|
"type": "group",
|
||||||
|
"header": "debug-gps-title",
|
||||||
|
"labels": "debug-gps"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "debug-gps-title",
|
||||||
|
"labels": ["hidden"],
|
||||||
|
"render": {
|
||||||
|
"en": "GPS info"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "debug-gps",
|
||||||
|
"labels": ["hidden"],
|
||||||
"render": "{gps_all_tags()}"
|
"render": "{gps_all_tags()}"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": "debug-info-group",
|
||||||
|
"condition": "mapcomplete-show_debug=yes",
|
||||||
|
|
||||||
|
"render": {
|
||||||
|
"special": {
|
||||||
|
"type": "group",
|
||||||
|
"header": "debug-tags-title",
|
||||||
|
"labels": "debug"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "debug-tags-title",
|
||||||
|
"labels": ["hidden"],
|
||||||
|
"render": {
|
||||||
|
"en": "Debug info"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "debug",
|
"id": "debug",
|
||||||
"condition": "mapcomplete-show_debug=yes",
|
"labels": ["hidden"],
|
||||||
"render": "{all_tags()}"
|
"render": "{all_tags()}"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -14,7 +14,7 @@ export interface GeoLocationPointProperties extends GeolocationCoordinates {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract representation of the current state of the geolocation.
|
* An abstract representation of the current state of the geolocation, keeping track of permissions and if a location is known.
|
||||||
*/
|
*/
|
||||||
export class GeoLocationState {
|
export class GeoLocationState {
|
||||||
/**
|
/**
|
||||||
|
@ -167,8 +167,16 @@ export class GeoLocationState {
|
||||||
|
|
||||||
if(AndroidPolyfill.inAndroid.data){
|
if(AndroidPolyfill.inAndroid.data){
|
||||||
this.permission.setData("requested")
|
this.permission.setData("requested")
|
||||||
AndroidPolyfill.geolocationPermission.addCallbackAndRunD(state => this.permission.set(state))
|
this.permission.addCallbackAndRunD(p => {
|
||||||
this.startWatching()
|
if(p === "granted"){
|
||||||
|
this.startWatching()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
AndroidPolyfill.requestGeoPermission().then(state => {
|
||||||
|
const granted = state.value === "true"
|
||||||
|
this.permission.set(granted ? "granted" : "denied")
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,6 +218,13 @@ export class GeoLocationState {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private async startWatching() {
|
private async startWatching() {
|
||||||
|
|
||||||
|
if(AndroidPolyfill.inAndroid.data){
|
||||||
|
AndroidPolyfill.watchLocation( this.currentGPSLocation, location => {
|
||||||
|
console.log(JSON.stringify(location))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
navigator.geolocation.watchPosition(
|
navigator.geolocation.watchPosition(
|
||||||
(position: GeolocationPosition) => {
|
(position: GeolocationPosition) => {
|
||||||
this._gpsAvailable.set(true)
|
this._gpsAvailable.set(true)
|
||||||
|
|
|
@ -416,6 +416,10 @@ export default class UserRelatedState {
|
||||||
typeof window === "undefined" ? "no" : window.navigator.share ? "yes" : "no",
|
typeof window === "undefined" ? "no" : window.navigator.share ? "yes" : "no",
|
||||||
_iframe: Utils.isIframe ? "yes" : "no",
|
_iframe: Utils.isIframe ? "yes" : "no",
|
||||||
})
|
})
|
||||||
|
if(!Utils.runningFromConsole){
|
||||||
|
amendedPrefs.data["_host"] = window.location.host
|
||||||
|
amendedPrefs.data["_path"] = window.location.pathname
|
||||||
|
}
|
||||||
|
|
||||||
for (const key in Constants.userJourney) {
|
for (const key in Constants.userJourney) {
|
||||||
amendedPrefs.data["__userjourney_" + key] = Constants.userJourney[key]
|
amendedPrefs.data["__userjourney_" + key] = Constants.userJourney[key]
|
||||||
|
|
|
@ -19,9 +19,9 @@ const DatabridgePluginSingleton = registerPlugin<DatabridgePlugin>("Databridge",
|
||||||
return { value: "web" }
|
return { value: "web" }
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export class AndroidPolyfill {
|
export class AndroidPolyfill {
|
||||||
|
@ -36,12 +36,18 @@ export class AndroidPolyfill {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private backfillGeolocation(databridgePlugin: DatabridgePlugin) {
|
private backfillGeolocation(databridgePlugin: DatabridgePlugin) {
|
||||||
const src = UIEventSource.FromPromise(databridgePlugin.request({ key: "location:request-permission" }))
|
const src = UIEventSource.FromPromise(databridgePlugin.request({ key: "location:has-permission" }))
|
||||||
src.addCallbackAndRunD(permission => {
|
src.addCallbackAndRunD(permission => {
|
||||||
AndroidPolyfill._geolocationPermission.set(<"granted" | "denied">permission.value)
|
console.log("> Checking geopermission gave: ", JSON.stringify(permission), permission.value)
|
||||||
|
const granted = permission.value === "true"
|
||||||
|
AndroidPolyfill._geolocationPermission.set(granted ? "granted" : "denied")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async requestGeoPermission(): Promise<{ value: string | object }> {
|
||||||
|
return DatabridgePluginSingleton.request({ key: "location:request-permission" })
|
||||||
|
}
|
||||||
|
|
||||||
public async init() {
|
public async init() {
|
||||||
console.log("Sniffing shell version")
|
console.log("Sniffing shell version")
|
||||||
const shell = await this.databridgePlugin.request({ key: "meta" })
|
const shell = await this.databridgePlugin.request({ key: "meta" })
|
||||||
|
@ -55,9 +61,9 @@ export class AndroidPolyfill {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async requestLoginCodes() {
|
public static async requestLoginCodes() {
|
||||||
const result = await DatabridgePluginSingleton.request<{oauth_token: string}>({ key: "request:login" })
|
const result = await DatabridgePluginSingleton.request<{ oauth_token: string }>({ key: "request:login" })
|
||||||
const token: string = result.value.oauth_token
|
const token: string = result.value.oauth_token
|
||||||
console.log("AndroidPolyfill: received oauth_token; trying to pass them to the oauth lib",token)
|
console.log("AndroidPolyfill: received oauth_token; trying to pass them to the oauth lib", token)
|
||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +73,7 @@ export class AndroidPolyfill {
|
||||||
console.log("Registering back button callback", callback)
|
console.log("Registering back button callback", callback)
|
||||||
DatabridgePluginSingleton.request({ key: "backbutton" }).then(ev => {
|
DatabridgePluginSingleton.request({ key: "backbutton" }).then(ev => {
|
||||||
console.log("AndroidPolyfill: received backbutton: ", ev)
|
console.log("AndroidPolyfill: received backbutton: ", ev)
|
||||||
if(ev === null){
|
if (ev === null) {
|
||||||
// Probably in web environment
|
// Probably in web environment
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -84,5 +90,26 @@ export class AndroidPolyfill {
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static watchLocation(writeInto: UIEventSource<GeolocationCoordinates>, callback: (location) => void) {
|
||||||
|
DatabridgePluginSingleton.request({
|
||||||
|
key: "location:watch",
|
||||||
|
}).then((l: {
|
||||||
|
value: { latitude: number, longitude: number, accuraccy: number, altidude: number, heading: number, speed:number }
|
||||||
|
}) => {
|
||||||
|
// example l: {"value":{"latitude":51.0618627,"longitude":3.730468566666667,"accuracy":2.0393495559692383,"altitude":46.408,"heading":168.2969970703125}}
|
||||||
|
console.log("Received location from Android:", JSON.stringify(l))
|
||||||
|
const loc = l.value
|
||||||
|
writeInto.set({
|
||||||
|
latitude: loc.latitude,
|
||||||
|
longitude: loc.longitude,
|
||||||
|
heading: loc.heading,
|
||||||
|
accuracy: loc.accuraccy,
|
||||||
|
altitude: loc.altidude,
|
||||||
|
altitudeAccuracy: undefined,
|
||||||
|
speed: loc.speed,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,9 @@ export default class TagRenderingConfig {
|
||||||
this.id
|
this.id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
if(json.labels && !Array.isArray( json.labels)){
|
||||||
|
throw (`Invalid labels at ${context}: labels should be a list of strings, but got a ${typeof json.labels}`)
|
||||||
|
}
|
||||||
|
|
||||||
this.labels = json.labels ?? []
|
this.labels = json.labels ?? []
|
||||||
if (typeof json.classes === "string") {
|
if (typeof json.classes === "string") {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import { ariaLabel } from "../../Utils/ariaLabel"
|
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||||
import { Translation } from "../i18n/Translation"
|
import { Translation } from "../i18n/Translation"
|
||||||
import Backspace from "@babeard/svelte-heroicons/outline/Backspace"
|
import Backspace from "@babeard/svelte-heroicons/outline/Backspace"
|
||||||
|
import { AndroidPolyfill } from "../../Logic/Web/AndroidPolyfill"
|
||||||
|
|
||||||
export let value: UIEventSource<string>
|
export let value: UIEventSource<string>
|
||||||
let _value = value.data ?? ""
|
let _value = value.data ?? ""
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
if (autofocus) {
|
if (autofocus) {
|
||||||
isFocused.set(true)
|
isFocused.set(true)
|
||||||
}
|
}
|
||||||
|
let isAndroid = AndroidPolyfill.inAndroid
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="w-full" on:submit|preventDefault={() => dispatch("search")}>
|
<form class="w-full" on:submit|preventDefault={() => dispatch("search")}>
|
||||||
|
@ -62,18 +64,20 @@
|
||||||
use:set_placeholder={placeholder}
|
use:set_placeholder={placeholder}
|
||||||
use:ariaLabel={placeholder}
|
use:ariaLabel={placeholder}
|
||||||
/>
|
/>
|
||||||
|
{#if !isAndroid}
|
||||||
{#if $value.length > 0}
|
<!-- Show a 'clear field' icon in the searchbar. The android-build already provides this for us, hence the outer if -->
|
||||||
<Backspace
|
{#if $value.length > 0}
|
||||||
on:click={(e) => {
|
<Backspace
|
||||||
|
on:click={(e) => {
|
||||||
value.set("")
|
value.set("")
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
}}
|
}}
|
||||||
color="var(--button-background)"
|
color="var(--button-background)"
|
||||||
class="mr-3 h-6 w-6 cursor-pointer"
|
class="mr-3 h-6 w-6 cursor-pointer"
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="mr-3 w-6" />
|
<div class="mr-3 w-6" />
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</label>
|
</label>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import Location_locked from "../../assets/svg/Location_locked.svelte"
|
import Location_locked from "../../assets/svg/Location_locked.svelte"
|
||||||
import Location_unlocked from "../../assets/svg/Location_unlocked.svelte"
|
import Location_unlocked from "../../assets/svg/Location_unlocked.svelte"
|
||||||
import Location from "../../assets/svg/Location.svelte"
|
import Location from "../../assets/svg/Location.svelte"
|
||||||
|
import Location_empty from "../../assets/svg/Location_empty.svelte"
|
||||||
|
|
||||||
export let state: ThemeViewState
|
export let state: ThemeViewState
|
||||||
let geolocationstate = state.geolocation.geolocationState
|
let geolocationstate = state.geolocation.geolocationState
|
||||||
|
@ -31,10 +32,10 @@
|
||||||
{:else if $geopermission === "denied" || !$isAvailable}
|
{:else if $geopermission === "denied" || !$isAvailable}
|
||||||
<Location_refused class={clss} />
|
<Location_refused class={clss} />
|
||||||
{:else if $geopermission === "prompt"}
|
{:else if $geopermission === "prompt"}
|
||||||
<Location class={clss} />
|
<Location_empty class={clss} />
|
||||||
{:else if $geopermission === "requested"}
|
{:else if $geopermission === "requested"}
|
||||||
<!-- Even though disabled, when clicking we request the location again in case the contributor dismissed the location popup -->
|
<!-- Even though disabled, when clicking we request the location again in case the contributor dismissed the location popup -->
|
||||||
<Location class={clss} style="animation: 3s linear 0s infinite normal none running spin;" />
|
<Location_empty class={clss} style="animation: 3s linear 0s infinite normal none running spin;" />
|
||||||
{:else}
|
{:else}
|
||||||
<Location class={clss} style="animation: 3s linear 0s infinite normal none running spin;" />
|
<Location class={clss} style="animation: 3s linear 0s infinite normal none running spin;" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -319,7 +319,7 @@
|
||||||
if (state?.osmConnection) {
|
if (state?.osmConnection) {
|
||||||
onDestroy(
|
onDestroy(
|
||||||
state.osmConnection?.userDetails?.addCallbackAndRun((ud) => {
|
state.osmConnection?.userDetails?.addCallbackAndRun((ud) => {
|
||||||
numberOfCs = ud.csCount
|
numberOfCs = ud?.csCount
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,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,
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
const isOpen = args[0] === "open"
|
const isOpen = args[0] === "open"
|
||||||
const readonly = args[1] === "readonly" || args[1] === "yes"
|
const readonly = args[1] === "readonly" || args[1] === "yes"
|
||||||
|
@ -189,7 +189,7 @@ class StealViz implements SpecialVisualization {
|
||||||
selectedElement: otherFeature,
|
selectedElement: otherFeature,
|
||||||
state,
|
state,
|
||||||
layer,
|
layer,
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (elements.length === 1) {
|
if (elements.length === 1) {
|
||||||
|
@ -197,8 +197,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],
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,11 +250,11 @@ class CloseNoteViz implements SpecialVisualization {
|
||||||
public constr(
|
public constr(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
args: string[]
|
args: string[],
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
const { text, icon, idkey, comment, minZoom, zoomButton } = Utils.ParseVisArgs(
|
const { text, icon, idkey, comment, minZoom, zoomButton } = Utils.ParseVisArgs(
|
||||||
this.args,
|
this.args,
|
||||||
args
|
args,
|
||||||
)
|
)
|
||||||
|
|
||||||
return new SvelteUIElement(CloseNoteButton, {
|
return new SvelteUIElement(CloseNoteButton, {
|
||||||
|
@ -295,7 +295,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,
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
const labels = args[0]
|
const labels = args[0]
|
||||||
?.split(";")
|
?.split(";")
|
||||||
|
@ -327,7 +327,7 @@ export default class SpecialVisualizations {
|
||||||
for (const specialVisualization of SpecialVisualizations.specialVisualizations) {
|
for (const specialVisualization of SpecialVisualizations.specialVisualizations) {
|
||||||
SpecialVisualizations.specialVisualisationsDict.set(
|
SpecialVisualizations.specialVisualisationsDict.set(
|
||||||
specialVisualization.funcName,
|
specialVisualization.funcName,
|
||||||
specialVisualization
|
specialVisualization,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,15 +347,15 @@ export default class SpecialVisualizations {
|
||||||
viz.docs,
|
viz.docs,
|
||||||
viz.args.length > 0
|
viz.args.length > 0
|
||||||
? MarkdownUtils.table(
|
? MarkdownUtils.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,
|
||||||
"#### Example usage of " + viz.funcName,
|
"#### Example usage of " + viz.funcName,
|
||||||
"<code>" + example + "</code>",
|
"<code>" + example + "</code>",
|
||||||
|
@ -364,18 +364,18 @@ export default class SpecialVisualizations {
|
||||||
|
|
||||||
public static constructSpecification(
|
public static constructSpecification(
|
||||||
template: string,
|
template: string,
|
||||||
extraMappings: SpecialVisualization[] = []
|
extraMappings: SpecialVisualization[] = [],
|
||||||
): RenderingSpecification[] {
|
): RenderingSpecification[] {
|
||||||
return SpecialVisualisationUtils.constructSpecification(
|
return SpecialVisualisationUtils.constructSpecification(
|
||||||
template,
|
template,
|
||||||
SpecialVisualizations.specialVisualisationsDict,
|
SpecialVisualizations.specialVisualisationsDict,
|
||||||
extraMappings
|
extraMappings,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HelpMessage(): string {
|
public static HelpMessage(): string {
|
||||||
const helpTexts: string[] = SpecialVisualizations.specialVisualizations.map((viz) =>
|
const helpTexts: string[] = SpecialVisualizations.specialVisualizations.map((viz) =>
|
||||||
SpecialVisualizations.DocumentationFor(viz)
|
SpecialVisualizations.DocumentationFor(viz),
|
||||||
)
|
)
|
||||||
|
|
||||||
const firstPart = new Combine([
|
const firstPart = new Combine([
|
||||||
|
@ -408,10 +408,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")
|
||||||
.AsMarkdown()
|
.AsMarkdown()
|
||||||
|
@ -452,7 +452,7 @@ export default class SpecialVisualizations {
|
||||||
(ud) => ud?.languages ?? []
|
(ud) => ud?.languages ?? []
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -491,7 +491,7 @@ export default class SpecialVisualizations {
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tagSource: UIEventSource<Record<string, string>>,
|
tagSource: UIEventSource<Record<string, string>>,
|
||||||
args: string[],
|
args: string[],
|
||||||
feature: Feature
|
feature: Feature,
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
return new SvelteUIElement(MinimapViz, { state, args, feature, tagSource })
|
return new SvelteUIElement(MinimapViz, { state, args, feature, tagSource })
|
||||||
},
|
},
|
||||||
|
@ -503,7 +503,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
|
||||||
|
@ -513,7 +513,7 @@ export default class SpecialVisualizations {
|
||||||
return new SvelteUIElement(SplitRoadWizard, { id, state })
|
return new SvelteUIElement(SplitRoadWizard, { id, state })
|
||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -527,7 +527,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
|
||||||
|
@ -550,7 +550,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
|
||||||
|
@ -576,7 +576,7 @@ export default class SpecialVisualizations {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig
|
layer: LayerConfig,
|
||||||
) {
|
) {
|
||||||
if (feature.geometry.type !== "LineString") {
|
if (feature.geometry.type !== "LineString") {
|
||||||
return undefined
|
return undefined
|
||||||
|
@ -608,7 +608,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, {
|
||||||
|
@ -671,7 +671,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(
|
||||||
|
@ -681,9 +681,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(),
|
||||||
|
@ -697,7 +697,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 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -782,7 +782,7 @@ export default class SpecialVisualizations {
|
||||||
nameKey: nameKey,
|
nameKey: nameKey,
|
||||||
fallbackName,
|
fallbackName,
|
||||||
},
|
},
|
||||||
state.featureSwitchIsTesting
|
state.featureSwitchIsTesting,
|
||||||
)
|
)
|
||||||
return new SvelteUIElement(StarsBarIcon, {
|
return new SvelteUIElement(StarsBarIcon, {
|
||||||
score: reviews.average,
|
score: reviews.average,
|
||||||
|
@ -821,7 +821,7 @@ export default class SpecialVisualizations {
|
||||||
nameKey: nameKey,
|
nameKey: nameKey,
|
||||||
fallbackName,
|
fallbackName,
|
||||||
},
|
},
|
||||||
state.featureSwitchIsTesting
|
state.featureSwitchIsTesting,
|
||||||
)
|
)
|
||||||
return new SvelteUIElement(ReviewForm, {
|
return new SvelteUIElement(ReviewForm, {
|
||||||
reviews,
|
reviews,
|
||||||
|
@ -859,7 +859,7 @@ export default class SpecialVisualizations {
|
||||||
nameKey: nameKey,
|
nameKey: nameKey,
|
||||||
fallbackName,
|
fallbackName,
|
||||||
},
|
},
|
||||||
state.featureSwitchIsTesting
|
state.featureSwitchIsTesting,
|
||||||
)
|
)
|
||||||
return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer })
|
return new SvelteUIElement(AllReviews, { reviews, state, tags, feature, layer })
|
||||||
},
|
},
|
||||||
|
@ -889,7 +889,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 Combine([
|
return new Combine([
|
||||||
SpecialVisualizations.specialVisualisationsDict
|
SpecialVisualizations.specialVisualisationsDict
|
||||||
|
@ -914,7 +914,7 @@ export default class SpecialVisualizations {
|
||||||
constr(
|
constr(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
_: UIEventSource<Record<string, string>>,
|
_: UIEventSource<Record<string, string>>,
|
||||||
argument: string[]
|
argument: string[],
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const [text] = argument
|
const [text] = argument
|
||||||
return new SvelteUIElement(ImportReviewIdentity, { state, text })
|
return new SvelteUIElement(ImportReviewIdentity, { state, text })
|
||||||
|
@ -971,7 +971,7 @@ export default class SpecialVisualizations {
|
||||||
constr(
|
constr(
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
args: string[]
|
args: string[],
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
const keyToUse = args[0]
|
const keyToUse = args[0]
|
||||||
const prefix = args[1]
|
const prefix = args[1]
|
||||||
|
@ -1008,17 +1008,17 @@ export default class SpecialVisualizations {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
const allUnits: Unit[] = [].concat(
|
const allUnits: Unit[] = [].concat(
|
||||||
...(state?.theme?.layers?.map((lyr) => lyr.units) ?? [])
|
...(state?.theme?.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)
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1072,7 +1072,7 @@ export default class SpecialVisualizations {
|
||||||
constr: (state) => {
|
constr: (state) => {
|
||||||
return new SubtleButton(
|
return new SubtleButton(
|
||||||
new SvelteUIElement(Trash),
|
new SvelteUIElement(Trash),
|
||||||
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)
|
||||||
|
@ -1113,10 +1113,10 @@ export default class SpecialVisualizations {
|
||||||
new SvelteUIElement(NoteCommentElement, {
|
new SvelteUIElement(NoteCommentElement, {
|
||||||
comment,
|
comment,
|
||||||
state,
|
state,
|
||||||
})
|
}),
|
||||||
)
|
),
|
||||||
).SetClass("flex flex-col")
|
).SetClass("flex flex-col")
|
||||||
})
|
}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1149,7 +1149,7 @@ export default class SpecialVisualizations {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
_: string[],
|
_: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig
|
layer: LayerConfig,
|
||||||
) => {
|
) => {
|
||||||
return new SvelteUIElement(FeatureTitle, { state, tags, feature, layer })
|
return new SvelteUIElement(FeatureTitle, { state, tags, feature, layer })
|
||||||
},
|
},
|
||||||
|
@ -1167,8 +1167,8 @@ export default class SpecialVisualizations {
|
||||||
const challenge = Stores.FromPromise(
|
const challenge = Stores.FromPromise(
|
||||||
Utils.downloadJsonCached<MaprouletteTask>(
|
Utils.downloadJsonCached<MaprouletteTask>(
|
||||||
`${Maproulette.defaultEndpoint}/challenge/${parentId}`,
|
`${Maproulette.defaultEndpoint}/challenge/${parentId}`,
|
||||||
24 * 60 * 60 * 1000
|
24 * 60 * 60 * 1000,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
|
@ -1193,7 +1193,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.",
|
||||||
|
@ -1207,15 +1207,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" +
|
||||||
|
@ -1291,7 +1291,7 @@ export default class SpecialVisualizations {
|
||||||
(l) =>
|
(l) =>
|
||||||
l.name !== null &&
|
l.name !== null &&
|
||||||
l.title &&
|
l.title &&
|
||||||
state.perLayer.get(l.id) !== undefined
|
state.perLayer.get(l.id) !== undefined,
|
||||||
)
|
)
|
||||||
.map(
|
.map(
|
||||||
(l) => {
|
(l) => {
|
||||||
|
@ -1301,8 +1301,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],
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1372,7 +1372,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[],
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
let [text, href, classnames, download, ariaLabel, icon] = args
|
let [text, href, classnames, download, ariaLabel, icon] = args
|
||||||
if (download === "") {
|
if (download === "") {
|
||||||
|
@ -1410,7 +1410,7 @@ export default class SpecialVisualizations {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
" "
|
" ",
|
||||||
) +
|
) +
|
||||||
"\n```",
|
"\n```",
|
||||||
args: [
|
args: [
|
||||||
|
@ -1434,7 +1434,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 ?? ""
|
||||||
|
@ -1452,7 +1452,7 @@ export default class SpecialVisualizations {
|
||||||
"Could not create a special visualization for multi(",
|
"Could not create a special visualization for multi(",
|
||||||
args.join(", ") + ")",
|
args.join(", ") + ")",
|
||||||
"no properties found for object",
|
"no properties found for object",
|
||||||
feature.properties.id
|
feature.properties.id,
|
||||||
)
|
)
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
@ -1469,7 +1469,7 @@ export default class SpecialVisualizations {
|
||||||
elements.push(subsTr)
|
elements.push(subsTr)
|
||||||
}
|
}
|
||||||
return elements
|
return elements
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1489,7 +1489,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) => {
|
||||||
|
@ -1501,7 +1501,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)
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1521,7 +1521,7 @@ export default class SpecialVisualizations {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: 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]
|
||||||
return new SvelteUIElement(FediverseLink, { key, tags, state })
|
return new SvelteUIElement(FediverseLink, { key, tags, state })
|
||||||
|
@ -1543,7 +1543,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] + "}")
|
||||||
},
|
},
|
||||||
|
@ -1564,7 +1564,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(
|
||||||
|
@ -1582,12 +1582,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")
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1608,7 +1608,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 })
|
||||||
|
@ -1624,15 +1624,24 @@ 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 geostate = (<ThemeViewState>(state)).geolocation.geolocationState
|
||||||
state
|
const tags = geostate.currentGPSLocation.map(
|
||||||
)).geolocation.currentUserLocation.features.map(
|
(geoloc) => {
|
||||||
(features) => features[0]?.properties
|
const tags = { }
|
||||||
|
for (const k in geoloc ?? {}) {
|
||||||
|
tags[k] = geoloc[k]
|
||||||
|
}
|
||||||
|
tags["_permission"] = geostate.permission.data,
|
||||||
|
tags["_request_moment"] = geostate.requestMoment.data
|
||||||
|
return tags
|
||||||
|
},
|
||||||
|
[geostate.permission, geostate.requestMoment]
|
||||||
)
|
)
|
||||||
|
|
||||||
return new Combine([
|
return new Combine([
|
||||||
new SvelteUIElement(OrientationDebugPanel, {}),
|
new SvelteUIElement(OrientationDebugPanel, {}), // compass and gyroscope info
|
||||||
new SvelteUIElement(AllTagsPanel, {
|
new SvelteUIElement(AllTagsPanel, {
|
||||||
state,
|
state,
|
||||||
tags,
|
tags,
|
||||||
|
@ -1651,7 +1660,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,
|
||||||
|
@ -1671,7 +1680,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,
|
||||||
|
@ -1691,7 +1700,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 })
|
||||||
},
|
},
|
||||||
|
@ -1704,7 +1713,7 @@ export default class SpecialVisualizations {
|
||||||
state: SpecialVisualizationState,
|
state: SpecialVisualizationState,
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature
|
feature: Feature,
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
return new SvelteUIElement(QrCode, { state, tags, feature })
|
return new SvelteUIElement(QrCode, { state, tags, feature })
|
||||||
},
|
},
|
||||||
|
@ -1723,7 +1732,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 {
|
||||||
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
|
const key = args[0] === "" ? "_direction:centerpoint" : args[0]
|
||||||
return new VariableUiElement(
|
return new VariableUiElement(
|
||||||
|
@ -1734,11 +1743,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]
|
||||||
})
|
}),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1768,7 +1777,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 readonly = args[3] === "yes"
|
const readonly = args[3] === "yes"
|
||||||
|
@ -1794,12 +1803,12 @@ 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 Toggle(
|
return new Toggle(
|
||||||
undefined,
|
undefined,
|
||||||
new SvelteUIElement(LoginButton, { osmConnection: state.osmConnection }),
|
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>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
feature: Feature,
|
feature: Feature,
|
||||||
layer: LayerConfig
|
layer: LayerConfig,
|
||||||
): BaseUIElement {
|
): BaseUIElement {
|
||||||
const key = argument[0] ?? "website"
|
const key = argument[0] ?? "website"
|
||||||
const useProxy = argument[1] !== "no"
|
const useProxy = argument[1] !== "no"
|
||||||
|
@ -1845,7 +1854,7 @@ export default class SpecialVisualizations {
|
||||||
const isClosed = (argument[4] ?? "yes") === "yes"
|
const isClosed = (argument[4] ?? "yes") === "yes"
|
||||||
|
|
||||||
const countryStore: Store<string | undefined> = tags.mapD(
|
const countryStore: Store<string | undefined> = tags.mapD(
|
||||||
(tags) => tags._country
|
(tags) => tags._country,
|
||||||
)
|
)
|
||||||
const sourceUrl: Store<string | undefined> = tags.mapD((tags) => {
|
const sourceUrl: Store<string | undefined> = tags.mapD((tags) => {
|
||||||
if (!tags[key] || tags[key] === "undefined") {
|
if (!tags[key] || tags[key] === "undefined") {
|
||||||
|
@ -1867,24 +1876,24 @@ export default class SpecialVisualizations {
|
||||||
const features =
|
const features =
|
||||||
await LinkedDataLoader.fetchVeloparkEntry(
|
await LinkedDataLoader.fetchVeloparkEntry(
|
||||||
url,
|
url,
|
||||||
loadAll
|
loadAll,
|
||||||
)
|
)
|
||||||
const feature =
|
const feature =
|
||||||
features.find(
|
features.find(
|
||||||
(f) => f.properties["ref:velopark"] === url
|
(f) => f.properties["ref:velopark"] === url,
|
||||||
) ?? features[0]
|
) ?? features[0]
|
||||||
const properties = feature.properties
|
const properties = feature.properties
|
||||||
properties["ref:velopark"] = url
|
properties["ref:velopark"] = url
|
||||||
console.log(
|
console.log(
|
||||||
"Got properties from velopark:",
|
"Got properties from velopark:",
|
||||||
properties
|
properties,
|
||||||
)
|
)
|
||||||
return properties
|
return properties
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
})()
|
})(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (country === undefined) {
|
if (country === undefined) {
|
||||||
|
@ -1896,29 +1905,29 @@ export default class SpecialVisualizations {
|
||||||
return await LinkedDataLoader.fetchJsonLd(
|
return await LinkedDataLoader.fetchJsonLd(
|
||||||
url,
|
url,
|
||||||
{ country },
|
{ country },
|
||||||
useProxy ? "proxy" : "fetch-lod"
|
useProxy ? "proxy" : "fetch-lod",
|
||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(
|
console.log(
|
||||||
"Could not get with proxy/download LOD, attempting to download directly. Error for ",
|
"Could not get with proxy/download LOD, attempting to download directly. Error for ",
|
||||||
url,
|
url,
|
||||||
"is",
|
"is",
|
||||||
e
|
e,
|
||||||
)
|
)
|
||||||
return await LinkedDataLoader.fetchJsonLd(
|
return await LinkedDataLoader.fetchJsonLd(
|
||||||
url,
|
url,
|
||||||
{ country },
|
{ country },
|
||||||
"fetch-raw"
|
"fetch-raw",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})()
|
})(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
[countryStore]
|
[countryStore],
|
||||||
)
|
)
|
||||||
|
|
||||||
externalData.addCallbackAndRunD((lod) =>
|
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(
|
return new Toggle(
|
||||||
|
@ -1933,7 +1942,7 @@ export default class SpecialVisualizations {
|
||||||
collapsed: isClosed,
|
collapsed: isClosed,
|
||||||
}),
|
}),
|
||||||
undefined,
|
undefined,
|
||||||
sourceUrl.map((url) => !!url)
|
sourceUrl.map((url) => !!url),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1953,7 +1962,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 text = argument[0]
|
const text = argument[0]
|
||||||
const cssClasses = argument[1]
|
const cssClasses = argument[1]
|
||||||
|
@ -1975,7 +1984,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 translation = tagSource.map((tags) => {
|
const translation = tagSource.map((tags) => {
|
||||||
const layer = state.theme.getMatchingLayer(tags)
|
const layer = state.theme.getMatchingLayer(tags)
|
||||||
|
@ -2007,7 +2016,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,
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
return new SvelteUIElement<any, any, any>(ClearCaches, {
|
return new SvelteUIElement<any, any, any>(ClearCaches, {
|
||||||
msg: argument[0] ?? "Clear local caches",
|
msg: argument[0] ?? "Clear local caches",
|
||||||
|
@ -2032,7 +2041,7 @@ export default class SpecialVisualizations {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
selectedElement: Feature,
|
selectedElement: Feature,
|
||||||
layer: LayerConfig
|
layer: LayerConfig,
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
const [header, labelsStr] = argument
|
const [header, labelsStr] = argument
|
||||||
const labels = labelsStr.split(";").map((x) => x.trim())
|
const labels = labelsStr.split(";").map((x) => x.trim())
|
||||||
|
@ -2055,7 +2064,7 @@ export default class SpecialVisualizations {
|
||||||
tags: UIEventSource<Record<string, string>>,
|
tags: UIEventSource<Record<string, string>>,
|
||||||
argument: string[],
|
argument: string[],
|
||||||
selectedElement: Feature,
|
selectedElement: Feature,
|
||||||
layer: LayerConfig
|
layer: LayerConfig,
|
||||||
): SvelteUIElement {
|
): SvelteUIElement {
|
||||||
const t = Translations.t.preset_type
|
const t = Translations.t.preset_type
|
||||||
const question: QuestionableTagRenderingConfigJson = {
|
const question: QuestionableTagRenderingConfigJson = {
|
||||||
|
@ -2095,7 +2104,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 text = argument[0]
|
const text = argument[0]
|
||||||
return new SubtleButton(undefined, text).onClick(() => {
|
return new SubtleButton(undefined, text).onClick(() => {
|
||||||
|
@ -2126,7 +2135,7 @@ export default class SpecialVisualizations {
|
||||||
"Invalid special visualisation found: funcName is undefined or doesn't match " +
|
"Invalid special visualisation found: funcName is undefined or doesn't match " +
|
||||||
regex +
|
regex +
|
||||||
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"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import MetaTagging from "./src/Logic/MetaTagging";
|
||||||
import { FixedUiElement } from "./src/UI/Base/FixedUiElement";
|
import { FixedUiElement } from "./src/UI/Base/FixedUiElement";
|
||||||
import { Utils } from "./src/Utils"
|
import { Utils } from "./src/Utils"
|
||||||
import Constants from "./src/Models/Constants"
|
import Constants from "./src/Models/Constants"
|
||||||
|
import { AndroidPolyfill } from "./src/Logic/Web/AndroidPolyfill"
|
||||||
|
|
||||||
function webgl_support() {
|
function webgl_support() {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -19,5 +19,5 @@
|
||||||
"esModuleInterop": true
|
"esModuleInterop": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "test", "scripts"]
|
"exclude": ["node_modules", "test", "scripts","android","dist","dist-full"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,11 +21,21 @@ export default defineConfig({
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
input,
|
input,
|
||||||
|
external:[
|
||||||
|
"android"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
base: `${ASSET_URL}`,
|
base: `${ASSET_URL}`,
|
||||||
plugins ,
|
plugins ,
|
||||||
server: {
|
server: {
|
||||||
port: 1234,
|
port: 1234,
|
||||||
|
watch:{
|
||||||
|
ignored: [
|
||||||
|
"**/android/**",
|
||||||
|
'**/.git/**',
|
||||||
|
'**/dist/**'
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue