forked from MapComplete/MapComplete
		
	Refactoring: LayoutToUse is a simple value now
This commit is contained in:
		
							parent
							
								
									41a2a79fe9
								
							
						
					
					
						commit
						a78d33112b
					
				
					 22 changed files with 133 additions and 153 deletions
				
			
		| 
						 | 
					@ -323,9 +323,7 @@ export class InitUiElements {
 | 
				
			||||||
            State.state.backgroundLayer,
 | 
					            State.state.backgroundLayer,
 | 
				
			||||||
            State.state.locationControl,
 | 
					            State.state.locationControl,
 | 
				
			||||||
            State.state.availableBackgroundLayers,
 | 
					            State.state.availableBackgroundLayers,
 | 
				
			||||||
            State.state.layoutToUse.map(
 | 
					            State.state.layoutToUse.defaultBackgroundId
 | 
				
			||||||
                (layout: LayoutConfig) => layout.defaultBackgroundId
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const attr = new Attribution(
 | 
					        const attr = new Attribution(
 | 
				
			||||||
| 
						 | 
					@ -345,7 +343,7 @@ export class InitUiElements {
 | 
				
			||||||
        }).SetClass("w-full h-full")
 | 
					        }).SetClass("w-full h-full")
 | 
				
			||||||
            .AttachTo("leafletDiv")
 | 
					            .AttachTo("leafletDiv")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const layout = State.state.layoutToUse.data;
 | 
					        const layout = State.state.layoutToUse;
 | 
				
			||||||
        if (layout.lockLocation) {
 | 
					        if (layout.lockLocation) {
 | 
				
			||||||
            if (layout.lockLocation === true) {
 | 
					            if (layout.lockLocation === true) {
 | 
				
			||||||
                const tile = Tiles.embedded_tile(
 | 
					                const tile = Tiles.embedded_tile(
 | 
				
			||||||
| 
						 | 
					@ -375,17 +373,16 @@ export class InitUiElements {
 | 
				
			||||||
        const state = State.state;
 | 
					        const state = State.state;
 | 
				
			||||||
        const empty = []
 | 
					        const empty = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        state.filteredLayers = state.layoutToUse.map((layoutToUse) => {
 | 
					 | 
				
			||||||
        const flayers: FilteredLayer[] = [];
 | 
					        const flayers: FilteredLayer[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (const layer of layoutToUse.layers) {
 | 
					        for (const layer of state.layoutToUse.layers) {
 | 
				
			||||||
            let defaultShown = "true"
 | 
					            let defaultShown = "true"
 | 
				
			||||||
                if(layoutToUse.id === personal.id){
 | 
					            if(state.layoutToUse.id === personal.id){
 | 
				
			||||||
                defaultShown = "false"
 | 
					                defaultShown = "false"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let isDisplayed: UIEventSource<boolean>
 | 
					            let isDisplayed: UIEventSource<boolean>
 | 
				
			||||||
                if(layoutToUse.id === personal.id){
 | 
					            if(state.layoutToUse.id === personal.id){
 | 
				
			||||||
                isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled")
 | 
					                isDisplayed = State.state.osmConnection.GetPreference("personal-theme-layer-" + layer.id + "-enabled")
 | 
				
			||||||
                    .map(value => value === "yes", [], enabled => {
 | 
					                    .map(value => value === "yes", [], enabled => {
 | 
				
			||||||
                        return enabled ? "yes" : "";
 | 
					                        return enabled ? "yes" : "";
 | 
				
			||||||
| 
						 | 
					@ -428,13 +425,14 @@ export class InitUiElements {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            flayers.push(flayer);
 | 
					            flayers.push(flayer);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
            return flayers;
 | 
					        state.filteredLayers = new UIEventSource<FilteredLayer[]>(flayers);
 | 
				
			||||||
        });
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const clusterCounter = TileHierarchyAggregator.createHierarchy()
 | 
					        const clusterCounter = TileHierarchyAggregator.createHierarchy()
 | 
				
			||||||
        new ShowDataLayer({
 | 
					        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,
 | 
					            leafletMap: State.state.leafletMap,
 | 
				
			||||||
            layerToShow: ShowTileInfo.styling,
 | 
					            layerToShow: ShowTileInfo.styling,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
| 
						 | 
					@ -444,7 +442,7 @@ export class InitUiElements {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                clusterCounter.addTile(source)
 | 
					                clusterCounter.addTile(source)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const clustering = State.state.layoutToUse.data.clustering
 | 
					                const clustering = State.state.layoutToUse.clustering
 | 
				
			||||||
                const doShowFeatures = source.features.map(
 | 
					                const doShowFeatures = source.features.map(
 | 
				
			||||||
                    f => {
 | 
					                    f => {
 | 
				
			||||||
                        const z = State.state.locationControl.data.zoom
 | 
					                        const z = State.state.locationControl.data.zoom
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,8 +11,8 @@ export default class BackgroundLayerResetter {
 | 
				
			||||||
    constructor(currentBackgroundLayer: UIEventSource<BaseLayer>,
 | 
					    constructor(currentBackgroundLayer: UIEventSource<BaseLayer>,
 | 
				
			||||||
                location: UIEventSource<Loc>,
 | 
					                location: UIEventSource<Loc>,
 | 
				
			||||||
                availableLayers: UIEventSource<BaseLayer[]>,
 | 
					                availableLayers: UIEventSource<BaseLayer[]>,
 | 
				
			||||||
                defaultLayerId: UIEventSource<string> = undefined) {
 | 
					                defaultLayerId: string = undefined) {
 | 
				
			||||||
        defaultLayerId = defaultLayerId ?? new UIEventSource<string>(AvailableBaseLayers.osmCarto.id);
 | 
					        defaultLayerId = defaultLayerId ?? AvailableBaseLayers.osmCarto.id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Change the baselayer back to OSM if we go out of the current range of the layer
 | 
					        // Change the baselayer back to OSM if we go out of the current range of the layer
 | 
				
			||||||
        availableLayers.addCallbackAndRun(availableLayers => {
 | 
					        availableLayers.addCallbackAndRun(availableLayers => {
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ export default class BackgroundLayerResetter {
 | 
				
			||||||
                    if (availableLayer.min_zoom > location.data.zoom) {
 | 
					                    if (availableLayer.min_zoom > location.data.zoom) {
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (availableLayer.id === defaultLayerId.data) {
 | 
					                    if (availableLayer.id === defaultLayerId) {
 | 
				
			||||||
                        defaultLayer = availableLayer;
 | 
					                        defaultLayer = availableLayer;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    return; // All good - the current layer still works!
 | 
					                    return; // All good - the current layer still works!
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@ import Loc from "../../Models/Loc";
 | 
				
			||||||
import {Or} from "../Tags/Or";
 | 
					import {Or} from "../Tags/Or";
 | 
				
			||||||
import {Overpass} from "../Osm/Overpass";
 | 
					import {Overpass} from "../Osm/Overpass";
 | 
				
			||||||
import Bounds from "../../Models/Bounds";
 | 
					import Bounds from "../../Models/Bounds";
 | 
				
			||||||
import FeatureSource, {FeatureSourceState} from "../FeatureSource/FeatureSource";
 | 
					import FeatureSource from "../FeatureSource/FeatureSource";
 | 
				
			||||||
import {Utils} from "../../Utils";
 | 
					import {Utils} from "../../Utils";
 | 
				
			||||||
import {TagsFilter} from "../Tags/TagsFilter";
 | 
					import {TagsFilter} from "../Tags/TagsFilter";
 | 
				
			||||||
import SimpleMetaTagger from "../SimpleMetaTagger";
 | 
					import SimpleMetaTagger from "../SimpleMetaTagger";
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ export default class OverpassFeatureSource implements FeatureSource {
 | 
				
			||||||
    private readonly _previousBounds: Map<number, Bounds[]> = new Map<number, Bounds[]>();
 | 
					    private readonly _previousBounds: Map<number, Bounds[]> = new Map<number, Bounds[]>();
 | 
				
			||||||
    private readonly state: {
 | 
					    private readonly state: {
 | 
				
			||||||
        readonly locationControl: UIEventSource<Loc>,
 | 
					        readonly locationControl: UIEventSource<Loc>,
 | 
				
			||||||
        readonly layoutToUse: UIEventSource<LayoutConfig>,
 | 
					        readonly layoutToUse: LayoutConfig,
 | 
				
			||||||
        readonly overpassUrl: UIEventSource<string>;
 | 
					        readonly overpassUrl: UIEventSource<string>;
 | 
				
			||||||
        readonly overpassTimeout: UIEventSource<number>;
 | 
					        readonly overpassTimeout: UIEventSource<number>;
 | 
				
			||||||
        readonly currentBounds :UIEventSource<BBox>
 | 
					        readonly currentBounds :UIEventSource<BBox>
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,7 @@ export default class OverpassFeatureSource implements FeatureSource {
 | 
				
			||||||
    constructor(
 | 
					    constructor(
 | 
				
			||||||
        state: {
 | 
					        state: {
 | 
				
			||||||
            readonly locationControl: UIEventSource<Loc>,
 | 
					            readonly locationControl: UIEventSource<Loc>,
 | 
				
			||||||
            readonly layoutToUse: UIEventSource<LayoutConfig>,
 | 
					            readonly layoutToUse: LayoutConfig,
 | 
				
			||||||
            readonly overpassUrl: UIEventSource<string>;
 | 
					            readonly overpassUrl: UIEventSource<string>;
 | 
				
			||||||
            readonly overpassTimeout: UIEventSource<number>;
 | 
					            readonly overpassTimeout: UIEventSource<number>;
 | 
				
			||||||
            readonly overpassMaxZoom: UIEventSource<number>,
 | 
					            readonly overpassMaxZoom: UIEventSource<number>,
 | 
				
			||||||
| 
						 | 
					@ -76,9 +76,6 @@ export default class OverpassFeatureSource implements FeatureSource {
 | 
				
			||||||
            this._previousBounds.set(i, []);
 | 
					            this._previousBounds.set(i, []);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        state.layoutToUse.addCallback(() => {
 | 
					 | 
				
			||||||
            self.update()
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        location.addCallback(() => {
 | 
					        location.addCallback(() => {
 | 
				
			||||||
            self.update()
 | 
					            self.update()
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
| 
						 | 
					@ -92,7 +89,7 @@ export default class OverpassFeatureSource implements FeatureSource {
 | 
				
			||||||
    private GetFilter(): Overpass {
 | 
					    private GetFilter(): Overpass {
 | 
				
			||||||
        let filters: TagsFilter[] = [];
 | 
					        let filters: TagsFilter[] = [];
 | 
				
			||||||
        let extraScripts: string[] = [];
 | 
					        let extraScripts: string[] = [];
 | 
				
			||||||
        for (const layer of this.state.layoutToUse.data.layers) {
 | 
					        for (const layer of this.state.layoutToUse.layers) {
 | 
				
			||||||
            if (typeof (layer) === "string") {
 | 
					            if (typeof (layer) === "string") {
 | 
				
			||||||
                throw "A layer was not expanded!"
 | 
					                throw "A layer was not expanded!"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -164,7 +161,7 @@ export default class OverpassFeatureSource implements FeatureSource {
 | 
				
			||||||
            return undefined;
 | 
					            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) {
 | 
					        if (bounds === undefined) {
 | 
				
			||||||
            return undefined;
 | 
					            return undefined;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,12 +3,18 @@ import Translations from "../../UI/i18n/Translations";
 | 
				
			||||||
import Locale from "../../UI/i18n/Locale";
 | 
					import Locale from "../../UI/i18n/Locale";
 | 
				
			||||||
import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer";
 | 
					import TagRenderingAnswer from "../../UI/Popup/TagRenderingAnswer";
 | 
				
			||||||
import Combine from "../../UI/Base/Combine";
 | 
					import Combine from "../../UI/Base/Combine";
 | 
				
			||||||
 | 
					import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
 | 
				
			||||||
 | 
					import {ElementStorage} from "../ElementStorage";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class TitleHandler {
 | 
					export default class TitleHandler {
 | 
				
			||||||
    constructor(state) {
 | 
					    constructor(state : {
 | 
				
			||||||
 | 
					        selectedElement: UIEventSource<any>,
 | 
				
			||||||
 | 
					        layoutToUse: LayoutConfig,
 | 
				
			||||||
 | 
					        allElements: ElementStorage
 | 
				
			||||||
 | 
					    }) {
 | 
				
			||||||
        const currentTitle: UIEventSource<string> = state.selectedElement.map(
 | 
					        const currentTitle: UIEventSource<string> = state.selectedElement.map(
 | 
				
			||||||
            selected => {
 | 
					            selected => {
 | 
				
			||||||
                const layout = state.layoutToUse.data
 | 
					                const layout = state.layoutToUse
 | 
				
			||||||
                const defaultTitle = Translations.WT(layout?.title)?.txt ?? "MapComplete"
 | 
					                const defaultTitle = Translations.WT(layout?.title)?.txt ?? "MapComplete"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (selected === undefined) {
 | 
					                if (selected === undefined) {
 | 
				
			||||||
| 
						 | 
					@ -27,7 +33,7 @@ export default class TitleHandler {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return defaultTitle
 | 
					                return defaultTitle
 | 
				
			||||||
            }, [Locale.language, state.layoutToUse]
 | 
					            }, [Locale.language]
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
 | 
					import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
 | 
				
			||||||
import FilteringFeatureSource from "./Sources/FilteringFeatureSource";
 | 
					import FilteringFeatureSource from "./Sources/FilteringFeatureSource";
 | 
				
			||||||
import PerLayerFeatureSourceSplitter from "./PerLayerFeatureSourceSplitter";
 | 
					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 TiledFeatureSource from "./TiledFeatureSource/TiledFeatureSource";
 | 
				
			||||||
import {UIEventSource} from "../UIEventSource";
 | 
					import {UIEventSource} from "../UIEventSource";
 | 
				
			||||||
import {TileHierarchyTools} from "./TiledFeatureSource/TileHierarchy";
 | 
					import {TileHierarchyTools} from "./TiledFeatureSource/TileHierarchy";
 | 
				
			||||||
| 
						 | 
					@ -48,7 +48,7 @@ export default class FeaturePipeline {
 | 
				
			||||||
            readonly locationControl: UIEventSource<Loc>,
 | 
					            readonly locationControl: UIEventSource<Loc>,
 | 
				
			||||||
            readonly selectedElement: UIEventSource<any>,
 | 
					            readonly selectedElement: UIEventSource<any>,
 | 
				
			||||||
            readonly changes: Changes,
 | 
					            readonly changes: Changes,
 | 
				
			||||||
            readonly  layoutToUse: UIEventSource<LayoutConfig>,
 | 
					            readonly  layoutToUse: LayoutConfig,
 | 
				
			||||||
            readonly leafletMap: any,
 | 
					            readonly leafletMap: any,
 | 
				
			||||||
            readonly overpassUrl: UIEventSource<string>;
 | 
					            readonly overpassUrl: UIEventSource<string>;
 | 
				
			||||||
            readonly overpassTimeout: UIEventSource<number>;
 | 
					            readonly overpassTimeout: UIEventSource<number>;
 | 
				
			||||||
| 
						 | 
					@ -86,7 +86,7 @@ export default class FeaturePipeline {
 | 
				
			||||||
                if (location?.zoom === undefined) {
 | 
					                if (location?.zoom === undefined) {
 | 
				
			||||||
                    return false;
 | 
					                    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;
 | 
					                return location.zoom >= minzoom;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
| 
						 | 
					@ -223,8 +223,8 @@ export default class FeaturePipeline {
 | 
				
			||||||
                layer: source.layer,
 | 
					                layer: source.layer,
 | 
				
			||||||
                minZoomLevel: 14,
 | 
					                minZoomLevel: 14,
 | 
				
			||||||
                dontEnforceMinZoom: true,
 | 
					                dontEnforceMinZoom: true,
 | 
				
			||||||
                maxFeatureCount: state.layoutToUse.data.clustering.minNeededElements,
 | 
					                maxFeatureCount: state.layoutToUse.clustering.minNeededElements,
 | 
				
			||||||
                maxZoomLevel: state.layoutToUse.data.clustering.maxZoom,
 | 
					                maxZoomLevel: state.layoutToUse.clustering.maxZoom,
 | 
				
			||||||
                registerTile: (tile) => {
 | 
					                registerTile: (tile) => {
 | 
				
			||||||
                    // We save the tile data for the given layer to local storage
 | 
					                    // We save the tile data for the given layer to local storage
 | 
				
			||||||
                    new SaveTileToLocalStorageActor(tile, tile.tileIndex)
 | 
					                    new SaveTileToLocalStorageActor(tile, tile.tileIndex)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ export default class OsmFeatureSource {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private async LoadTile(z, x, y): Promise<void> {
 | 
					    private async LoadTile(z, x, y): Promise<void> {
 | 
				
			||||||
        if (z > 18) {
 | 
					        if (z > 20) {
 | 
				
			||||||
            throw "This is an absurd high zoom level"
 | 
					            throw "This is an absurd high zoom level"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ export default class DeleteAction {
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    State.state.osmConnection.changesetHandler.DeleteElement(
 | 
					                    State.state.osmConnection.changesetHandler.DeleteElement(
 | 
				
			||||||
                        obj,
 | 
					                        obj,
 | 
				
			||||||
                        State.state.layoutToUse.data,
 | 
					                        State.state.layoutToUse,
 | 
				
			||||||
                        reason,
 | 
					                        reason,
 | 
				
			||||||
                        State.state.allElements,
 | 
					                        State.state.allElements,
 | 
				
			||||||
                        () => {
 | 
					                        () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,7 +131,7 @@ export class Changes {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await State.state.osmConnection.UploadChangeset(
 | 
					            await State.state.osmConnection.UploadChangeset(
 | 
				
			||||||
                State.state.layoutToUse.data,
 | 
					                State.state.layoutToUse,
 | 
				
			||||||
                State.state.allElements,
 | 
					                State.state.allElements,
 | 
				
			||||||
                (csId) => Changes.createChangesetFor(csId, changes),
 | 
					                (csId) => Changes.createChangesetFor(csId, changes),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ export default class SimpleMetaTagger {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        (feature => {
 | 
					        (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) {
 | 
					            if (units.length == 0) {
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										38
									
								
								State.ts
									
										
									
									
									
								
							
							
						
						
									
										38
									
								
								State.ts
									
										
									
									
									
								
							| 
						 | 
					@ -27,7 +27,7 @@ export default class State {
 | 
				
			||||||
    // The singleton of the global state
 | 
					    // The singleton of the global state
 | 
				
			||||||
    public static state: State;
 | 
					    public static state: State;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public readonly layoutToUse = new UIEventSource<LayoutConfig>(undefined, "layoutToUse");
 | 
					    public readonly layoutToUse : LayoutConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     The mapping from id -> UIEventSource<properties>
 | 
					     The mapping from id -> UIEventSource<properties>
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,9 @@ export default class State {
 | 
				
			||||||
    public readonly featureSwitchExportAsPdf: UIEventSource<boolean>;
 | 
					    public readonly featureSwitchExportAsPdf: UIEventSource<boolean>;
 | 
				
			||||||
    public readonly overpassUrl: UIEventSource<string>;
 | 
					    public readonly overpassUrl: UIEventSource<string>;
 | 
				
			||||||
    public readonly overpassTimeout: UIEventSource<number>;
 | 
					    public readonly overpassTimeout: UIEventSource<number>;
 | 
				
			||||||
    public readonly overpassMaxZoom: UIEventSource<number> = new UIEventSource<number>(20);
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public readonly overpassMaxZoom: UIEventSource<number> = new UIEventSource<number>(17, "overpass-max-zoom: point to switch between OSM-api and overpass");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public featurePipeline: FeaturePipeline;
 | 
					    public featurePipeline: FeaturePipeline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,7 +157,7 @@ export default class State {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(layoutToUse: LayoutConfig) {
 | 
					    constructor(layoutToUse: LayoutConfig) {
 | 
				
			||||||
        const self = this;
 | 
					        const self = this;
 | 
				
			||||||
        this.layoutToUse.setData(layoutToUse);
 | 
					        this.layoutToUse  = layoutToUse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // -- Location control initialization
 | 
					        // -- Location control initialization
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -193,13 +195,6 @@ export default class State {
 | 
				
			||||||
                lon.setData(latlonz.lon);
 | 
					                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
 | 
					        // Helper function to initialize feature switches
 | 
				
			||||||
| 
						 | 
					@ -208,28 +203,19 @@ export default class State {
 | 
				
			||||||
            deflt: (layout: LayoutConfig) => boolean,
 | 
					            deflt: (layout: LayoutConfig) => boolean,
 | 
				
			||||||
            documentation: string
 | 
					            documentation: string
 | 
				
			||||||
        ): UIEventSource<boolean> {
 | 
					        ): UIEventSource<boolean> {
 | 
				
			||||||
            const queryParameterSource = QueryParameters.GetQueryParameter(
 | 
					 | 
				
			||||||
                key,
 | 
					 | 
				
			||||||
                undefined,
 | 
					 | 
				
			||||||
                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
 | 
					            const defaultValue = deflt(self.layoutToUse);
 | 
				
			||||||
            return UIEventSource.flatten(
 | 
					 | 
				
			||||||
                self.layoutToUse.map((layout) => {
 | 
					 | 
				
			||||||
                    const defaultValue = deflt(layout);
 | 
					 | 
				
			||||||
            const queryParam = QueryParameters.GetQueryParameter(
 | 
					            const queryParam = QueryParameters.GetQueryParameter(
 | 
				
			||||||
                key,
 | 
					                key,
 | 
				
			||||||
                "" + defaultValue,
 | 
					                "" + defaultValue,
 | 
				
			||||||
                documentation
 | 
					                documentation
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // It takes the current layout, extracts the default value for this query parameter. A query parameter event source is then retrieved and flattened
 | 
				
			||||||
            return queryParam.map((str) =>
 | 
					            return queryParam.map((str) =>
 | 
				
			||||||
                str === undefined ? defaultValue : str !== "false"
 | 
					                str === undefined ? defaultValue : str !== "false"
 | 
				
			||||||
                    );
 | 
					            )
 | 
				
			||||||
                }),
 | 
					   
 | 
				
			||||||
                [queryParameterSource]
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Feature switch initialization - not as a function as the UIEventSources are readonly
 | 
					        // Feature switch initialization - not as a function as the UIEventSources are readonly
 | 
				
			||||||
| 
						 | 
					@ -412,11 +398,11 @@ export default class State {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Locale.language
 | 
					        Locale.language
 | 
				
			||||||
            .addCallback((currentLanguage) => {
 | 
					            .addCallback((currentLanguage) => {
 | 
				
			||||||
                const layoutToUse = self.layoutToUse.data;
 | 
					                const layoutToUse = self.layoutToUse;
 | 
				
			||||||
                if (layoutToUse === undefined) {
 | 
					                if (layoutToUse === undefined) {
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (this.layoutToUse.data.language.indexOf(currentLanguage) < 0) {
 | 
					                if (this.layoutToUse.language.indexOf(currentLanguage) < 0) {
 | 
				
			||||||
                    console.log(
 | 
					                    console.log(
 | 
				
			||||||
                        "Resetting language to",
 | 
					                        "Resetting language to",
 | 
				
			||||||
                        layoutToUse.language[0],
 | 
					                        layoutToUse.language[0],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,13 +16,13 @@ export default class Attribution extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     constructor(location: UIEventSource<Loc>,
 | 
					     constructor(location: UIEventSource<Loc>,
 | 
				
			||||||
                userDetails: UIEventSource<UserDetails>,
 | 
					                userDetails: UIEventSource<UserDetails>,
 | 
				
			||||||
                layoutToUse: UIEventSource<LayoutConfig>,
 | 
					                layoutToUse: LayoutConfig,
 | 
				
			||||||
                currentBounds: UIEventSource<BBox>) {
 | 
					                currentBounds: UIEventSource<BBox>) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const mapComplete = new Link(`Mapcomplete ${Constants.vNumber}`, 'https://github.com/pietervdvn/MapComplete', true);
 | 
					        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 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()
 | 
					        const now = new Date()
 | 
				
			||||||
        // Note: getMonth is zero-index, we want 1-index but with one substracted, so it checks out!
 | 
					        // 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()
 | 
					        const startDate = now.getFullYear() + "-" + now.getMonth() + "-" + now.getDate()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,11 +20,11 @@ export default class AttributionPanel extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static LicenseObject = AttributionPanel.GenerateLicenses();
 | 
					    private static LicenseObject = AttributionPanel.GenerateLicenses();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(layoutToUse: UIEventSource<LayoutConfig>, contributions: UIEventSource<Map<string, number>>) {
 | 
					    constructor(layoutToUse: LayoutConfig, contributions: UIEventSource<Map<string, number>>) {
 | 
				
			||||||
        super([
 | 
					        super([
 | 
				
			||||||
            Translations.t.general.attribution.attributionContent,
 | 
					            Translations.t.general.attribution.attributionContent,
 | 
				
			||||||
            ((layoutToUse.data.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.data.maintainer}),
 | 
					            ((layoutToUse.maintainer ?? "") == "") ? "" : Translations.t.general.attribution.themeBy.Subs({author: layoutToUse.maintainer}),
 | 
				
			||||||
            layoutToUse.data.credits,
 | 
					            layoutToUse.credits,
 | 
				
			||||||
            "<br/>",
 | 
					            "<br/>",
 | 
				
			||||||
            new Attribution(State.state.locationControl, State.state.osmConnection.userDetails, State.state.layoutToUse, State.state.currentBounds),
 | 
					            new Attribution(State.state.locationControl, State.state.osmConnection.userDetails, State.state.layoutToUse, State.state.currentBounds),
 | 
				
			||||||
            "<br/>",
 | 
					            "<br/>",
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ export default class AttributionPanel extends Combine {
 | 
				
			||||||
            "<br/>",
 | 
					            "<br/>",
 | 
				
			||||||
            AttributionPanel.CodeContributors(),
 | 
					            AttributionPanel.CodeContributors(),
 | 
				
			||||||
            "<h3>", Translations.t.general.attribution.iconAttribution.title.Clone().SetClass("pt-6 pb-3"), "</h3>",
 | 
					            "<h3>", Translations.t.general.attribution.iconAttribution.title.Clone().SetClass("pt-6 pb-3"), "</h3>",
 | 
				
			||||||
            ...Utils.NoNull(Array.from(layoutToUse.data.ExtractImages()))
 | 
					            ...Utils.NoNull(Array.from(layoutToUse.ExtractImages()))
 | 
				
			||||||
                .map(AttributionPanel.IconAttribution)
 | 
					                .map(AttributionPanel.IconAttribution)
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
        this.SetClass("flex flex-col link-underline overflow-hidden")
 | 
					        this.SetClass("flex flex-col link-underline overflow-hidden")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ export class DownloadPanel extends Toggle {
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const t = Translations.t.general.download
 | 
					        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 includeMetaToggle = new CheckBoxes([t.includeMetaData.Clone()])
 | 
				
			||||||
        const metaisIncluded = includeMetaToggle.GetValue().map(selected => selected.length > 0)
 | 
					        const metaisIncluded = includeMetaToggle.GetValue().map(selected => selected.length > 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(isShown: UIEventSource<boolean>) {
 | 
					    constructor(isShown: UIEventSource<boolean>) {
 | 
				
			||||||
        const layoutToUse = State.state.layoutToUse.data;
 | 
					        const layoutToUse = State.state.layoutToUse;
 | 
				
			||||||
        super(
 | 
					        super(
 | 
				
			||||||
            () => layoutToUse.title.Clone(),
 | 
					            () => layoutToUse.title.Clone(),
 | 
				
			||||||
            () => FullWelcomePaneWithTabs.GenerateContents(layoutToUse, State.state.osmConnection.userDetails, isShown),
 | 
					            () => FullWelcomePaneWithTabs.GenerateContents(layoutToUse, State.state.osmConnection.userDetails, isShown),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,7 +126,7 @@ export default class MoreScreen extends Combine {
 | 
				
			||||||
        if (layout.hideFromOverview) {
 | 
					        if (layout.hideFromOverview) {
 | 
				
			||||||
            return undefined;
 | 
					            return undefined;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (layout.id === State.state.layoutToUse.data?.id) {
 | 
					        if (layout.id === State.state.layoutToUse?.id) {
 | 
				
			||||||
            return undefined;
 | 
					            return undefined;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
 | 
				
			||||||
export default class ShareScreen extends Combine {
 | 
					export default class ShareScreen extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) {
 | 
					    constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) {
 | 
				
			||||||
        layout = layout ?? State.state?.layoutToUse?.data;
 | 
					        layout = layout ?? State.state?.layoutToUse;
 | 
				
			||||||
        layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition;
 | 
					        layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition;
 | 
				
			||||||
        const tr = Translations.t.general.sharescreen;
 | 
					        const tr = Translations.t.general.sharescreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,21 +2,17 @@ import State from "../../State";
 | 
				
			||||||
import Combine from "../Base/Combine";
 | 
					import Combine from "../Base/Combine";
 | 
				
			||||||
import LanguagePicker from "../LanguagePicker";
 | 
					import LanguagePicker from "../LanguagePicker";
 | 
				
			||||||
import Translations from "../i18n/Translations";
 | 
					import Translations from "../i18n/Translations";
 | 
				
			||||||
import {VariableUiElement} from "../Base/VariableUIElement";
 | 
					 | 
				
			||||||
import Toggle from "../Input/Toggle";
 | 
					import Toggle from "../Input/Toggle";
 | 
				
			||||||
import {SubtleButton} from "../Base/SubtleButton";
 | 
					import {SubtleButton} from "../Base/SubtleButton";
 | 
				
			||||||
import Svg from "../../Svg";
 | 
					import Svg from "../../Svg";
 | 
				
			||||||
import {UIEventSource} from "../../Logic/UIEventSource";
 | 
					import {UIEventSource} from "../../Logic/UIEventSource";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class ThemeIntroductionPanel extends VariableUiElement {
 | 
					export default class ThemeIntroductionPanel extends Combine {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(isShown: UIEventSource<boolean>) {
 | 
					    constructor(isShown: UIEventSource<boolean>) {
 | 
				
			||||||
 | 
					        const layout = State.state.layoutToUse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const languagePicker =
 | 
					        const languagePicker =                LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone())
 | 
				
			||||||
            new VariableUiElement(
 | 
					 | 
				
			||||||
                State.state.layoutToUse.map(layout => LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone()))
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        ;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const toTheMap = new SubtleButton(
 | 
					        const toTheMap = new SubtleButton(
 | 
				
			||||||
            undefined,
 | 
					            undefined,
 | 
				
			||||||
| 
						 | 
					@ -53,8 +49,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement {
 | 
				
			||||||
                State.state.featureSwitchUserbadge
 | 
					                State.state.featureSwitchUserbadge
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        super([
 | 
				
			||||||
        super(State.state.layoutToUse.map(layout => new Combine([
 | 
					 | 
				
			||||||
            layout.description.Clone(),
 | 
					            layout.description.Clone(),
 | 
				
			||||||
            "<br/><br/>",
 | 
					            "<br/><br/>",
 | 
				
			||||||
            toTheMap,
 | 
					            toTheMap,
 | 
				
			||||||
| 
						 | 
					@ -63,7 +58,7 @@ export default class ThemeIntroductionPanel extends VariableUiElement {
 | 
				
			||||||
            "<br/>",
 | 
					            "<br/>",
 | 
				
			||||||
            languagePicker,
 | 
					            languagePicker,
 | 
				
			||||||
            ...layout.CustomCodeSnippets()
 | 
					            ...layout.CustomCodeSnippets()
 | 
				
			||||||
        ])))
 | 
					        ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.SetClass("link-underline")
 | 
					        this.SetClass("link-underline")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ export default class UserBadge extends Toggle {
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                const linkStyle = "flex items-baseline"
 | 
					                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;");
 | 
					                    .SetStyle("width:min-content;");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let messageSpan =
 | 
					                let messageSpan =
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,7 @@ export class ImageUploadFlow extends Toggle {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const tags = tagsSource.data;
 | 
					            const tags = tagsSource.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const layout = State.state?.layoutToUse?.data
 | 
					            const layout = State.state?.layoutToUse
 | 
				
			||||||
            let matchingLayer: LayerConfig = undefined
 | 
					            let matchingLayer: LayerConfig = undefined
 | 
				
			||||||
            for (const layer of layout?.layers ?? []) {
 | 
					            for (const layer of layout?.layers ?? []) {
 | 
				
			||||||
                if (layer.source.osmTags.matchesProperties(tags)) {
 | 
					                if (layer.source.osmTags.matchesProperties(tags)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,7 +47,7 @@ export class DropDown<T> extends InputElement<T> {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        options = options ?? {}
 | 
					        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'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ export default class LocationInput extends InputElement<Loc> {
 | 
				
			||||||
    private readonly _maxSnapDistance: number
 | 
					    private readonly _maxSnapDistance: number
 | 
				
			||||||
    private readonly _snappedPointTags: any;
 | 
					    private readonly _snappedPointTags: any;
 | 
				
			||||||
    private readonly _bounds: UIEventSource<BBox>;
 | 
					    private readonly _bounds: UIEventSource<BBox>;
 | 
				
			||||||
    public readonly _matching_layer: UIEventSource<LayerConfig>;
 | 
					    public readonly _matching_layer: LayerConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(options: {
 | 
					    constructor(options: {
 | 
				
			||||||
        mapBackground?: UIEventSource<BaseLayer>,
 | 
					        mapBackground?: UIEventSource<BaseLayer>,
 | 
				
			||||||
| 
						 | 
					@ -63,18 +63,17 @@ export default class LocationInput extends InputElement<Loc> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (self._snappedPointTags !== undefined) {
 | 
					            if (self._snappedPointTags !== undefined) {
 | 
				
			||||||
                this._matching_layer = State.state.layoutToUse.map(layout => {
 | 
					                const layout = State.state.layoutToUse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                let matchingLayer = LocationInput.matchLayer
 | 
				
			||||||
                for (const layer of layout.layers) {
 | 
					                for (const layer of layout.layers) {
 | 
				
			||||||
                    if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) {
 | 
					                    if (layer.source.osmTags.matchesProperties(self._snappedPointTags)) {
 | 
				
			||||||
                            return layer
 | 
					                        matchingLayer = layer
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                    console.error("No matching layer found for tags ", self._snappedPointTags)
 | 
					                this._matching_layer = matchingLayer;
 | 
				
			||||||
                    return LocationInput.matchLayer
 | 
					 | 
				
			||||||
                })
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
               this._matching_layer = new UIEventSource<LayerConfig>(LocationInput.matchLayer)
 | 
					               this._matching_layer = LocationInput.matchLayer
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this._snappedPoint = options.centerLocation.map(loc => {
 | 
					            this._snappedPoint = options.centerLocation.map(loc => {
 | 
				
			||||||
| 
						 | 
					@ -176,7 +175,7 @@ export default class LocationInput extends InputElement<Loc> {
 | 
				
			||||||
                        enablePopups: false,
 | 
					                        enablePopups: false,
 | 
				
			||||||
                        zoomToFeatures: false,
 | 
					                        zoomToFeatures: false,
 | 
				
			||||||
                        leafletMap: map.leafletMap,
 | 
					                        leafletMap: map.leafletMap,
 | 
				
			||||||
                        layerToShow: this._matching_layer.data
 | 
					                        layerToShow: this._matching_layer
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -316,10 +316,10 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                        const generateShareData = () => {
 | 
					                        const generateShareData = () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            const title = state?.layoutToUse?.data?.title?.txt ?? "MapComplete";
 | 
					                            const title = state?.layoutToUse?.title?.txt ?? "MapComplete";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            let matchingLayer: LayerConfig = undefined;
 | 
					                            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)) {
 | 
					                                if (layer.source.osmTags.matchesProperties(tagSource?.data)) {
 | 
				
			||||||
                                    matchingLayer = layer
 | 
					                                    matchingLayer = layer
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
| 
						 | 
					@ -337,7 +337,7 @@ export default class SpecialVisualizations {
 | 
				
			||||||
                            return {
 | 
					                            return {
 | 
				
			||||||
                                title: name,
 | 
					                                title: name,
 | 
				
			||||||
                                url: url,
 | 
					                                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) {
 | 
					                                if (value === undefined) {
 | 
				
			||||||
                                    return 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]
 | 
					                                const unit = allUnits.filter(unit => unit.isApplicableToKey(key))[0]
 | 
				
			||||||
                                if (unit === undefined) {
 | 
					                                if (unit === undefined) {
 | 
				
			||||||
                                    return value;
 | 
					                                    return value;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                                return unit.asHumanLongValue(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    
 | 
					    A reference number to the original dataset is an excellen way to do this    
 | 
				
			||||||
`,
 | 
					`,
 | 
				
			||||||
                constr: (state, tagSource, args) => {
 | 
					                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"),
 | 
					                        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.")])
 | 
					                            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.")])
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue