diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index bdd25f9..134dec0 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -12,13 +12,14 @@ import {Natuurpunt} from "./Layouts/Natuurpunt"; import {ClimbingTrees} from "./Layouts/ClimbingTrees"; import {Smoothness} from "./Layouts/Smoothness"; import {LayerDefinition} from "./LayerDefinition"; -import {CustomLayers} from "../Logic/CustomLayers"; +import {CustomLayout} from "../Logic/CustomLayers"; export class AllKnownLayouts { public static allLayers: Map = undefined; public static layoutsList: Layout[] = [ + new CustomLayout(), new Groen(), new GRB(), new Cyclofix(), @@ -30,7 +31,6 @@ export class AllKnownLayouts { new ClimbingTrees(), new Artworks(), new Smoothness(), - new CustomLayers() /*new Toilets(), */ ]; diff --git a/Customizations/LayerDefinition.ts b/Customizations/LayerDefinition.ts index be6bc27..aed16ff 100644 --- a/Customizations/LayerDefinition.ts +++ b/Customizations/LayerDefinition.ts @@ -3,6 +3,13 @@ import {UIElement} from "../UI/UIElement"; import {TagRenderingOptions} from "./TagRendering"; import {TagDependantUIElementConstructor} from "./UIElementConstructor"; +export interface Preset { + tags: Tag[], + title: string | UIElement, + description?: string | UIElement, + icon?: string +} + export class LayerDefinition { @@ -20,12 +27,7 @@ export class LayerDefinition { * These tags are added whenever a new point is added by the user on the map. * This is the ideal place to add extra info, such as "fixme=added by MapComplete, geometry should be checked" */ - presets: { - tags: Tag[], - title: string | UIElement, - description?: string | UIElement, - icon?: string - }[] + presets: Preset[] /** * Not really used anymore * This is meant to serve as icon in the buttons diff --git a/InitUiElements.ts b/InitUiElements.ts index 26ed5e6..d81890e 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -13,7 +13,6 @@ import {Tag} from "./Logic/TagsFilter"; import {FilteredLayer} from "./Logic/FilteredLayer"; import {FeatureInfoBox} from "./UI/FeatureInfoBox"; import {ElementStorage} from "./Logic/ElementStorage"; -import {Preset} from "./UI/SimpleAddUI"; import {Changes} from "./Logic/Osm/Changes"; import {OsmConnection} from "./Logic/Osm/OsmConnection"; import {BaseLayers, Basemap} from "./Logic/Leaflet/Basemap"; @@ -23,6 +22,8 @@ import {Img} from "./UI/Img"; import {DropDown} from "./UI/Input/DropDown"; import {LayerSelection} from "./UI/LayerSelection"; import {CustomLayersPanel} from "./Logic/CustomLayersPanel"; +import {CustomLayout} from "./Logic/CustomLayers"; +import {Preset} from "./Customizations/LayerDefinition"; export class InitUiElements { @@ -44,15 +45,18 @@ export class InitUiElements { private static CreateWelcomePane() { - const welcome = new WelcomeMessage() - const layoutToUse = State.state.layoutToUse.data; + let welcome: UIElement = new WelcomeMessage(); + if (layoutToUse.name === CustomLayout.NAME) { + welcome = new CustomLayersPanel(); + } + + const fullOptions = new TabbedComponent([ {header: ``, content: welcome}, {header: ``, content: Translations.t.general.openStreetMapIntro}, {header: ``, content: new ShareScreen()}, {header: ``, content: new MoreScreen()}, - {header: ``, content: new CustomLayersPanel()}, ]) return fullOptions; @@ -94,7 +98,7 @@ export class InitUiElements { } - static InitLayerSelection(layerSetup) { + static InitLayerSelection() { const closedFilterButton = ``; const openFilterButton = ``; @@ -103,9 +107,9 @@ export class InitUiElements { return {value: layer, shown: layer.name} }); const backgroundMapPicker = new Combine([new DropDown(`Background map`, baseLayerOptions, State.state.bm.CurrentLayer), openFilterButton]); - const layerSelection = new Combine([`

Maplayers

`, new LayerSelection(layerSetup.flayers)]); + const layerSelection = new Combine([`

Maplayers

`, new LayerSelection()]); let layerControl = backgroundMapPicker; - if (layerSetup.flayers.length > 1) { + if (State.state.filteredLayers.data.length > 1) { layerControl = new Combine([layerSelection, backgroundMapPicker]); } @@ -120,14 +124,11 @@ export class InitUiElements { }); } - static InitLayers(): { - minZoom: number - flayers: FilteredLayer[], - presets: Preset[] - } { - const addButtons: Preset[] = []; + + static InitLayers() { const flayers: FilteredLayer[] = [] + const presets: Preset[] = []; let minZoom = 0; const state = State.state; @@ -145,7 +146,6 @@ export class InitUiElements { minZoom = Math.max(minZoom, layer.minzoom); - const flayer = FilteredLayer.fromDefinition(layer, generateInfo); for (const preset of layer.presets ?? []) { @@ -160,25 +160,17 @@ export class InitUiElements { preset.icon = layer.style(tags)?.icon?.iconUrl; } - const addButton = { - name: preset.title, - description: preset.description, - icon: preset.icon, - tags: preset.tags, - layerToAddTo: flayer - } - addButtons.push(addButton); + presets.push(preset); } + + const flayer: FilteredLayer = FilteredLayer.fromDefinition(layer, generateInfo); flayers.push(flayer); + flayer.isDisplayed.setData(true) } - - - return { - minZoom: minZoom, - flayers: flayers, - presets: addButtons - } + State.state.filteredLayers.setData(flayers); + State.state.presets.setData(presets); + } } \ No newline at end of file diff --git a/Logic/CustomLayers.ts b/Logic/CustomLayers.ts index 042c2f2..72121f5 100644 --- a/Logic/CustomLayers.ts +++ b/Logic/CustomLayers.ts @@ -1,13 +1,13 @@ import {Layout} from "../Customizations/Layout"; import Translations from "../UI/i18n/Translations"; -export class CustomLayers extends Layout { +export class CustomLayout extends Layout { public static NAME: string = "personal"; constructor() { super( - CustomLayers.NAME, + CustomLayout.NAME, ["en"], Translations.t.favourite.title, [], diff --git a/Logic/CustomLayersPanel.ts b/Logic/CustomLayersPanel.ts index 36accf0..ede6064 100644 --- a/Logic/CustomLayersPanel.ts +++ b/Logic/CustomLayersPanel.ts @@ -9,22 +9,40 @@ import {CheckBox} from "../UI/Input/CheckBox"; import {CustomLayersState} from "./CustomLayersState"; import {VerticalCombine} from "../UI/Base/VerticalCombine"; import {FixedUiElement} from "../UI/Base/FixedUiElement"; +import {CustomLayout} from "./CustomLayers"; +import {SubtleButton} from "../UI/Base/SubtleButton"; export class CustomLayersPanel extends UIElement { - private checkboxes: UIElement[]; + private checkboxes: UIElement[] = []; + + private updateButton : UIElement; constructor() { super(State.state.favourteLayers); + this.ListenTo(State.state.osmConnection.userDetails); const t = Translations.t.favourite; - - this.checkboxes = []; - const controls = new Map>(); const favs = State.state.favourteLayers.data; + + this.updateButton = new SubtleButton("./assets/reload.svg", t.reload) + .onClick(() => { + State.state.layerUpdater.ForceRefresh(); + CustomLayersState.InitFavouriteLayers(State.state); + State.state.layoutToUse.ping(); + }) + + const controls = new Map>(); for (const layout of AllKnownLayouts.layoutsList) { + if(layout.name === CustomLayout.NAME){ + continue; + } + if (layout.hideFromOverview && State.state.osmConnection.userDetails.data.name !== "Pieter Vander Vennet") { + continue + } + const header = new Combine([ `
`, @@ -38,14 +56,23 @@ export class CustomLayersPanel extends UIElement { for (const layer of layout.layers) { const image = (layer.icon ? `` : Img.checkmark); + const noimage = (layer.icon ? `` : Img.no_checkmark); + + const content = new Combine([ + "", + "", layer.name ?? "", " ", + layer.description !== undefined ? new Combine(["
", layer.description]) : "", + "
"]) const cb = new CheckBox( new Combine([ - image, - "", layer.name ?? "", " ", layer.description ?? "" + image, content ]), new Combine([ - "", - image, "", "", layer.name ?? "", " ", layer.description ?? "" + "", + noimage, "", + "", + content, + "" ]), controls[layer.id] ?? (favs.indexOf(layer.id) >= 0) ); @@ -64,30 +91,25 @@ export class CustomLayersPanel extends UIElement { } + State.state.favourteLayers.addCallback((layers) => { + for (const layerId of layers) { + controls[layerId]?.setData(true); + } + }) + } - - State.state.favourteLayers.addCallback((layers) => { - for (const layerId of layers) { - controls[layerId].setData(true); - } - }) - } InnerRender(): string { const t = Translations.t.favourite; const userDetails = State.state.osmConnection.userDetails.data; if(!userDetails.loggedIn){ - return ""; + return t.loginNeeded.Render(); } - - if(userDetails.csCount <= 100){ - return ""; - } - - return new VerticalCombine([ + + return new Combine([ t.panelIntro, - new FixedUiElement("GO"), + this.updateButton, ...this.checkboxes ], "custom-layer-panel").Render(); } diff --git a/Logic/CustomLayersState.ts b/Logic/CustomLayersState.ts index a941083..085f119 100644 --- a/Logic/CustomLayersState.ts +++ b/Logic/CustomLayersState.ts @@ -3,35 +3,29 @@ import {State} from "../State"; export class CustomLayersState { static RemoveFavouriteLayer(layer: string) { + State.state.GetFilteredLayerFor(layer)?.isDisplayed?.setData(false); + const favs = State.state.favourteLayers.data; const ind = favs.indexOf(layer); if (ind < 0) { return; } - console.log("REmovign fav layer", layer); + favs.splice(ind, 1); - State.state.favourteLayers.ping(); + const osmConnection = State.state.osmConnection; const count = osmConnection.GetPreference("mapcomplete-custom-layer-count"); - if (favs.length === 0) { - count.setData("0") - } else if (count.data === undefined || isNaN(Number(count.data))) { - count.data = "0"; - } - const lastId = Number(count.data); - - for (let i = 0; i < lastId; i++) { + for (let i = 0; i < favs.length; i++) { const layerIDescr = osmConnection.GetPreference("mapcomplete-custom-layer-" + i); - if (layerIDescr.data === layer) { - // We found the value to remove - mark with a tombstone - layerIDescr.setData("-"); - return; - } + layerIDescr.setData(favs[i]); } + count.setData("" + favs.length) } static AddFavouriteLayer(layer: string) { + State.state.GetFilteredLayerFor(layer)?.isDisplayed?.setData(true); + const favs = State.state.favourteLayers.data; const ind = favs.indexOf(layer); if (ind >= 0) { @@ -39,7 +33,6 @@ export class CustomLayersState { } console.log("Adding fav layer", layer); favs.push(layer); - State.state.favourteLayers.ping(); const osmConnection = State.state.osmConnection; @@ -51,7 +44,7 @@ export class CustomLayersState { for (let i = 0; i < lastId; i++) { const layerIDescr = osmConnection.GetPreference("mapcomplete-custom-layer-" + i); - if (layerIDescr.data === undefined || layerIDescr.data === "-") { + if (layerIDescr.data === undefined || layerIDescr.data === "") { // An earlier item was removed -> overwrite it layerIDescr.setData(layer); count.ping(); @@ -65,12 +58,13 @@ export class CustomLayersState { count.setData((lastId + 1) + ""); } - static InitFavouriteLayer() { - const osmConnection = State.state.osmConnection; + static InitFavouriteLayers(state: State) { + const osmConnection = state.osmConnection; const count = osmConnection.GetPreference("mapcomplete-custom-layer-count"); - const favs = State.state.favourteLayers.data; + const favs = state.favourteLayers.data; let changed = false; count.addCallback((countStr) => { + console.log("UPdating favourites") if (countStr === undefined) { return; } @@ -80,13 +74,13 @@ export class CustomLayersState { } for (let i = 0; i < countI; i++) { const layerId = osmConnection.GetPreference("mapcomplete-custom-layer-" + i).data; - if (layerId !== undefined && layerId !== "-" && favs.indexOf(layerId) < 0) { - State.state.favourteLayers.data.push(layerId); + if (layerId !== undefined && layerId !== "" && favs.indexOf(layerId) < 0) { + state.favourteLayers.data.push(layerId); changed = true; } } if (changed) { - State.state.favourteLayers.ping(); + state.favourteLayers.ping(); } }) } diff --git a/Logic/LayerUpdater.ts b/Logic/LayerUpdater.ts index def77ac..dcb510f 100644 --- a/Logic/LayerUpdater.ts +++ b/Logic/LayerUpdater.ts @@ -7,9 +7,8 @@ import {Basemap} from "./Leaflet/Basemap"; import {State} from "../State"; export class LayerUpdater { - private _layers: FilteredLayer[]; - private widenFactor: number; + public readonly sufficentlyZoomed: UIEventSource = new UIEventSource(false); public readonly runningQuery: UIEventSource = new UIEventSource(false); public readonly retries: UIEventSource = new UIEventSource(0); /** @@ -17,8 +16,6 @@ export class LayerUpdater { */ private previousBounds: Bounds; - private _overpass: Overpass; - private _minzoom: number; /** * The most important layer should go first, as that one gets first pick for the questions @@ -26,28 +23,39 @@ export class LayerUpdater { * @param minzoom * @param layers */ - constructor(minzoom: number, - widenFactor: number, - layers: FilteredLayer[]) { - this.widenFactor = widenFactor; - this._layers = layers; - this._minzoom = minzoom; - var filters: TagsFilter[] = []; - for (const layer of layers) { - filters.push(layer.filters); - } - this._overpass = new Overpass(new Or(filters)); + constructor(state: State) { const self = this; - State.state.locationControl.addCallback(function () { - self.update(); + state.locationControl.addCallback(() => { + self.update(state) }); - self.update(); + state.layoutToUse.addCallback(() => { + self.update(state) + }); + + self.update(state); + } + private GetFilter(state: State) { + var filters: TagsFilter[] = []; + state = state ?? State.state; + for (const layer of state.layoutToUse.data.layers) { + if (state.locationControl.data.zoom < layer.minzoom) { + return undefined; + } + filters.push(layer.overpassFilter); + } + if (filters.length === 0) { + return undefined; + } + return new Or(filters); } private handleData(geojson: any) { const self = this; + + self.retries.setData(0); + function renderLayers(layers: FilteredLayer[]) { if (layers.length === 0) { self.runningQuery.setData(false); @@ -65,69 +73,79 @@ export class LayerUpdater { renderLayers(rest); }, 50) } - renderLayers(this._layers); + + renderLayers(State.state.filteredLayers.data); } - private handleFail(reason: any) { + private handleFail(state: State, reason: any) { + this.retries.data++; + this.ForceRefresh(); console.log(`QUERY FAILED (retrying in ${5 * this.retries.data} sec)`, reason); - this.previousBounds = undefined; - this.retries.data ++; this.retries.ping(); const self = this; window?.setTimeout( - function(){self.update()}, this.retries.data * 5000 + function () { + self.update(state) + }, this.retries.data * 5000 ) - + } - private update(): void { - if (this.IsInBounds()) { + private update(state: State): void { + if (this.IsInBounds(state)) { return; } - console.log("Zoom level: ",State.state.bm.map.getZoom(), "Least needed zoom:", this._minzoom) - if (State.state.bm.map.getZoom() < this._minzoom || State.state.bm.Location.data.zoom < this._minzoom) { + + + const filter = this.GetFilter(state); + + + this.sufficentlyZoomed.setData(filter !== undefined); + if (filter === undefined) { + console.log("Zoom insufficient to run query") return; } if (this.runningQuery.data) { console.log("Still running a query, skip"); + return; } - - const bounds = State.state.bm.map.getBounds(); - const diff = this.widenFactor; + const bounds = state.bm.map.getBounds(); + + const diff = state.layoutToUse.data.widenFactor; const n = bounds.getNorth() + diff; - const e = bounds.getEast() + diff; + const e = bounds.getEast() + diff; const s = bounds.getSouth() - diff; - const w = bounds.getWest() - diff; + const w = bounds.getWest() - diff; this.previousBounds = {north: n, east: e, south: s, west: w}; - + this.runningQuery.setData(true); const self = this; - this._overpass.queryGeoJson(this.previousBounds, + const overpass = new Overpass(filter); + overpass.queryGeoJson(this.previousBounds, function (data) { self.handleData(data) }, function (reason) { - self.handleFail(reason) + self.handleFail(state, reason) } ); } - - private IsInBounds(): boolean { + private IsInBounds(state: State): boolean { if (this.previousBounds === undefined) { return false; } - const b = State.state.bm.map.getBounds(); + const b = state.bm.map.getBounds(); if (b.getSouth() < this.previousBounds.south) { return false; } @@ -145,5 +163,9 @@ export class LayerUpdater { return true; } + + public ForceRefresh(){ + this.previousBounds = undefined; + } } \ No newline at end of file diff --git a/Logic/LocalStorageSource.ts b/Logic/LocalStorageSource.ts index f3ed37d..6000725 100644 --- a/Logic/LocalStorageSource.ts +++ b/Logic/LocalStorageSource.ts @@ -1,13 +1,17 @@ import {UIEventSource} from "../UI/UIEventSource"; +import {UIElement} from "../UI/UIElement"; export class LocalStorageSource { static Get(key: string, defaultValue: string = undefined): UIEventSource { - - //* + + if (UIElement.runningFromConsole) { + // ignore when running from the console return new UIEventSource(defaultValue); - /*/ + } + + const saved = localStorage.getItem(key); const source = new UIEventSource(saved ?? defaultValue); @@ -16,6 +20,5 @@ export class LocalStorageSource { console.log("Wriging ", key, data) }); return source; - //*/ } } \ No newline at end of file diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 465865c..edb6b79 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -303,12 +303,13 @@ export class Changes { const millisTillChangesAreSaved = state.secondsTillChangesAreSaved; const saveAfterXMillis = state.secondsTillChangesAreSaved.data * 1000; + const self= this; this.pendingChangesES.addCallback(function () { - var c = this.pendingChangesES.data; + var c = self.pendingChangesES.data; if (c > 10) { millisTillChangesAreSaved.setData(0); - this.uploadAll(undefined); + self.uploadAll(undefined); return; } @@ -319,8 +320,8 @@ export class Changes { }); millisTillChangesAreSaved.addCallback((time) => { - if (time <= 0 && this.pendingChangesES.data > 0) { - this.uploadAll(undefined); + if (time <= 0 && self.pendingChangesES.data > 0) { + self.uploadAll(undefined); } } ) diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 993654b..b5a3164 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -216,7 +216,6 @@ export class OsmConnection { self.preferences.data[k] = v; } self.preferences.ping(); - CustomLayersState.InitFavouriteLayer(); }); } @@ -234,6 +233,24 @@ export class OsmConnection { this.preferences.data[k] = v; this.preferences.ping(); + + if(v === ""){ + this.auth.xhr({ + method: 'DELETE', + path: '/api/0.6/user/preferences/' + k, + options: {header: {'Content-Type': 'text/plain'}}, + }, function (error, result) { + if (error) { + console.log("Could not remove preference", error); + return; + } + + console.log("Preference removed!", result == "" ? "OK" : result); + + }); + } + + this.auth.xhr({ method: 'PUT', path: '/api/0.6/user/preferences/' + k, diff --git a/State.ts b/State.ts index 233e052..1a3ce5e 100644 --- a/State.ts +++ b/State.ts @@ -4,7 +4,7 @@ import {QueryParameters} from "./Logic/QueryParameters"; import {LocalStorageSource} from "./Logic/LocalStorageSource"; import {Layout} from "./Customizations/Layout"; import {Utils} from "./Utils"; -import {LayerDefinition} from "./Customizations/LayerDefinition"; +import {LayerDefinition, Preset} from "./Customizations/LayerDefinition"; import {ElementStorage} from "./Logic/ElementStorage"; import {Changes} from "./Logic/Osm/Changes"; import {Basemap} from "./Logic/Leaflet/Basemap"; @@ -13,6 +13,8 @@ import Locale from "./UI/i18n/Locale"; import {VariableUiElement} from "./UI/Base/VariableUIElement"; import Translations from "./UI/i18n/Translations"; import {CustomLayersState} from "./Logic/CustomLayersState"; +import {FilteredLayer} from "./Logic/FilteredLayer"; +import {LayerUpdater} from "./Logic/LayerUpdater"; /** * Contains the global state: a bunch of UI-event sources @@ -45,7 +47,13 @@ export class State { The user crednetials */ public osmConnection: OsmConnection; - + + public layerUpdater : LayerUpdater; + + + public filteredLayers: UIEventSource = new UIEventSource([]) + public presets: UIEventSource = new UIEventSource([]) + /** * The message that should be shown at the center of the screen */ @@ -144,6 +152,7 @@ export class State { QueryParameters.GetQueryParameter("oauth_token", undefined) ); + CustomLayersState.InitFavouriteLayers(this); Locale.language.syncWith(this.osmConnection.GetPreference("language")); @@ -190,6 +199,17 @@ export class State { }) )); + this.layerUpdater = new LayerUpdater(this); } -} \ No newline at end of file + + public GetFilteredLayerFor(id: string) : FilteredLayer{ + for (const flayer of this.filteredLayers.data) { + console.log(flayer.layerDef.id, id) + if(flayer.layerDef.id === id){ + return flayer; + } + } + return undefined; + } +} diff --git a/UI/CenterMessageBox.ts b/UI/CenterMessageBox.ts index d82a14b..9656f43 100644 --- a/UI/CenterMessageBox.ts +++ b/UI/CenterMessageBox.ts @@ -6,31 +6,30 @@ import {State} from "../State"; export class CenterMessageBox extends UIElement { - private readonly _queryRunning: UIEventSource; - private startZoom: number; - constructor( - startZoom: number, - queryRunning: UIEventSource ) { super(State.state.centerMessage); - this.startZoom = startZoom; this.ListenTo(State.state.locationControl); - this.ListenTo(queryRunning); - - this._queryRunning = queryRunning; - - + this.ListenTo(State.state.layerUpdater.retries); + this.ListenTo(State.state.layerUpdater.runningQuery); + this.ListenTo(State.state.layerUpdater.sufficentlyZoomed); } private prep(): { innerHtml: string, done: boolean } { if (State.state.centerMessage.data != "") { return {innerHtml: State.state.centerMessage.data, done: false}; } - if (this._queryRunning.data) { + const lu = State.state.layerUpdater; + if(lu.retries.data > 0) { + return {innerHtml: Translations.t.centerMessage.retrying.Subs({count: ""+ lu.retries.data}).Render(), done: false}; + } + + if (lu.runningQuery.data) { return {innerHtml: Translations.t.centerMessage.loadingData.Render(), done: false}; - } else if (State.state.locationControl.data.zoom < this.startZoom) { + + } + if (!lu.sufficentlyZoomed.data) { return {innerHtml: Translations.t.centerMessage.zoomIn.Render(), done: false}; } else { return {innerHtml: Translations.t.centerMessage.ready.Render(), done: true}; diff --git a/UI/LayerSelection.ts b/UI/LayerSelection.ts index 1e0bcb6..14e9eb6 100644 --- a/UI/LayerSelection.ts +++ b/UI/LayerSelection.ts @@ -4,26 +4,27 @@ import { CheckBox } from "./Input/CheckBox"; import Combine from "./Base/Combine"; import {Utils} from "../Utils"; import {Img} from "./Img"; +import {State} from "../State"; -export class LayerSelection extends UIElement{ +export class LayerSelection extends UIElement { private readonly _checkboxes: UIElement[]; - constructor(layers: FilteredLayer[]) { - super(undefined); - this._checkboxes = []; - - for (const layer of layers) { - const checkbox = ` + constructor() { + super(undefined); + this._checkboxes = []; + + for (const layer of State.state.filteredLayers.data) { + const checkbox = ` `; - let icon = ""; - if (layer.layerDef.icon && layer.layerDef.icon !== "") { - icon = `` - } - const name = layer.layerDef.name; + let icon = ""; + if (layer.layerDef.icon && layer.layerDef.icon !== "") { + icon = `` + } + const name = layer.layerDef.name; - this._checkboxes.push(new CheckBox( + this._checkboxes.push(new CheckBox( new Combine([checkbox, icon, name]), new Combine([ Img.no_checkmark, diff --git a/UI/MoreScreen.ts b/UI/MoreScreen.ts index f15e7a1..1377ede 100644 --- a/UI/MoreScreen.ts +++ b/UI/MoreScreen.ts @@ -10,12 +10,14 @@ import {VariableUiElement} from "./Base/VariableUIElement"; import Combine from "./Base/Combine"; import {SubtleButton} from "./Base/SubtleButton"; import {State} from "../State"; +import {CustomLayout} from "../Logic/CustomLayers"; export class MoreScreen extends UIElement { constructor() { super(State.state.locationControl); + this.ListenTo(State.state.osmConnection.userDetails); } InnerRender(): string { @@ -24,12 +26,20 @@ export class MoreScreen extends UIElement { const els: UIElement[] = [] for (const k in AllKnownLayouts.allSets) { const layout = AllKnownLayouts.allSets[k] - if (layout.hideFromOverview) { + if (layout.hideFromOverview && State.state.osmConnection.userDetails.data.name !== "Pieter Vander Vennet") { continue } if (layout.name === State.state.layoutToUse.data.name) { continue; } + if (layout.name === CustomLayout.NAME) { + if (!State.state.osmConnection.userDetails.data.loggedIn) { + continue; + } + if (State.state.osmConnection.userDetails.data.csCount < 100) { + continue; + } + } const currentLocation = State.state.locationControl.data; const linkText = diff --git a/UI/SimpleAddUI.ts b/UI/SimpleAddUI.ts index 4e56327..7d4e19e 100644 --- a/UI/SimpleAddUI.ts +++ b/UI/SimpleAddUI.ts @@ -13,13 +13,6 @@ import {Changes} from "../Logic/Osm/Changes"; import {UserDetails} from "../Logic/Osm/OsmConnection"; import {State} from "../State"; -export interface Preset { - description: string | UIElement, - name: string | UIElement, - icon: string, - tags: Tag[], - layerToAddTo: FilteredLayer -} /** * Asks to add a feature at the last clicked location, at least if zoom is sufficient @@ -27,57 +20,68 @@ export interface Preset { export class SimpleAddUI extends UIElement { private _addButtons: UIElement[]; - private _dataIsLoading: UIEventSource; - - private _confirmPreset: UIEventSource - = new UIEventSource(undefined); + private _confirmPreset: UIEventSource<{ + description: string | UIElement, + name: string | UIElement, + icon: string, + tags: Tag[], + layerToAddTo: FilteredLayer + }> + = new UIEventSource(undefined); private confirmButton: UIElement = undefined; private cancelButton: UIElement; private goToInboxButton: UIElement = new SubtleButton("./assets/envelope.svg", Translations.t.general.goToInbox, {url:"https://www.openstreetmap.org/messages/inbox", newTab: false}); - constructor( - dataIsLoading: UIEventSource, - addButtons: { description: string | UIElement, name: string | UIElement; icon: string; tags: Tag[]; layerToAddTo: FilteredLayer }[], - ) { + constructor() { super(State.state.locationControl); this.ListenTo(Locale.language); this.ListenTo(State.state.osmConnection.userDetails); - - this._dataIsLoading = dataIsLoading; - this.ListenTo(dataIsLoading); - + + this.ListenTo(State.state.layerUpdater.runningQuery); + this._addButtons = []; this.ListenTo(this._confirmPreset); this.clss = "add-ui" const self = this; - for (const option of addButtons) { - //