diff --git a/InitUiElements.ts b/InitUiElements.ts index 202e64149..40932dfd2 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -323,9 +323,7 @@ export class InitUiElements { State.state.backgroundLayer, State.state.locationControl, State.state.availableBackgroundLayers, - State.state.layoutToUse.map( - (layout: LayoutConfig) => layout.defaultBackgroundId - ) + State.state.layoutToUse.defaultBackgroundId ); const attr = new Attribution( @@ -345,7 +343,7 @@ export class InitUiElements { }).SetClass("w-full h-full") .AttachTo("leafletDiv") - const layout = State.state.layoutToUse.data; + const layout = State.state.layoutToUse; if (layout.lockLocation) { if (layout.lockLocation === true) { const tile = Tiles.embedded_tile( @@ -375,66 +373,66 @@ export class InitUiElements { const state = State.state; const empty = [] - state.filteredLayers = state.layoutToUse.map((layoutToUse) => { - const flayers: FilteredLayer[] = []; + const flayers: FilteredLayer[] = []; - for (const layer of layoutToUse.layers) { - let defaultShown = "true" - if(layoutToUse.id === personal.id){ - defaultShown = "false" - } - - let isDisplayed: UIEventSource - if(layoutToUse.id === personal.id){ - isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled") - .map(value => value === "yes", [], enabled => { - return enabled ? "yes" : ""; - }) - isDisplayed.addCallbackAndRun(d =>console.log("IsDisplayed for layer", layer.id, "is currently", d) ) - }else{ - isDisplayed = QueryParameters.GetQueryParameter( - "layer-" + layer.id, - defaultShown, - "Wether or not layer " + layer.id + " is shown" - ).map( - (str) => str !== "false", - [], - (b) => b.toString() - ); - } - const flayer = { - isDisplayed: isDisplayed, - layerDef: layer, - appliedFilters: new UIEventSource<{ filter: FilterConfig, selected: number }[]>([]), - }; - - if (layer.filters.length > 0) { - const filtersPerName = new Map() - layer.filters.forEach(f => filtersPerName.set(f.id, f)) - const qp = QueryParameters.GetQueryParameter("filter-" + layer.id, "","Filtering state for a layer") - flayer.appliedFilters.map(filters => { - filters = filters ?? [] - return filters.map(f => f.filter.id + "." + f.selected).join(",") - }, [], textual => { - if(textual.length === 0){ - return empty - } - return textual.split(",").map(part => { - const [filterId, selected] = part.split("."); - return {filter: filtersPerName.get(filterId), selected: Number(selected)} - }).filter(f => f.filter !== undefined && !isNaN(f.selected)) - }).syncWith(qp, true) - } - - flayers.push(flayer); + for (const layer of state.layoutToUse.layers) { + let defaultShown = "true" + if(state.layoutToUse.id === personal.id){ + defaultShown = "false" } - return flayers; - }); + + let isDisplayed: UIEventSource + if(state.layoutToUse.id === personal.id){ + isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled") + .map(value => value === "yes", [], enabled => { + return enabled ? "yes" : ""; + }) + isDisplayed.addCallbackAndRun(d =>console.log("IsDisplayed for layer", layer.id, "is currently", d) ) + }else{ + isDisplayed = QueryParameters.GetQueryParameter( + "layer-" + layer.id, + defaultShown, + "Wether or not layer " + layer.id + " is shown" + ).map( + (str) => str !== "false", + [], + (b) => b.toString() + ); + } + const flayer = { + isDisplayed: isDisplayed, + layerDef: layer, + appliedFilters: new UIEventSource<{ filter: FilterConfig, selected: number }[]>([]), + }; + + if (layer.filters.length > 0) { + const filtersPerName = new Map() + layer.filters.forEach(f => filtersPerName.set(f.id, f)) + const qp = QueryParameters.GetQueryParameter("filter-" + layer.id, "","Filtering state for a layer") + flayer.appliedFilters.map(filters => { + filters = filters ?? [] + return filters.map(f => f.filter.id + "." + f.selected).join(",") + }, [], textual => { + if(textual.length === 0){ + return empty + } + return textual.split(",").map(part => { + const [filterId, selected] = part.split("."); + return {filter: filtersPerName.get(filterId), selected: Number(selected)} + }).filter(f => f.filter !== undefined && !isNaN(f.selected)) + }).syncWith(qp, true) + } + + flayers.push(flayer); + } + state.filteredLayers = new UIEventSource(flayers); + + const clusterCounter = TileHierarchyAggregator.createHierarchy() new ShowDataLayer({ - features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.data.clustering.minNeededElements), + features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.clustering.minNeededElements), leafletMap: State.state.leafletMap, layerToShow: ShowTileInfo.styling, }) @@ -444,7 +442,7 @@ export class InitUiElements { clusterCounter.addTile(source) - const clustering = State.state.layoutToUse.data.clustering + const clustering = State.state.layoutToUse.clustering const doShowFeatures = source.features.map( f => { const z = State.state.locationControl.data.zoom diff --git a/Logic/Actors/BackgroundLayerResetter.ts b/Logic/Actors/BackgroundLayerResetter.ts index 96c43bda3..d193d8132 100644 --- a/Logic/Actors/BackgroundLayerResetter.ts +++ b/Logic/Actors/BackgroundLayerResetter.ts @@ -11,8 +11,8 @@ export default class BackgroundLayerResetter { constructor(currentBackgroundLayer: UIEventSource, location: UIEventSource, availableLayers: UIEventSource, - defaultLayerId: UIEventSource = undefined) { - defaultLayerId = defaultLayerId ?? new UIEventSource(AvailableBaseLayers.osmCarto.id); + defaultLayerId: string = undefined) { + defaultLayerId = defaultLayerId ?? AvailableBaseLayers.osmCarto.id; // Change the baselayer back to OSM if we go out of the current range of the layer availableLayers.addCallbackAndRun(availableLayers => { @@ -28,7 +28,7 @@ export default class BackgroundLayerResetter { if (availableLayer.min_zoom > location.data.zoom) { break; } - if (availableLayer.id === defaultLayerId.data) { + if (availableLayer.id === defaultLayerId) { defaultLayer = availableLayer; } return; // All good - the current layer still works! diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index d77f326e5..248703954 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -3,7 +3,7 @@ import Loc from "../../Models/Loc"; import {Or} from "../Tags/Or"; import {Overpass} from "../Osm/Overpass"; import Bounds from "../../Models/Bounds"; -import FeatureSource, {FeatureSourceState} from "../FeatureSource/FeatureSource"; +import FeatureSource from "../FeatureSource/FeatureSource"; import {Utils} from "../../Utils"; import {TagsFilter} from "../Tags/TagsFilter"; import SimpleMetaTagger from "../SimpleMetaTagger"; @@ -39,7 +39,7 @@ export default class OverpassFeatureSource implements FeatureSource { private readonly _previousBounds: Map = new Map(); private readonly state: { readonly locationControl: UIEventSource, - readonly layoutToUse: UIEventSource, + readonly layoutToUse: LayoutConfig, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly currentBounds :UIEventSource @@ -52,7 +52,7 @@ export default class OverpassFeatureSource implements FeatureSource { constructor( state: { readonly locationControl: UIEventSource, - readonly layoutToUse: UIEventSource, + readonly layoutToUse: LayoutConfig, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; readonly overpassMaxZoom: UIEventSource, @@ -76,9 +76,6 @@ export default class OverpassFeatureSource implements FeatureSource { this._previousBounds.set(i, []); } - state.layoutToUse.addCallback(() => { - self.update() - }); location.addCallback(() => { self.update() }); @@ -92,7 +89,7 @@ export default class OverpassFeatureSource implements FeatureSource { private GetFilter(): Overpass { let filters: TagsFilter[] = []; let extraScripts: string[] = []; - for (const layer of this.state.layoutToUse.data.layers) { + for (const layer of this.state.layoutToUse.layers) { if (typeof (layer) === "string") { throw "A layer was not expanded!" } @@ -164,7 +161,7 @@ export default class OverpassFeatureSource implements FeatureSource { return undefined; } - const bounds = this.state.currentBounds.data?.pad(this.state.layoutToUse.data.widenFactor)?.expandToTileBounds(14); + const bounds = this.state.currentBounds.data?.pad(this.state.layoutToUse.widenFactor)?.expandToTileBounds(14); if (bounds === undefined) { return undefined; diff --git a/Logic/Actors/TitleHandler.ts b/Logic/Actors/TitleHandler.ts index 49661f289..699a33aa8 100644 --- a/Logic/Actors/TitleHandler.ts +++ b/Logic/Actors/TitleHandler.ts @@ -3,12 +3,18 @@ import Translations from "../../UI/i18n/Translations"; import Locale from "../../UI/i18n/Locale"; import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer"; import Combine from "../../UI/Base/Combine"; +import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import {ElementStorage} from "../ElementStorage"; export default class TitleHandler { - constructor(state) { + constructor(state : { + selectedElement: UIEventSource, + layoutToUse: LayoutConfig, + allElements: ElementStorage + }) { const currentTitle: UIEventSource = state.selectedElement.map( selected => { - const layout = state.layoutToUse.data + const layout = state.layoutToUse const defaultTitle = Translations.WT(layout?.title)?.txt ?? "MapComplete" if (selected === undefined) { @@ -27,7 +33,7 @@ export default class TitleHandler { } } return defaultTitle - }, [Locale.language, state.layoutToUse] + }, [Locale.language] ) diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index fab051aa5..d65771da2 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -1,7 +1,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import FilteringFeatureSource from "./Sources/FilteringFeatureSource"; import PerLayerFeatureSourceSplitter from "./PerLayerFeatureSourceSplitter"; -import FeatureSource, {FeatureSourceForLayer, FeatureSourceState, IndexedFeatureSource, Tiled} from "./FeatureSource"; +import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from "./FeatureSource"; import TiledFeatureSource from "./TiledFeatureSource/TiledFeatureSource"; import {UIEventSource} from "../UIEventSource"; import {TileHierarchyTools} from "./TiledFeatureSource/TileHierarchy"; @@ -48,7 +48,7 @@ export default class FeaturePipeline { readonly locationControl: UIEventSource, readonly selectedElement: UIEventSource, readonly changes: Changes, - readonly layoutToUse: UIEventSource, + readonly layoutToUse: LayoutConfig, readonly leafletMap: any, readonly overpassUrl: UIEventSource; readonly overpassTimeout: UIEventSource; @@ -86,7 +86,7 @@ export default class FeaturePipeline { if (location?.zoom === undefined) { return false; } - let minzoom = Math.min(...state.layoutToUse.data.layers.map(layer => layer.minzoom ?? 18)); + let minzoom = Math.min(...state.layoutToUse.layers.map(layer => layer.minzoom ?? 18)); return location.zoom >= minzoom; } ); @@ -223,8 +223,8 @@ export default class FeaturePipeline { layer: source.layer, minZoomLevel: 14, dontEnforceMinZoom: true, - maxFeatureCount: state.layoutToUse.data.clustering.minNeededElements, - maxZoomLevel: state.layoutToUse.data.clustering.maxZoom, + maxFeatureCount: state.layoutToUse.clustering.minNeededElements, + maxZoomLevel: state.layoutToUse.clustering.maxZoom, registerTile: (tile) => { // We save the tile data for the given layer to local storage new SaveTileToLocalStorageActor(tile, tile.tileIndex) diff --git a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts index 2bed33298..a7485facf 100644 --- a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts @@ -65,7 +65,7 @@ export default class OsmFeatureSource { } private async LoadTile(z, x, y): Promise { - if (z > 18) { + if (z > 20) { throw "This is an absurd high zoom level" } diff --git a/Logic/Osm/Actions/DeleteAction.ts b/Logic/Osm/Actions/DeleteAction.ts index 25542bf18..68919bd12 100644 --- a/Logic/Osm/Actions/DeleteAction.ts +++ b/Logic/Osm/Actions/DeleteAction.ts @@ -62,7 +62,7 @@ export default class DeleteAction { } State.state.osmConnection.changesetHandler.DeleteElement( obj, - State.state.layoutToUse.data, + State.state.layoutToUse, reason, State.state.allElements, () => { diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 828ba7d78..b4bf3b4ec 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -131,7 +131,7 @@ export class Changes { } await State.state.osmConnection.UploadChangeset( - State.state.layoutToUse.data, + State.state.layoutToUse, State.state.allElements, (csId) => Changes.createChangesetFor(csId, changes), ) diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index a938e9c72..4b047fc7d 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -87,7 +87,7 @@ export default class SimpleMetaTagger { }, (feature => { - const units = Utils.NoNull([].concat(...State.state?.layoutToUse?.data?.layers?.map(layer => layer.units ?? []))); + const units = Utils.NoNull([].concat(...State.state?.layoutToUse?.layers?.map(layer => layer.units ?? []))); if (units.length == 0) { return; } diff --git a/State.ts b/State.ts index 85dfc9cfd..0af8e5a64 100644 --- a/State.ts +++ b/State.ts @@ -27,7 +27,7 @@ export default class State { // The singleton of the global state public static state: State; - public readonly layoutToUse = new UIEventSource(undefined, "layoutToUse"); + public readonly layoutToUse : LayoutConfig; /** The mapping from id -> UIEventSource @@ -83,7 +83,9 @@ export default class State { public readonly featureSwitchExportAsPdf: UIEventSource; public readonly overpassUrl: UIEventSource; public readonly overpassTimeout: UIEventSource; - public readonly overpassMaxZoom: UIEventSource = new UIEventSource(20); + + + public readonly overpassMaxZoom: UIEventSource = new UIEventSource(17, "overpass-max-zoom: point to switch between OSM-api and overpass"); public featurePipeline: FeaturePipeline; @@ -155,7 +157,7 @@ export default class State { constructor(layoutToUse: LayoutConfig) { const self = this; - this.layoutToUse.setData(layoutToUse); + this.layoutToUse = layoutToUse; // -- Location control initialization { @@ -192,14 +194,7 @@ export default class State { lat.setData(latlonz.lat); lon.setData(latlonz.lon); }); - - this.layoutToUse.addCallback((layoutToUse) => { - const lcd = self.locationControl.data; - lcd.zoom = lcd.zoom ?? layoutToUse?.startZoom; - lcd.lat = lcd.lat ?? layoutToUse?.startLat; - lcd.lon = lcd.lon ?? layoutToUse?.startLon; - self.locationControl.ping(); - }); + } // Helper function to initialize feature switches @@ -208,28 +203,19 @@ export default class State { deflt: (layout: LayoutConfig) => boolean, documentation: string ): UIEventSource { - const queryParameterSource = QueryParameters.GetQueryParameter( + + const defaultValue = deflt(self.layoutToUse); + const queryParam = QueryParameters.GetQueryParameter( key, - undefined, + "" + defaultValue, documentation ); - // I'm so sorry about someone trying to decipher this // It takes the current layout, extracts the default value for this query parameter. A query parameter event source is then retrieved and flattened - return UIEventSource.flatten( - self.layoutToUse.map((layout) => { - const defaultValue = deflt(layout); - const queryParam = QueryParameters.GetQueryParameter( - key, - "" + defaultValue, - documentation - ); - return queryParam.map((str) => - str === undefined ? defaultValue : str !== "false" - ); - }), - [queryParameterSource] - ); + return queryParam.map((str) => + str === undefined ? defaultValue : str !== "false" + ) + } // Feature switch initialization - not as a function as the UIEventSources are readonly @@ -412,11 +398,11 @@ export default class State { Locale.language .addCallback((currentLanguage) => { - const layoutToUse = self.layoutToUse.data; + const layoutToUse = self.layoutToUse; if (layoutToUse === undefined) { return; } - if (this.layoutToUse.data.language.indexOf(currentLanguage) < 0) { + if (this.layoutToUse.language.indexOf(currentLanguage) < 0) { console.log( "Resetting language to", layoutToUse.language[0], diff --git a/UI/BigComponents/Attribution.ts b/UI/BigComponents/Attribution.ts index 9b1ddb013..471556798 100644 --- a/UI/BigComponents/Attribution.ts +++ b/UI/BigComponents/Attribution.ts @@ -16,13 +16,13 @@ export default class Attribution extends Combine { constructor(location: UIEventSource, userDetails: UIEventSource, - layoutToUse: UIEventSource, + layoutToUse: LayoutConfig, currentBounds: UIEventSource) { const mapComplete = new Link(`Mapcomplete ${Constants.vNumber}`, 'https://github.com/pietervdvn/MapComplete', true); const reportBug = new Link(Svg.bug_ui().SetClass("small-image"), "https://github.com/pietervdvn/MapComplete/issues", true); - const layoutId = layoutToUse?.data?.id; + const layoutId = layoutToUse?.id; const now = new Date() // Note: getMonth is zero-index, we want 1-index but with one substracted, so it checks out! const startDate = now.getFullYear() + "-" + now.getMonth() + "-" + now.getDate() diff --git a/UI/BigComponents/AttributionPanel.ts b/UI/BigComponents/AttributionPanel.ts index 542326314..c18c8d287 100644 --- a/UI/BigComponents/AttributionPanel.ts +++ b/UI/BigComponents/AttributionPanel.ts @@ -20,11 +20,11 @@ export default class AttributionPanel extends Combine { private static LicenseObject = AttributionPanel.GenerateLicenses(); - constructor(layoutToUse: UIEventSource, contributions: UIEventSource>) { + constructor(layoutToUse: LayoutConfig, contributions: UIEventSource>) { super([ Translations.t.general.attribution.attributionContent, - ((layoutToUse.data.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.data.maintainer}), - layoutToUse.data.credits, + ((layoutToUse.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.maintainer}), + layoutToUse.credits, "
", new Attribution(State.state.locationControl, State.state.osmConnection.userDetails, State.state.layoutToUse, State.state.currentBounds), "
", @@ -65,7 +65,7 @@ export default class AttributionPanel extends Combine { "
", AttributionPanel.CodeContributors(), "

", Translations.t.general.attribution.iconAttribution.title.Clone().SetClass("pt-6 pb-3"), "

", - ...Utils.NoNull(Array.from(layoutToUse.data.ExtractImages())) + ...Utils.NoNull(Array.from(layoutToUse.ExtractImages())) .map(AttributionPanel.IconAttribution) ]); this.SetClass("flex flex-col link-underline overflow-hidden") diff --git a/UI/BigComponents/DownloadPanel.ts b/UI/BigComponents/DownloadPanel.ts index 500d28e19..f23d98747 100644 --- a/UI/BigComponents/DownloadPanel.ts +++ b/UI/BigComponents/DownloadPanel.ts @@ -26,7 +26,7 @@ export class DownloadPanel extends Toggle { const t = Translations.t.general.download - const name = State.state.layoutToUse.data.id; + const name = State.state.layoutToUse.id; const includeMetaToggle = new CheckBoxes([t.includeMetaData.Clone()]) const metaisIncluded = includeMetaToggle.GetValue().map(selected => selected.length > 0) diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index f6574f04b..8ee36ecec 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -19,7 +19,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { constructor(isShown: UIEventSource) { - const layoutToUse = State.state.layoutToUse.data; + const layoutToUse = State.state.layoutToUse; super( () => layoutToUse.title.Clone(), () => FullWelcomePaneWithTabs.GenerateContents(layoutToUse, State.state.osmConnection.userDetails, isShown), diff --git a/UI/BigComponents/MoreScreen.ts b/UI/BigComponents/MoreScreen.ts index 9d8fa44f9..01e4b9f95 100644 --- a/UI/BigComponents/MoreScreen.ts +++ b/UI/BigComponents/MoreScreen.ts @@ -126,7 +126,7 @@ export default class MoreScreen extends Combine { if (layout.hideFromOverview) { return undefined; } - if (layout.id === State.state.layoutToUse.data?.id) { + if (layout.id === State.state.layoutToUse?.id) { return undefined; } diff --git a/UI/BigComponents/ShareScreen.ts b/UI/BigComponents/ShareScreen.ts index 9b97ef441..32e1b0ce0 100644 --- a/UI/BigComponents/ShareScreen.ts +++ b/UI/BigComponents/ShareScreen.ts @@ -17,7 +17,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; export default class ShareScreen extends Combine { constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) { - layout = layout ?? State.state?.layoutToUse?.data; + layout = layout ?? State.state?.layoutToUse; layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition; const tr = Translations.t.general.sharescreen; diff --git a/UI/BigComponents/ThemeIntroductionPanel.ts b/UI/BigComponents/ThemeIntroductionPanel.ts index 8c4add4d9..75c5b6f55 100644 --- a/UI/BigComponents/ThemeIntroductionPanel.ts +++ b/UI/BigComponents/ThemeIntroductionPanel.ts @@ -2,21 +2,17 @@ import State from "../../State"; import Combine from "../Base/Combine"; import LanguagePicker from "../LanguagePicker"; import Translations from "../i18n/Translations"; -import {VariableUiElement} from "../Base/VariableUIElement"; import Toggle from "../Input/Toggle"; import {SubtleButton} from "../Base/SubtleButton"; import Svg from "../../Svg"; import {UIEventSource} from "../../Logic/UIEventSource"; -export default class ThemeIntroductionPanel extends VariableUiElement { +export default class ThemeIntroductionPanel extends Combine { constructor(isShown: UIEventSource) { + const layout = State.state.layoutToUse - const languagePicker = - new VariableUiElement( - State.state.layoutToUse.map(layout => LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone())) - ) - ; + const languagePicker = LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone()) const toTheMap = new SubtleButton( undefined, @@ -53,8 +49,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement { State.state.featureSwitchUserbadge ) - - super(State.state.layoutToUse.map(layout => new Combine([ + super([ layout.description.Clone(), "

", toTheMap, @@ -63,7 +58,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement { "
", languagePicker, ...layout.CustomCodeSnippets() - ]))) + ]) this.SetClass("link-underline") } diff --git a/UI/BigComponents/UserBadge.ts b/UI/BigComponents/UserBadge.ts index 62f74e0ae..006b1823a 100644 --- a/UI/BigComponents/UserBadge.ts +++ b/UI/BigComponents/UserBadge.ts @@ -47,7 +47,7 @@ export default class UserBadge extends Toggle { }); const linkStyle = "flex items-baseline" - const languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.data.language) ?? new FixedUiElement("")) + const languagePicker = (LanguagePicker.CreateLanguagePicker(State.state.layoutToUse.language) ?? new FixedUiElement("")) .SetStyle("width:min-content;"); let messageSpan = diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 2a8053523..432541395 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -55,7 +55,7 @@ export class ImageUploadFlow extends Toggle { const tags = tagsSource.data; - const layout = State.state?.layoutToUse?.data + const layout = State.state?.layoutToUse let matchingLayer: LayerConfig = undefined for (const layer of layout?.layers ?? []) { if (layer.source.osmTags.matchesProperties(tags)) { diff --git a/UI/Input/DropDown.ts b/UI/Input/DropDown.ts index fe8f8bc98..147ad0f50 100644 --- a/UI/Input/DropDown.ts +++ b/UI/Input/DropDown.ts @@ -47,7 +47,7 @@ export class DropDown extends InputElement { } options = options ?? {} - options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200' + options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full' { diff --git a/UI/Input/LocationInput.ts b/UI/Input/LocationInput.ts index 262d9a7db..e826773ab 100644 --- a/UI/Input/LocationInput.ts +++ b/UI/Input/LocationInput.ts @@ -39,7 +39,7 @@ export default class LocationInput extends InputElement { private readonly _maxSnapDistance: number private readonly _snappedPointTags: any; private readonly _bounds: UIEventSource; - public readonly _matching_layer: UIEventSource; + public readonly _matching_layer: LayerConfig; constructor(options: { mapBackground?: UIEventSource, @@ -63,18 +63,17 @@ export default class LocationInput extends InputElement { if (self._snappedPointTags !== undefined) { - this._matching_layer = State.state.layoutToUse.map(layout => { + const layout = State.state.layoutToUse - for (const layer of layout.layers) { - if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) { - return layer - } + let matchingLayer = LocationInput.matchLayer + for (const layer of layout.layers) { + if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) { + matchingLayer = layer } - console.error("No matching layer found for tags ", self._snappedPointTags) - return LocationInput.matchLayer - }) + } + this._matching_layer = matchingLayer; } else { - this._matching_layer = new UIEventSource(LocationInput.matchLayer) + this._matching_layer = LocationInput.matchLayer } this._snappedPoint = options.centerLocation.map(loc => { @@ -176,7 +175,7 @@ export default class LocationInput extends InputElement { enablePopups: false, zoomToFeatures: false, leafletMap: map.leafletMap, - layerToShow: this._matching_layer.data + layerToShow: this._matching_layer }) } diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 7814cbbdc..5b15cfdaa 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -316,10 +316,10 @@ export default class SpecialVisualizations { const generateShareData = () => { - const title = state?.layoutToUse?.data?.title?.txt ?? "MapComplete"; + const title = state?.layoutToUse?.title?.txt ?? "MapComplete"; let matchingLayer: LayerConfig = undefined; - for (const layer of (state?.layoutToUse?.data?.layers ?? [])) { + for (const layer of (state?.layoutToUse?.layers ?? [])) { if (layer.source.osmTags.matchesProperties(tagSource?.data)) { matchingLayer = layer } @@ -337,7 +337,7 @@ export default class SpecialVisualizations { return { title: name, url: url, - text: state?.layoutToUse?.data?.shortDescription?.txt ?? "MapComplete" + text: state?.layoutToUse?.shortDescription?.txt ?? "MapComplete" } } @@ -363,15 +363,14 @@ export default class SpecialVisualizations { if (value === undefined) { return undefined } - const allUnits = [].concat(...state.layoutToUse.data.layers.map(lyr => lyr.units)) + const allUnits = [].concat(...state.layoutToUse.layers.map(lyr => lyr.units)) const unit = allUnits.filter(unit => unit.isApplicableToKey(key))[0] if (unit === undefined) { return value; } return unit.asHumanLongValue(value); - }, - [state.layoutToUse]) + }) ) } }, @@ -410,7 +409,7 @@ There are also some technicalities in your theme to keep in mind: A reference number to the original dataset is an excellen way to do this `, constr: (state, tagSource, args) => { - if (!state.layoutToUse.data.official && !state.featureSwitchIsTesting.data) { + if (!state.layoutToUse.official && !state.featureSwitchIsTesting.data) { return new Combine([new FixedUiElement("The import button is disabled for unofficial themes to prevent accidents.").SetClass("alert"), new FixedUiElement("To test, add 'test=true' to the URL. The changeset will be printed in the console. Please open a PR to officialize this theme to actually enable the import button.")]) }