From 604daf760040a88f2e650ce0069206dd6201e62f Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Wed, 22 Jul 2020 23:47:04 +0200 Subject: [PATCH] Made query string track the location --- Logic/QueryParameters.ts | 58 ++++++++++++++++++++++++++++++++++++++++ index.ts | 54 ++++++++++++++++++++----------------- test.ts | 15 ++++------- 3 files changed, 92 insertions(+), 35 deletions(-) create mode 100644 Logic/QueryParameters.ts diff --git a/Logic/QueryParameters.ts b/Logic/QueryParameters.ts new file mode 100644 index 0000000..47006c6 --- /dev/null +++ b/Logic/QueryParameters.ts @@ -0,0 +1,58 @@ +/** + * Wraps the query parameters into UIEventSources + */ +import {UIEventSource} from "../UI/UIEventSource"; + +export class QueryParameters { + + private static order: string [] = ["layout","test","zoom","lat","lon"]; + private static knownSources = QueryParameters.init(); + + private static addOrder(key){ + if(this.order.indexOf(key) < 0){ + this.order.push(key) + } + } + + private static init() { + const knownSources = {} + if (window.location.search) { + const params = window.location.search.substr(1).split("&"); + for (const param of params) { + const kv = param.split("="); + const key = kv[0]; + QueryParameters.addOrder(key) + const v = kv[1]; + const source = new UIEventSource(v); + source.addCallback(() => QueryParameters.Serialize()) + knownSources[key] = source; + } + } + return knownSources; + } + + private static Serialize() { + const parts = [] + for (const key of QueryParameters.order) { + if (QueryParameters.knownSources[key] === undefined || QueryParameters.knownSources[key].data === undefined) { + continue; + } + parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(QueryParameters.knownSources[key].data)) + } + parts.sort(); + history.replaceState(null, "", "?" + parts.join("&")); + + } + + public static GetQueryParameter(key: string): UIEventSource { + if (QueryParameters.knownSources[key] !== undefined) { + return QueryParameters.knownSources[key]; + } + QueryParameters.addOrder(key); + const source = new UIEventSource(undefined); + QueryParameters.knownSources[key] = source; + source.addCallback(() => QueryParameters.Serialize()) + return source; + } + +} \ No newline at end of file diff --git a/index.ts b/index.ts index b971e53..2dbc9ea 100644 --- a/index.ts +++ b/index.ts @@ -29,6 +29,7 @@ import {FixedUiElement} from "./UI/Base/FixedUiElement"; import {LayerSelection} from "./UI/LayerSelection"; import Combine from "./UI/Base/Combine"; import {Img} from "./UI/Img"; +import {QueryParameters} from "./Logic/QueryParameters"; // --------------------- Read the URL parameters ----------------- @@ -72,23 +73,8 @@ for (const k in AllKnownLayouts.allSets) { } } -// Read the query string to grap settings -let paramDict: any = {}; -if (window.location.search) { - const params = window.location.search.substr(1).split("&"); - for (const param of params) { - var kv = param.split("="); - paramDict[kv[0]] = kv[1]; - } -} - -if (paramDict.layout) { - defaultLayout = paramDict.layout -} - -if (paramDict.test) { - dryRun = paramDict.test === "true"; -} +defaultLayout = QueryParameters.GetQueryParameter("layout").data ?? defaultLayout; +dryRun = QueryParameters.GetQueryParameter("test").data === "true"; const layoutToUse: Layout = AllKnownLayouts.allSets[defaultLayout]; console.log("Using layout: ", layoutToUse.name); @@ -102,10 +88,6 @@ Locale.language.addCallback(e => { // ----------------- Setup a few event sources ------------- -// const LanguageSelect = document.getElementById('language-select') as HTMLOptionElement -// eLanguageSelect.addEventListener('selectionchange') - - // The message that should be shown at the center of the screen const centerMessage = new UIEventSource(""); @@ -118,15 +100,37 @@ const secondsTillChangesAreSaved = new UIEventSource(0); const fullScreenMessage = new UIEventSource(undefined); // The latest element that was selected - used to generate the right UI at the right place -const selectedElement = new UIEventSource<{feature: any}>(undefined); +const selectedElement = new UIEventSource<{ feature: any }>(undefined); +function clean(str) : number{ + if (str) { + const i = parseFloat(str); + if (isNaN(i)) { + return undefined; + } + return i; + } + return undefined; +} + +const zoom = QueryParameters.GetQueryParameter("z"); +const lat = QueryParameters.GetQueryParameter("lat"); +const lon = QueryParameters.GetQueryParameter("lon"); + const locationControl = new UIEventSource<{ lat: number, lon: number, zoom: number }>({ - zoom: layoutToUse.startzoom, - lat: layoutToUse.startLat, - lon: layoutToUse.startLon + zoom: clean(zoom.data) ?? layoutToUse.startzoom, + lat: clean(lat.data) ?? layoutToUse.startLat, + lon: clean(lon.data) ?? layoutToUse.startLon }); +locationControl.addCallback((latlonz) => { + zoom.setData(latlonz.zoom.toString()); + + lat.setData(latlonz.lat.toString().substr(0,6)); + lon.setData(latlonz.lon.toString().substr(0,6)); +}) + // ----------------- Prepare the important objects ----------------- diff --git a/test.ts b/test.ts index 15d721f..6489560 100644 --- a/test.ts +++ b/test.ts @@ -1,14 +1,9 @@ -import { DropDown } from "./UI/Input/DropDown"; -import { BaseLayers, Basemap } from "./Logic/Basemap"; +import {QueryParameters} from "./Logic/QueryParameters"; -let baseLayerOptions = []; +console.log("Hi"); -Object.entries(BaseLayers.baseLayers).forEach(([key, value], i) => { -// console.log(key, value, i); - baseLayerOptions.push({value: i, shown: key}); -}); +const layout = QueryParameters.GetQueryParameter("layout").addCallback(console.log) -console.log(Basemap); +console.log("Layout is", layout.data) - -new DropDown(`label`, baseLayerOptions, Basemap.CurrentLayer).AttachTo("maindiv"); \ No newline at end of file +window.setTimeout(() => {layout.setData("XXX"), 2000}) \ No newline at end of file