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)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -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 -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {#if $selectedLayer.popupInFloatover === "title"}
 | 
				
			||||||
      <FloatOver
 | 
					      <FloatOver
 | 
				
			||||||
        on:close={() => {
 | 
					        on:close={() => {
 | 
				
			||||||
        state.selectedElement.setData(undefined)
 | 
					        state.selectedElement.setData(undefined)
 | 
				
			||||||
      }}
 | 
					      }}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
      <div class="flex h-full w-full flex-col">
 | 
					 | 
				
			||||||
        {#if $selectedLayer.popupInFloatover === "title"}
 | 
					 | 
				
			||||||
          <SelectedElementTitle {state} layer={$selectedLayer} selectedElement={$selectedElement}>
 | 
					 | 
				
			||||||
        <span slot="close-button" />
 | 
					        <span slot="close-button" />
 | 
				
			||||||
          </SelectedElementTitle>
 | 
					         <SelectedElementPanel absolute={false} {state} selected={$selectedElement} />
 | 
				
			||||||
        {/if}
 | 
					 | 
				
			||||||
        <SelectedElementView {state} selectedElement={$selectedElement} />
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
      </FloatOver>
 | 
					      </FloatOver>
 | 
				
			||||||
 | 
					    {:else}
 | 
				
			||||||
 | 
					      <FloatOver
 | 
				
			||||||
 | 
					        on:close={() => {
 | 
				
			||||||
 | 
					        state.selectedElement.setData(undefined)
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <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)}>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue