forked from MapComplete/MapComplete
Fix #1956 with workaround
This commit is contained in:
parent
4fd592cc4f
commit
8b6ee7075c
6 changed files with 106 additions and 66 deletions
|
@ -198,6 +198,9 @@ export default class MetaTagging {
|
||||||
for (let i = 0; i < features.length; i++) {
|
for (let i = 0; i < features.length; i++) {
|
||||||
const feature = features[i]
|
const feature = features[i]
|
||||||
const tags = featurePropertiesStores?.getStore(feature.properties.id)
|
const tags = featurePropertiesStores?.getStore(feature.properties.id)
|
||||||
|
if(!tags){
|
||||||
|
continue
|
||||||
|
}
|
||||||
let somethingChanged = false
|
let somethingChanged = false
|
||||||
const definedTags = new Set(Object.getOwnPropertyNames(feature.properties))
|
const definedTags = new Set(Object.getOwnPropertyNames(feature.properties))
|
||||||
|
|
||||||
|
|
62
src/UI/Base/SelectedElementPanel.svelte
Normal file
62
src/UI/Base/SelectedElementPanel.svelte
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||||
|
import type { Feature } from "geojson"
|
||||||
|
import SelectedElementView from "../BigComponents/SelectedElementView.svelte"
|
||||||
|
import SelectedElementTitle from "../BigComponents/SelectedElementTitle.svelte"
|
||||||
|
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
||||||
|
import { LastClickFeatureSource } from "../../Logic/FeatureSource/Sources/LastClickFeatureSource"
|
||||||
|
import Loading from "./Loading.svelte"
|
||||||
|
import { onDestroy } from "svelte"
|
||||||
|
|
||||||
|
export let state: SpecialVisualizationState
|
||||||
|
export let selected: Feature
|
||||||
|
let tags = state.featureProperties.getStore(selected.properties.id)
|
||||||
|
|
||||||
|
export let absolute = true
|
||||||
|
function getLayer(properties: Record<string, string>) {
|
||||||
|
if (properties.id === "settings") {
|
||||||
|
return UserRelatedState.usersettingsConfig
|
||||||
|
}
|
||||||
|
if (properties.id.startsWith(LastClickFeatureSource.newPointElementId)) {
|
||||||
|
return state.layout.layers.find((l) => l.id === "last_click")
|
||||||
|
}
|
||||||
|
if (properties.id === "location_track") {
|
||||||
|
return state.layout.layers.find((l) => l.id === "gps_track")
|
||||||
|
}
|
||||||
|
return state.layout.getMatchingLayer(properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let layer = getLayer(selected.properties)
|
||||||
|
|
||||||
|
let stillMatches = tags.map(
|
||||||
|
(tags) => !layer?.source?.osmTags || layer?.source?.osmTags?.matchesProperties(tags)
|
||||||
|
)
|
||||||
|
onDestroy(
|
||||||
|
stillMatches.addCallbackAndRunD(matches => {
|
||||||
|
if (matches) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This is a workaround. Normally, we would dynamically rewrite 'layer' and this should update the view.
|
||||||
|
* However, because there are quite some legacy elements and some elements have a different layer calculation,
|
||||||
|
* we simply close the popup and open it again.
|
||||||
|
* See #1956
|
||||||
|
*/
|
||||||
|
state.selectedElement.setData(undefined)
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
state.selectedElement.setData(selected)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
{#if !$stillMatches}
|
||||||
|
<Loading />
|
||||||
|
{:else}
|
||||||
|
<div class="normal-background flex h-full w-full flex-col" class:absolute={absolute}>
|
||||||
|
<SelectedElementTitle {state} {layer} selectedElement={selected} />
|
||||||
|
<SelectedElementView {state} {layer} selectedElement={selected} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
|
@ -1,8 +1,3 @@
|
||||||
<script lang="ts">
|
|
||||||
|
|
||||||
import Translations from "../i18n/Translations"
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="flex h-full flex-col">
|
<div class="flex h-full flex-col">
|
||||||
<h2 class="low-interaction m-0 flex items-center p-4 drop-shadow-md">
|
<h2 class="low-interaction m-0 flex items-center p-4 drop-shadow-md">
|
||||||
<slot name="title" />
|
<slot name="title" />
|
||||||
|
|
|
@ -72,14 +72,14 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<slot name="close-button">
|
<slot name="close-button">
|
||||||
<div
|
<button
|
||||||
class="mt-2 h-fit shrink-0 rounded-full border-none p-0 cursor-pointer"
|
class="mt-2 h-fit shrink-0 rounded-full border-none p-0 cursor-pointer self-center"
|
||||||
on:click={() => state.selectedElement.setData(undefined)}
|
on:click={() => state.selectedElement.setData(undefined)}
|
||||||
style="border: 0 !important; padding: 0 !important;"
|
style="border: 0 !important; padding: 0 !important;"
|
||||||
use:ariaLabel={Translations.t.general.backToMap}
|
use:ariaLabel={Translations.t.general.backToMap}
|
||||||
>
|
>
|
||||||
<XCircleIcon aria-hidden={true} class="h-8 w-8" />
|
<XCircleIcon aria-hidden={true} class="h-8 w-8" />
|
||||||
</div>
|
</button>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,10 @@
|
||||||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||||
import TagRenderingEditable from "../Popup/TagRendering/TagRenderingEditable.svelte"
|
|
||||||
import { onDestroy } from "svelte"
|
import { onDestroy } from "svelte"
|
||||||
import Translations from "../i18n/Translations"
|
import Translations from "../i18n/Translations"
|
||||||
import Tr from "../Base/Tr.svelte"
|
import Tr from "../Base/Tr.svelte"
|
||||||
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
|
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
|
||||||
import UserRelatedState from "../../Logic/State/UserRelatedState"
|
|
||||||
import Delete_icon from "../../assets/svg/Delete_icon.svelte"
|
import Delete_icon from "../../assets/svg/Delete_icon.svelte"
|
||||||
import BackButton from "../Base/BackButton.svelte"
|
import BackButton from "../Base/BackButton.svelte"
|
||||||
import TagRenderingEditableDynamic from "../Popup/TagRendering/TagRenderingEditableDynamic.svelte"
|
import TagRenderingEditableDynamic from "../Popup/TagRendering/TagRenderingEditableDynamic.svelte"
|
||||||
|
@ -24,24 +22,8 @@
|
||||||
|
|
||||||
let isAddNew = tags.mapD(t => t?.id?.startsWith(LastClickFeatureSource.newPointElementId) ?? false)
|
let isAddNew = tags.mapD(t => t?.id?.startsWith(LastClickFeatureSource.newPointElementId) ?? false)
|
||||||
|
|
||||||
function getLayer(properties: Record<string, string>) {
|
|
||||||
if (properties.id === "settings") {
|
|
||||||
return UserRelatedState.usersettingsConfig
|
|
||||||
}
|
|
||||||
if (properties.id.startsWith(LastClickFeatureSource.newPointElementId)) {
|
|
||||||
return state.layout.layers.find((l) => l.id === "last_click")
|
|
||||||
}
|
|
||||||
if (properties.id === "location_track") {
|
|
||||||
return state.layout.layers.find((l) => l.id === "gps_track")
|
|
||||||
}
|
|
||||||
return state.layout.getMatchingLayer(properties)
|
|
||||||
}
|
|
||||||
|
|
||||||
let layer: LayerConfig = getLayer(selectedElement.properties)
|
export let layer: LayerConfig
|
||||||
|
|
||||||
let stillMatches = tags.map(
|
|
||||||
(tags) => !layer?.source?.osmTags || layer.source.osmTags?.matchesProperties(tags)
|
|
||||||
)
|
|
||||||
|
|
||||||
let _metatags: Record<string, string>
|
let _metatags: Record<string, string>
|
||||||
if (state?.userRelatedState?.preferencesAsTags) {
|
if (state?.userRelatedState?.preferencesAsTags) {
|
||||||
|
@ -53,7 +35,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let knownTagRenderings: Store<TagRenderingConfig[]> = tags.mapD((tgs) =>
|
let knownTagRenderings: Store<TagRenderingConfig[]> = tags.mapD((tgs) =>
|
||||||
layer.tagRenderings.filter(
|
layer?.tagRenderings?.filter(
|
||||||
(config) =>
|
(config) =>
|
||||||
(config.condition?.matchesProperties(tgs) ?? true) &&
|
(config.condition?.matchesProperties(tgs) ?? true) &&
|
||||||
(config.metacondition?.matchesProperties({ ...tgs, ..._metatags }) ?? true) &&
|
(config.metacondition?.matchesProperties({ ...tgs, ..._metatags }) ?? true) &&
|
||||||
|
@ -62,11 +44,7 @@
|
||||||
)
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !$stillMatches}
|
{#if $tags._deleted === "yes"}
|
||||||
<div class="alert" aria-live="assertive">
|
|
||||||
<Tr t={Translations.t.delete.isChanged} />
|
|
||||||
</div>
|
|
||||||
{:else if $tags._deleted === "yes"}
|
|
||||||
<div class="flex w-full flex-col p-2">
|
<div class="flex w-full flex-col p-2">
|
||||||
<div aria-live="assertive" class="alert flex items-center justify-center self-stretch">
|
<div aria-live="assertive" class="alert flex items-center justify-center self-stretch">
|
||||||
<Delete_icon class="m-2 h-8 w-8" />
|
<Delete_icon class="m-2 h-8 w-8" />
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
EyeIcon,
|
EyeIcon,
|
||||||
HeartIcon,
|
HeartIcon,
|
||||||
MenuIcon,
|
MenuIcon,
|
||||||
XCircleIcon,
|
XCircleIcon
|
||||||
} from "@rgossiaux/svelte-heroicons/solid"
|
} from "@rgossiaux/svelte-heroicons/solid"
|
||||||
import Tr from "./Base/Tr.svelte"
|
import Tr from "./Base/Tr.svelte"
|
||||||
import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte"
|
import CommunityIndexView from "./BigComponents/CommunityIndexView.svelte"
|
||||||
|
@ -72,9 +72,8 @@
|
||||||
import DocumentChartBar from "@babeard/svelte-heroicons/outline/DocumentChartBar"
|
import DocumentChartBar from "@babeard/svelte-heroicons/outline/DocumentChartBar"
|
||||||
import Marker from "./Map/Marker.svelte"
|
import Marker from "./Map/Marker.svelte"
|
||||||
import AboutMapComplete from "./BigComponents/AboutMapComplete.svelte"
|
import AboutMapComplete from "./BigComponents/AboutMapComplete.svelte"
|
||||||
import IfNot from "./Base/IfNot.svelte"
|
|
||||||
import Hotkeys from "./Base/Hotkeys"
|
|
||||||
import HotkeyTable from "./BigComponents/HotkeyTable.svelte"
|
import HotkeyTable from "./BigComponents/HotkeyTable.svelte"
|
||||||
|
import SelectedElementPanel from "./Base/SelectedElementPanel.svelte"
|
||||||
|
|
||||||
export let state: ThemeViewState
|
export let state: ThemeViewState
|
||||||
let layout = state.layout
|
let layout = state.layout
|
||||||
|
@ -146,7 +145,7 @@
|
||||||
const bottomRight = mlmap.unproject([rect.right, rect.bottom])
|
const bottomRight = mlmap.unproject([rect.right, rect.bottom])
|
||||||
const bbox = new BBox([
|
const bbox = new BBox([
|
||||||
[topLeft.lng, topLeft.lat],
|
[topLeft.lng, topLeft.lat],
|
||||||
[bottomRight.lng, bottomRight.lat],
|
[bottomRight.lng, bottomRight.lat]
|
||||||
])
|
])
|
||||||
state.visualFeedbackViewportBounds.setData(bbox)
|
state.visualFeedbackViewportBounds.setData(bbox)
|
||||||
}
|
}
|
||||||
|
@ -213,7 +212,7 @@
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div class="absolute top-0 left-0 h-screen w-screen overflow-hidden">
|
<div class="absolute top-0 left-0 h-screen w-screen overflow-hidden">
|
||||||
<MaplibreMap map={maplibremap} mapProperties={mapproperties} autorecovery={true}/>
|
<MaplibreMap map={maplibremap} mapProperties={mapproperties} autorecovery={true} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if $visualFeedback}
|
{#if $visualFeedback}
|
||||||
|
@ -287,9 +286,9 @@
|
||||||
htmlElem={openCurrentViewLayerButton}
|
htmlElem={openCurrentViewLayerButton}
|
||||||
>
|
>
|
||||||
<div class="w-8 h-8 cursor-pointer">
|
<div class="w-8 h-8 cursor-pointer">
|
||||||
<ToSvelte
|
<ToSvelte
|
||||||
construct={() => currentViewLayer.defaultIcon()}
|
construct={() => currentViewLayer.defaultIcon()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</MapControlButton>
|
</MapControlButton>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -303,7 +302,7 @@
|
||||||
<div class="thanks">
|
<div class="thanks">
|
||||||
Testserver
|
Testserver
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<If condition={state.featureSwitches.featureSwitchFakeUser}>
|
<If condition={state.featureSwitches.featureSwitchFakeUser}>
|
||||||
<div class="alert w-fit">Faking a user (Testmode)</div>
|
<div class="alert w-fit">Faking a user (Testmode)</div>
|
||||||
</If>
|
</If>
|
||||||
|
@ -453,29 +452,32 @@
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div slot="close-button" />
|
<div slot="close-button" />
|
||||||
<div class="normal-background absolute flex h-full w-full flex-col">
|
<SelectedElementPanel {state} selected={$selectedElement} />
|
||||||
<SelectedElementTitle {state} layer={$selectedLayer} selectedElement={$selectedElement} />
|
|
||||||
<SelectedElementView {state} selectedElement={$selectedElement} />
|
|
||||||
</div>
|
|
||||||
</ModalRight>
|
</ModalRight>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $selectedElement !== undefined && $selectedLayer !== undefined && $selectedLayer.popupInFloatover}
|
{#if $selectedElement !== undefined && $selectedLayer !== undefined && $selectedLayer.popupInFloatover}
|
||||||
<!-- Floatover with the selected element, if applicable -->
|
<!-- Floatover with the selected element, if applicable -->
|
||||||
<FloatOver
|
|
||||||
on:close={() => {
|
{#if $selectedLayer.popupInFloatover === "title"}
|
||||||
|
<FloatOver
|
||||||
|
on:close={() => {
|
||||||
state.selectedElement.setData(undefined)
|
state.selectedElement.setData(undefined)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="flex h-full w-full flex-col">
|
<span slot="close-button" />
|
||||||
{#if $selectedLayer.popupInFloatover === "title"}
|
<SelectedElementPanel absolute={false} {state} selected={$selectedElement} />
|
||||||
<SelectedElementTitle {state} layer={$selectedLayer} selectedElement={$selectedElement}>
|
</FloatOver>
|
||||||
<span slot="close-button" />
|
{:else}
|
||||||
</SelectedElementTitle>
|
<FloatOver
|
||||||
{/if}
|
on:close={() => {
|
||||||
<SelectedElementView {state} selectedElement={$selectedElement} />
|
state.selectedElement.setData(undefined)
|
||||||
</div>
|
}}
|
||||||
</FloatOver>
|
>
|
||||||
|
<SelectedElementView {state} layer={$selectedLayer} selectedElement={$selectedElement} />
|
||||||
|
</FloatOver>
|
||||||
|
{/if}
|
||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<If condition={state.previewedImage.map((i) => i !== undefined)}>
|
<If condition={state.previewedImage.map((i) => i !== undefined)}>
|
||||||
|
@ -551,13 +553,13 @@
|
||||||
state.guistate.backgroundLayerSelectionIsOpened.setData(false)
|
state.guistate.backgroundLayerSelectionIsOpened.setData(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RasterLayerOverview
|
<RasterLayerOverview
|
||||||
{availableLayers}
|
{availableLayers}
|
||||||
map={state.map}
|
map={state.map}
|
||||||
mapproperties={state.mapProperties}
|
mapproperties={state.mapProperties}
|
||||||
userstate={state.userRelatedState}
|
userstate={state.userRelatedState}
|
||||||
visible={state.guistate.backgroundLayerSelectionIsOpened}
|
visible={state.guistate.backgroundLayerSelectionIsOpened}
|
||||||
/>
|
/>
|
||||||
</FloatOver>
|
</FloatOver>
|
||||||
</IfHidden>
|
</IfHidden>
|
||||||
|
|
||||||
|
@ -583,7 +585,7 @@
|
||||||
<div slot="content0" class="flex flex-col">
|
<div slot="content0" class="flex flex-col">
|
||||||
<AboutMapComplete {state} />
|
<AboutMapComplete {state} />
|
||||||
<div class="m-2 flex flex-col">
|
<div class="m-2 flex flex-col">
|
||||||
<HotkeyTable/>
|
<HotkeyTable />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue