diff --git a/Logic/DetermineLayout.ts b/Logic/DetermineLayout.ts index 90ee115f2..4fae151d3 100644 --- a/Logic/DetermineLayout.ts +++ b/Logic/DetermineLayout.ts @@ -9,7 +9,6 @@ import BaseUIElement from "../UI/BaseUIElement"; import {UIEventSource} from "./UIEventSource"; import {LocalStorageSource} from "./Web/LocalStorageSource"; import LZString from "lz-string"; -import * as personal from "../assets/themes/personal/personal.json"; import {FixLegacyTheme} from "../Models/ThemeConfig/Conversion/LegacyJsonConvert"; import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson"; import SharedTagRenderings from "../Customizations/SharedTagRenderings"; @@ -52,17 +51,7 @@ export default class DetermineLayout { console.log("Using layout", layoutId); } layoutId = QueryParameters.GetQueryParameter("layout", layoutId, "The layout to load into MapComplete").data; - const layoutToUse: LayoutConfig = AllKnownLayouts.allKnownLayouts.get(layoutId?.toLowerCase()); - - if (layoutToUse?.id === personal.id) { - layoutToUse.layers = AllKnownLayouts.AllPublicLayers() - for (const layer of layoutToUse.layers) { - layer.minzoomVisible = Math.max(layer.minzoomVisible, layer.minzoom) - layer.minzoom = Math.max(16, layer.minzoom) - } - } - - return layoutToUse + return AllKnownLayouts.allKnownLayouts.get(layoutId?.toLowerCase()) } public static LoadLayoutFromHash( @@ -161,7 +150,8 @@ export default class DetermineLayout { } const converState = { tagRenderings: SharedTagRenderings.SharedTagRenderingJson, - sharedLayers: knownLayersDict + sharedLayers: knownLayersDict, + publicLayers: new Set() } json = new FixLegacyTheme().convertStrict(json, "While loading a dynamic theme") const raw = json; diff --git a/Models/Constants.ts b/Models/Constants.ts index ac9b884aa..7d583c5be 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.20.1"; + public static vNumber = "0.20.2"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" @@ -23,7 +23,7 @@ export default class Constants { /** * Layer IDs of layers which have special properties through built-in hooks */ - public static readonly priviliged_layers: string[] = [...Constants.added_by_default, "type_node", "note", "import_candidate", ...Constants.no_include] + public static readonly priviliged_layers: string[] = [...Constants.added_by_default, "type_node", "note", "import_candidate", "direction", ...Constants.no_include] // The user journey states thresholds when a new feature gets unlocked diff --git a/Models/ThemeConfig/Conversion/Conversion.ts b/Models/ThemeConfig/Conversion/Conversion.ts index bc5ff9f64..63e8a181d 100644 --- a/Models/ThemeConfig/Conversion/Conversion.ts +++ b/Models/ThemeConfig/Conversion/Conversion.ts @@ -4,7 +4,8 @@ import {Utils} from "../../../Utils"; export interface DesugaringContext { tagRenderings: Map - sharedLayers: Map + sharedLayers: Map, + publicLayers: Set } export abstract class Conversion { diff --git a/Models/ThemeConfig/Conversion/PrepareTheme.ts b/Models/ThemeConfig/Conversion/PrepareTheme.ts index f580007bf..772aa56bc 100644 --- a/Models/ThemeConfig/Conversion/PrepareTheme.ts +++ b/Models/ThemeConfig/Conversion/PrepareTheme.ts @@ -453,9 +453,16 @@ class PreparePersonalTheme extends DesugaringStep { if (json.id !== "personal") { return {result: json} } + + // The only thing this _really_ does, is adding the layer-ids into 'layers' + // All other preparations are done by the 'override-all'-block in personal.json - json.layers = Array.from(this._state.sharedLayers.keys()).filter(l => Constants.priviliged_layers.indexOf(l) < 0) - return {result: json}; + json.layers = Array.from(this._state.sharedLayers.keys()) + .filter(l => Constants.priviliged_layers.indexOf(l) < 0) + .filter(l => this._state.publicLayers.has(l)) + return {result: json, information: [ + "The personal theme has "+json.layers.length+" public layers" + ]}; } } diff --git a/Models/ThemeConfig/Json/LayerConfigJson.ts b/Models/ThemeConfig/Json/LayerConfigJson.ts index 4264d3565..68687fde1 100644 --- a/Models/ThemeConfig/Json/LayerConfigJson.ts +++ b/Models/ThemeConfig/Json/LayerConfigJson.ts @@ -426,7 +426,7 @@ export interface LayerConfigJson { units?: UnitConfigJson[] /** - * If set, synchronizes wether or not this layer is selected. + * If set, synchronizes whether or not this layer is enabled. * * no: Do not sync at all, always revert to default * local: keep selection on local storage diff --git a/Models/ThemeConfig/LayerConfig.ts b/Models/ThemeConfig/LayerConfig.ts index 24fc810bd..635691fcd 100644 --- a/Models/ThemeConfig/LayerConfig.ts +++ b/Models/ThemeConfig/LayerConfig.ts @@ -65,7 +65,8 @@ export default class LayerConfig extends WithContextLoader { public readonly filterIsSameAs: string; public readonly forceLoad: boolean; - public readonly syncSelection: "no" | "local" | "theme-only" | "global" + public static readonly syncSelectionAllowed = ["no" , "local" , "theme-only" , "global"] as const; + public readonly syncSelection: (typeof LayerConfig.syncSelectionAllowed)[number] // this is a trick to conver a constant array of strings into a type union of these values constructor( json: LayerConfigJson, @@ -97,7 +98,10 @@ export default class LayerConfig extends WithContextLoader { } this.maxAgeOfCache = json.source.maxCacheAge ?? 24 * 60 * 60 * 30 - this.syncSelection = json.syncSelection; + if(json.syncSelection !== undefined && LayerConfig.syncSelectionAllowed.indexOf(json.syncSelection) < 0){ + throw context+ " Invalid sync-selection: must be one of "+LayerConfig.syncSelectionAllowed.map(v => `'${v}'`).join(", ")+" but got '"+json.syncSelection+"'" + } + this.syncSelection = json.syncSelection ?? "no"; const osmTags = TagUtils.Tag( json.source.osmTags, context + "source.osmTags" diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index ff28d1de0..52fa5c664 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -223,7 +223,9 @@ export default class FeatureInfoBox extends ScrollableFullScreen { return new Combine([new TagRenderingAnswer(tags, config_all_tags, state), new TagRenderingAnswer(tags, config_download, state), - new TagRenderingAnswer(tags, config_id, state)]) + new TagRenderingAnswer(tags, config_id, state), + "This is layer "+layerConfig.id + ]) } }) ) diff --git a/assets/themes/personal/personal.json b/assets/themes/personal/personal.json index 16cf8bd6c..738729787 100644 --- a/assets/themes/personal/personal.json +++ b/assets/themes/personal/personal.json @@ -41,8 +41,9 @@ "overpassMaxZoom": 15, "overrideAll": { "minzoom": 17, - "syncSelection": "theme", + "syncSelection": "theme-only", "shownByDefault": false }, + "enableNoteImports": false, "layers": [] } \ No newline at end of file diff --git a/scripts/generateLayerOverview.ts b/scripts/generateLayerOverview.ts index 19239fc2b..4fc206475 100644 --- a/scripts/generateLayerOverview.ts +++ b/scripts/generateLayerOverview.ts @@ -13,8 +13,6 @@ import PointRenderingConfigJson from "../Models/ThemeConfig/Json/PointRenderingC import {PrepareLayer} from "../Models/ThemeConfig/Conversion/PrepareLayer"; import {PrepareTheme} from "../Models/ThemeConfig/Conversion/PrepareTheme"; import {DesugaringContext} from "../Models/ThemeConfig/Conversion/Conversion"; -import LayerConfig from "../Models/ThemeConfig/LayerConfig"; -import LayerConfigJsonJSC from "../Docs/Schemas/LayerConfigJsonJSC"; import {Utils} from "../Utils"; // This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files. @@ -190,7 +188,8 @@ class LayerOverviewUtils { const sharedLayers = new Map() const state: DesugaringContext = { tagRenderings: sharedTagRenderings, - sharedLayers + sharedLayers, + publicLayers: new Set() } const prepLayer = new PrepareLayer(state); for (const sharedLayerJson of layerFiles) { @@ -210,15 +209,43 @@ class LayerOverviewUtils { } return sharedLayers; } + + private static publicLayerIdsFrom(themefiles: LayoutConfigJson[]): Set{ + const publicLayers = [].concat(...themefiles + .filter(th => !th.hideFromOverview) + .map(th => th.layers)) + + const publicLayerIds = new Set() + for (const publicLayer of publicLayers) { + if(typeof publicLayer === "string"){ + publicLayerIds.add(publicLayer) + continue + } + if(publicLayer["builtin"] !== undefined){ + const bi = publicLayer["builtin"] + if(typeof bi === "string"){ + publicLayerIds.add(bi) + continue + } + bi.forEach(id=>publicLayerIds.add(id)) + continue + } + publicLayerIds.add(publicLayer.id) + } + return publicLayerIds + } private buildThemeIndex(knownImagePaths: Set, sharedLayers: Map): Map { console.log(" ---------- VALIDATING BUILTIN THEMES ---------") const themeFiles = ScriptUtils.getThemeFiles(); const fixed = new Map(); + const publicLayers = LayerOverviewUtils.publicLayerIdsFrom(themeFiles.map(th => th.parsed)) + const convertState: DesugaringContext = { sharedLayers, - tagRenderings: this.getSharedTagRenderings() + tagRenderings: this.getSharedTagRenderings(), + publicLayers } for (const themeInfo of themeFiles) { let themeFile = themeInfo.parsed