Fix personal theme, add possibility to sync layer selection

This commit is contained in:
pietervdvn 2022-02-14 18:18:05 +01:00
parent 4f45fed45a
commit 419f2b1351
10 changed files with 68 additions and 36 deletions

View file

@ -138,7 +138,6 @@ export class OsmPreferences {
const prefixes = ["mapcomplete-installed-theme", "mapcomplete-installed-themes-", "mapcomplete-current-open-changeset", "mapcomplete-personal-theme-layer"] const prefixes = ["mapcomplete-installed-theme", "mapcomplete-installed-themes-", "mapcomplete-current-open-changeset", "mapcomplete-personal-theme-layer"]
for (const key in prefs) { for (const key in prefs) {
for (const prefix of prefixes) { for (const prefix of prefixes) {
// console.log(key)
if (key.startsWith(prefix)) { if (key.startsWith(prefix)) {
console.log("Clearing ", key) console.log("Clearing ", key)
self.GetPreference(key, "").setData("") self.GetPreference(key, "").setData("")
@ -173,8 +172,9 @@ export class OsmPreferences {
// We merge all the preferences: new keys are uploaded // We merge all the preferences: new keys are uploaded
// For differing values, the server overrides local changes // For differing values, the server overrides local changes
self.preferenceSources.forEach((preference, key) => { self.preferenceSources.forEach((preference, key) => {
const osmValue = self.preferences[key] const osmValue = self.preferences.data[key]
if(osmValue === undefined){ console.log("Sending value to osm:", key," osm has: ", osmValue, " local has: ", preference.data)
if(osmValue === undefined && preference.data !== undefined){
// OSM doesn't know this value yet // OSM doesn't know this value yet
self.UploadPreference(key, preference.data) self.UploadPreference(key, preference.data)
} else { } else {

View file

@ -146,17 +146,17 @@ export default class FeatureSwitchState {
this.featureSwitchIsTesting = QueryParameters.GetBooleanQueryParameter( this.featureSwitchIsTesting = QueryParameters.GetBooleanQueryParameter(
"test", "test",
"" + testingDefaultValue, testingDefaultValue,
"If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org" "If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org"
) )
this.featureSwitchIsDebugging = QueryParameters.GetBooleanQueryParameter( this.featureSwitchIsDebugging = QueryParameters.GetBooleanQueryParameter(
"debug", "debug",
"false", false,
"If true, shows some extra debugging help such as all the available tags on every object" "If true, shows some extra debugging help such as all the available tags on every object"
) )
this.featureSwitchFakeUser = QueryParameters.GetBooleanQueryParameter("fake-user", "false", this.featureSwitchFakeUser = QueryParameters.GetBooleanQueryParameter("fake-user", false,
"If true, 'dryrun' mode is activated and a fake user account is loaded") "If true, 'dryrun' mode is activated and a fake user account is loaded")

View file

@ -10,7 +10,6 @@ import BaseUIElement from "../../UI/BaseUIElement";
import FilteredLayer, {FilterState} from "../../Models/FilteredLayer"; import FilteredLayer, {FilterState} from "../../Models/FilteredLayer";
import TilesourceConfig from "../../Models/ThemeConfig/TilesourceConfig"; import TilesourceConfig from "../../Models/ThemeConfig/TilesourceConfig";
import {QueryParameters} from "../Web/QueryParameters"; import {QueryParameters} from "../Web/QueryParameters";
import * as personal from "../../assets/themes/personal/personal.json";
import ShowOverlayLayer from "../../UI/ShowDataLayer/ShowOverlayLayer"; import ShowOverlayLayer from "../../UI/ShowDataLayer/ShowOverlayLayer";
import {FeatureSourceForLayer, Tiled} from "../FeatureSource/FeatureSource"; import {FeatureSourceForLayer, Tiled} from "../FeatureSource/FeatureSource";
import SimpleFeatureSource from "../FeatureSource/Sources/SimpleFeatureSource"; import SimpleFeatureSource from "../FeatureSource/Sources/SimpleFeatureSource";
@ -18,7 +17,7 @@ import {LocalStorageSource} from "../Web/LocalStorageSource";
import {GeoOperations} from "../GeoOperations"; import {GeoOperations} from "../GeoOperations";
import TitleHandler from "../Actors/TitleHandler"; import TitleHandler from "../Actors/TitleHandler";
import {BBox} from "../BBox"; import {BBox} from "../BBox";
import MetaTagging from "../MetaTagging"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
/** /**
* Contains all the leaflet-map related state * Contains all the leaflet-map related state
@ -120,7 +119,7 @@ export default class MapState extends UserRelatedState {
this.overlayToggles = this.layoutToUse.tileLayerSources.filter(c => c.name !== undefined).map(c => ({ this.overlayToggles = this.layoutToUse.tileLayerSources.filter(c => c.name !== undefined).map(c => ({
config: c, config: c,
isDisplayed: QueryParameters.GetBooleanQueryParameter("overlay-" + c.id, "" + c.defaultState, "Wether or not the overlay " + c.id + " is shown") isDisplayed: QueryParameters.GetBooleanQueryParameter("overlay-" + c.id, c.defaultState, "Wether or not the overlay " + c.id + " is shown")
})) }))
this.filteredLayers = this.InitializeFilteredLayers() this.filteredLayers = this.InitializeFilteredLayers()
@ -345,24 +344,41 @@ export default class MapState extends UserRelatedState {
} }
private getPref(key: string, layer: LayerConfig): UIEventSource<boolean> {
const pref = this.osmConnection
.GetPreference(key)
.map(v => {
if(v === undefined){
return undefined
}
return v === "true";
}, [], b => {
if(b === undefined){
return undefined
}
return "" + b;
})
pref.setData(layer.shownByDefault)
return pref
}
private InitializeFilteredLayers() { private InitializeFilteredLayers() {
const layoutToUse = this.layoutToUse; const layoutToUse = this.layoutToUse;
const flayers: FilteredLayer[] = []; const flayers: FilteredLayer[] = [];
for (const layer of layoutToUse.layers) { for (const layer of layoutToUse.layers) {
let isDisplayed: UIEventSource<boolean> let isDisplayed: UIEventSource<boolean>
if (layoutToUse.id === personal.id) { if (layer.syncSelection === "local") {
isDisplayed = this.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled") isDisplayed = LocalStorageSource.GetParsed(layoutToUse.id + "-layer-" + layer.id + "-enabled", layer.shownByDefault)
.map(value => value === "yes", [], enabled => { } else if (layer.syncSelection === "theme-only") {
return enabled ? "yes" : ""; isDisplayed = this.getPref(layoutToUse.id+ "-layer-" + layer.id + "-enabled", layer)
}) } else if (layer.syncSelection === "global") {
isDisplayed = this.getPref("layer-" + layer.id + "-enabled", layer)
} else { } else {
isDisplayed = QueryParameters.GetBooleanQueryParameter( isDisplayed = QueryParameters.GetBooleanQueryParameter("layer-" + layer.id + "-enabled",layer.shownByDefault, "Wether or not layer "+layer.id+" is shown")
"layer-" + layer.id,
"" + layer.shownByDefault,
"Wether or not layer " + layer.id + " is shown"
)
} }
const flayer: FilteredLayer = { const flayer: FilteredLayer = {
isDisplayed: isDisplayed, isDisplayed: isDisplayed,
layerDef: layer, layerDef: layer,
@ -380,14 +396,14 @@ export default class MapState extends UserRelatedState {
} }
for (const layer of layoutToUse.layers) { for (const layer of layoutToUse.layers) {
if(layer.filterIsSameAs === undefined){ if (layer.filterIsSameAs === undefined) {
continue continue
} }
const toReuse = flayers.find(l => l.layerDef.id === layer.filterIsSameAs) const toReuse = flayers.find(l => l.layerDef.id === layer.filterIsSameAs)
if(toReuse === undefined){ if (toReuse === undefined) {
throw "Error in layer "+layer.id+": it defines that it should be use the filters of "+layer.filterIsSameAs+", but this layer was not loaded" throw "Error in layer " + layer.id + ": it defines that it should be use the filters of " + layer.filterIsSameAs + ", but this layer was not loaded"
} }
console.warn("Linking filter and isDisplayed-states of "+layer.id+" and "+layer.filterIsSameAs) console.warn("Linking filter and isDisplayed-states of " + layer.id + " and " + layer.filterIsSameAs)
const selfLayer = flayers.findIndex(l => l.layerDef.id === layer.id) const selfLayer = flayers.findIndex(l => l.layerDef.id === layer.id)
flayers[selfLayer] = { flayers[selfLayer] = {
isDisplayed: toReuse.isDisplayed, isDisplayed: toReuse.isDisplayed,
@ -395,7 +411,7 @@ export default class MapState extends UserRelatedState {
appliedFilters: toReuse.appliedFilters appliedFilters: toReuse.appliedFilters
}; };
} }
return new UIEventSource<FilteredLayer[]>(flayers); return new UIEventSource<FilteredLayer[]>(flayers);
} }

View file

@ -326,8 +326,10 @@ export class UIEventSource<T> {
this.addCallback((latest) => otherSource.setData(latest)); this.addCallback((latest) => otherSource.setData(latest));
const self = this; const self = this;
otherSource.addCallback((latest) => self.setData(latest)); otherSource.addCallback((latest) => self.setData(latest));
if (reverseOverride && otherSource.data !== undefined) { if (reverseOverride) {
this.setData(otherSource.data); if(otherSource.data !== undefined){
this.setData(otherSource.data);
}
} else if (this.data === undefined) { } else if (this.data === undefined) {
this.setData(otherSource.data); this.setData(otherSource.data);
} else { } else {

View file

@ -32,8 +32,8 @@ export class QueryParameters {
return source; return source;
} }
public static GetBooleanQueryParameter(key: string, deflt: string, documentation?: string): UIEventSource<boolean> { public static GetBooleanQueryParameter(key: string, deflt: boolean, documentation?: string): UIEventSource<boolean> {
return QueryParameters.GetQueryParameter(key, deflt, documentation).map(str => str === "true", [], b => "" + b) return QueryParameters.GetQueryParameter(key, ""+ deflt, documentation).map(str => str === "true", [], b => "" + b)
} }

View file

@ -399,4 +399,13 @@ export interface LayerConfigJson {
*/ */
units?: UnitConfigJson[] units?: UnitConfigJson[]
/**
* If set, synchronizes wether or not this layer is selected.
*
* no: Do not sync at all, always revert to default
* local: keep selection on local storage
* theme-only: sync via OSM, but this layer will only be toggled in this theme
* global: all layers with this ID will be synced accross all themes
*/
syncSelection?: "no" | "local" | "theme-only" | "global"
} }

View file

@ -61,6 +61,8 @@ export default class LayerConfig extends WithContextLoader {
public readonly filterIsSameAs: string; public readonly filterIsSameAs: string;
public readonly forceLoad: boolean; public readonly forceLoad: boolean;
public readonly syncSelection: "no" | "local" | "theme-only" | "global"
constructor( constructor(
json: LayerConfigJson, json: LayerConfigJson,
context?: string, context?: string,
@ -90,7 +92,7 @@ export default class LayerConfig extends WithContextLoader {
} }
this.maxAgeOfCache = json.source.maxCacheAge ?? 24 * 60 * 60 * 30 this.maxAgeOfCache = json.source.maxCacheAge ?? 24 * 60 * 60 * 30
this.syncSelection = json.syncSelection;
const osmTags = TagUtils.Tag( const osmTags = TagUtils.Tag(
json.source.osmTags, json.source.osmTags,
context + "source.osmTags" context + "source.osmTags"

View file

@ -22,27 +22,27 @@ export class DefaultGuiState {
)); ));
this.welcomeMessageIsOpened = QueryParameters.GetBooleanQueryParameter( this.welcomeMessageIsOpened = QueryParameters.GetBooleanQueryParameter(
"welcome-control-toggle", "welcome-control-toggle",
"false", false,
"Whether or not the welcome panel is shown" "Whether or not the welcome panel is shown"
) )
this.downloadControlIsOpened = QueryParameters.GetBooleanQueryParameter( this.downloadControlIsOpened = QueryParameters.GetBooleanQueryParameter(
"download-control-toggle", "download-control-toggle",
"false", false,
"Whether or not the download panel is shown" "Whether or not the download panel is shown"
) )
this.filterViewIsOpened = QueryParameters.GetBooleanQueryParameter( this.filterViewIsOpened = QueryParameters.GetBooleanQueryParameter(
"filter-toggle", "filter-toggle",
"false", false,
"Whether or not the filter view is shown" "Whether or not the filter view is shown"
) )
this.copyrightViewIsOpened = QueryParameters.GetBooleanQueryParameter( this.copyrightViewIsOpened = QueryParameters.GetBooleanQueryParameter(
"copyright-toggle", "copyright-toggle",
"false", false,
"Whether or not the copyright view is shown" "Whether or not the copyright view is shown"
) )
this.currentViewControlIsOpened = QueryParameters.GetBooleanQueryParameter( this.currentViewControlIsOpened = QueryParameters.GetBooleanQueryParameter(
"currentview-toggle", "currentview-toggle",
"false", false,
"Whether or not the current view box is shown" "Whether or not the current view box is shown"
) )
const states = { const states = {

View file

@ -34,5 +34,6 @@
"width": 3, "width": 3,
"color": "#bb000077" "color": "#bb000077"
} }
] ],
"syncSelection": "global"
} }

View file

@ -40,7 +40,9 @@
"#note": "The 'overpassMaxZoom' should be exactly the same as or less then the overrideAll", "#note": "The 'overpassMaxZoom' should be exactly the same as or less then the overrideAll",
"overpassMaxZoom": 15, "overpassMaxZoom": 15,
"overrideAll": { "overrideAll": {
"minZoom": 16 "minZoom": 16,
"syncSelection": "theme",
"shownByDefault": false
}, },
"layers": [] "layers": []
} }