From 2c49aa8d4eea36ddae1623dfa524a2ccc505c23e Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 23 Aug 2023 21:08:59 +0200 Subject: [PATCH 1/3] Prototype of alternative add flow --- .../Sources/LastClickFeatureSource.ts | 53 +++++++------ src/Models/ThemeViewState.ts | 13 +++- src/UI/ThemeViewGUI.svelte | 77 +++++++++++-------- 3 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/Logic/FeatureSource/Sources/LastClickFeatureSource.ts b/src/Logic/FeatureSource/Sources/LastClickFeatureSource.ts index ecd8d82884..a8c4623f72 100644 --- a/src/Logic/FeatureSource/Sources/LastClickFeatureSource.ts +++ b/src/Logic/FeatureSource/Sources/LastClickFeatureSource.ts @@ -13,6 +13,11 @@ import { Utils } from "../../../Utils" export class LastClickFeatureSource implements WritableFeatureSource { public readonly features: UIEventSource = new UIEventSource([]) + private i: number = 0 + private readonly renderings: string[] + private readonly has_note_layer: string + private readonly has_presets: string + constructor(location: Store<{ lon: number; lat: number }>, layout: LayoutConfig) { const allPresets: BaseUIElement[] = [] for (const layer of layout.layers) @@ -26,35 +31,39 @@ export class LastClickFeatureSource implements WritableFeatureSource { allPresets.push(html) } - const renderings = Utils.Dedup( + this.renderings = Utils.Dedup( allPresets.map((uiElem) => Utils.runningFromConsole ? "" : uiElem.ConstructElement().innerHTML ) ) - let i = 0 + this.has_note_layer = layout.layers.some((l) => l.id === "note") ? "yes" : "no" + + this.has_presets = layout.layers.some((l) => l.presets?.length > 0) ? "yes" : "no" location.addCallbackAndRunD(({ lon, lat }) => { - const properties = { - lastclick: "yes", - id: "last_click_" + i, - has_note_layer: layout.layers.some((l) => l.id === "note") ? "yes" : "no", - has_presets: layout.layers.some((l) => l.presets?.length > 0) ? "yes" : "no", - renderings: renderings.join(""), - number_of_presets: "" + renderings.length, - first_preset: renderings[0], - } - i++ - - const point = >{ - type: "Feature", - properties, - geometry: { - type: "Point", - coordinates: [lon, lat], - }, - } - this.features.setData([point]) + this.features.setData([this.createFeature(lon, lat)]) }) } + + public createFeature(lon: number, lat: number): Feature { + const properties = { + lastclick: "yes", + id: "last_click_" + this.i, + has_note_layer: this.has_note_layer, + has_presets: this.has_presets, + renderings: this.renderings.join(""), + number_of_presets: "" + this.renderings.length, + first_preset: this.renderings[0], + } + this.i++ + return >{ + type: "Feature", + properties, + geometry: { + type: "Point", + coordinates: [lon, lat], + }, + } + } } diff --git a/src/Models/ThemeViewState.ts b/src/Models/ThemeViewState.ts index 778576654f..6724eac7c2 100644 --- a/src/Models/ThemeViewState.ts +++ b/src/Models/ThemeViewState.ts @@ -102,7 +102,7 @@ export default class ThemeViewState implements SpecialVisualizationState { readonly userRelatedState: UserRelatedState readonly geolocation: GeoLocationHandler - readonly lastClickObject: WritableFeatureSource + readonly lastClickObject: WritableFeatureSource & LastClickFeatureSource readonly overlayLayerStates: ReadonlyMap< string, { readonly isDisplayed: UIEventSource } @@ -452,9 +452,16 @@ export default class ThemeViewState implements SpecialVisualizationState { ) } + public openNewItemDialog() { + this.selectedElement.setData(undefined) + this.selectedLayer.setData(this.layerState.filteredLayers.get("last_click").layerDef) + const { lon, lat } = this.mapProperties.location.data + const feature = this.lastClickObject.createFeature(lon, lat) + this.selectedElement.setData(feature) + } private addLastClick(last_click: LastClickFeatureSource) { // The last_click gets a _very_ special treatment as it interacts with various parts - + /* const last_click_layer = this.layerState.filteredLayers.get("last_click") this.featureProperties.trackFeatureSource(last_click) this.indexedFeatures.addSource(last_click) @@ -489,7 +496,7 @@ export default class ThemeViewState implements SpecialVisualizationState { this.selectedElement.setData(feature) this.selectedLayer.setData(last_click_layer.layerDef) }, - }) + }) //*/ } /** diff --git a/src/UI/ThemeViewGUI.svelte b/src/UI/ThemeViewGUI.svelte index e69d73fd5b..6edb510d73 100644 --- a/src/UI/ThemeViewGUI.svelte +++ b/src/UI/ThemeViewGUI.svelte @@ -53,62 +53,62 @@ import Locale from "./i18n/Locale"; import ShareScreen from "./BigComponents/ShareScreen.svelte"; - export let state: ThemeViewState - let layout = state.layout + export let state: ThemeViewState; + let layout = state.layout; - let maplibremap: UIEventSource = state.map - let selectedElement: UIEventSource = state.selectedElement - let selectedLayer: UIEventSource = state.selectedLayer + let maplibremap: UIEventSource = state.map; + let selectedElement: UIEventSource = state.selectedElement; + let selectedLayer: UIEventSource = state.selectedLayer; const selectedElementView = selectedElement.map( (selectedElement) => { // Svelte doesn't properly reload some of the legacy UI-elements // As such, we _reconstruct_ the selectedElementView every time a new feature is selected // This is a bit wasteful, but until everything is a svelte-component, this should do the trick - const layer = selectedLayer.data + const layer = selectedLayer.data; if (selectedElement === undefined || layer === undefined) { - return undefined + return undefined; } if (!(layer.tagRenderings?.length > 0) || layer.title === undefined) { - return undefined + return undefined; } - const tags = state.featureProperties.getStore(selectedElement.properties.id) - return new SvelteUIElement(SelectedElementView, { state, layer, selectedElement, tags }) + const tags = state.featureProperties.getStore(selectedElement.properties.id); + return new SvelteUIElement(SelectedElementView, { state, layer, selectedElement, tags }); }, [selectedLayer] - ) + ); const selectedElementTitle = selectedElement.map( (selectedElement) => { // Svelte doesn't properly reload some of the legacy UI-elements // As such, we _reconstruct_ the selectedElementView every time a new feature is selected // This is a bit wasteful, but until everything is a svelte-component, this should do the trick - const layer = selectedLayer.data + const layer = selectedLayer.data; if (selectedElement === undefined || layer === undefined) { - return undefined + return undefined; } - const tags = state.featureProperties.getStore(selectedElement.properties.id) - return new SvelteUIElement(SelectedElementTitle, { state, layer, selectedElement, tags }) + const tags = state.featureProperties.getStore(selectedElement.properties.id); + return new SvelteUIElement(SelectedElementTitle, { state, layer, selectedElement, tags }); }, [selectedLayer] - ) + ); - let mapproperties: MapProperties = state.mapProperties - let featureSwitches: FeatureSwitchState = state.featureSwitches - let availableLayers = state.availableLayers - let userdetails = state.osmConnection.userDetails - let currentViewLayer = layout.layers.find((l) => l.id === "current_view") - let rasterLayer: Store = state.mapProperties.rasterLayer + let mapproperties: MapProperties = state.mapProperties; + let featureSwitches: FeatureSwitchState = state.featureSwitches; + let availableLayers = state.availableLayers; + let userdetails = state.osmConnection.userDetails; + let currentViewLayer = layout.layers.find((l) => l.id === "current_view"); + let rasterLayer: Store = state.mapProperties.rasterLayer; let rasterLayerName = - rasterLayer.data?.properties?.name ?? AvailableRasterLayers.maplibre.properties.name + rasterLayer.data?.properties?.name ?? AvailableRasterLayers.maplibre.properties.name; onDestroy( rasterLayer.addCallbackAndRunD((l) => { - rasterLayerName = l.properties.name + rasterLayerName = l.properties.name; }) - ) + );
@@ -170,16 +170,25 @@
@@ -314,12 +323,12 @@ new CopyrightPanel(state)} slot="content3" /> -
+
- +
From 89434014c69c179b191c13740fe24e47b2b655a6 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 23 Aug 2023 21:16:20 +0200 Subject: [PATCH 2/3] Fix: toggle button if not zoomed in enough --- src/UI/ThemeViewGUI.svelte | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/UI/ThemeViewGUI.svelte b/src/UI/ThemeViewGUI.svelte index 6edb510d73..77b9d8db59 100644 --- a/src/UI/ThemeViewGUI.svelte +++ b/src/UI/ThemeViewGUI.svelte @@ -171,9 +171,16 @@
- + }}> + Add a new point + + +
From bfb70c8593174ab651467bf94510aff7099aa701 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Sat, 16 Sep 2023 02:55:13 +0200 Subject: [PATCH 3/3] Usability: give error message if WebGL is disabled --- src/index.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index ebdabc56ec..2a5b2600c6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,9 +7,22 @@ import Combine from "./UI/Base/Combine" import { SubtleButton } from "./UI/Base/SubtleButton" import Svg from "./Svg" import { Utils } from "./Utils" - +function webgl_support() { + try { + var canvas = document.createElement("canvas") + return ( + !!window.WebGLRenderingContext && + (canvas.getContext("webgl") || canvas.getContext("experimental-webgl")) + ) + } catch (e) { + return false + } +} // @ts-ignore try { + if (!webgl_support()) { + throw "WebGL is not supported or not enabled. This is essential for MapComplete to function, please enable this." + } DetermineLayout.GetLayout() .then((layout) => { const state = new ThemeViewState(layout)