forked from MapComplete/MapComplete
		
	UX: move some items behind login-toggles, add a 'login to add pictures' button again (fix #1698)
This commit is contained in:
		
							parent
							
								
									5168b42c8f
								
							
						
					
					
						commit
						4e1384c2df
					
				
					 4 changed files with 182 additions and 174 deletions
				
			
		| 
						 | 
					@ -1,50 +1,53 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  /**
 | 
					    /**
 | 
				
			||||||
   * Shows an 'upload'-button which will start the upload for this feature
 | 
					     * Shows an 'upload'-button which will start the upload for this feature
 | 
				
			||||||
   */
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  import type { SpecialVisualizationState } from "../SpecialVisualization"
 | 
					    import type { SpecialVisualizationState } from "../SpecialVisualization"
 | 
				
			||||||
  import { ImmutableStore, Store } from "../../Logic/UIEventSource"
 | 
					    import { ImmutableStore, Store } from "../../Logic/UIEventSource"
 | 
				
			||||||
  import type { OsmTags } from "../../Models/OsmFeature"
 | 
					    import type { OsmTags } from "../../Models/OsmFeature"
 | 
				
			||||||
  import LoginToggle from "../Base/LoginToggle.svelte"
 | 
					    import LoginToggle from "../Base/LoginToggle.svelte"
 | 
				
			||||||
  import Translations from "../i18n/Translations"
 | 
					    import Translations from "../i18n/Translations"
 | 
				
			||||||
  import Tr from "../Base/Tr.svelte"
 | 
					    import Tr from "../Base/Tr.svelte"
 | 
				
			||||||
  import UploadingImageCounter from "./UploadingImageCounter.svelte"
 | 
					    import UploadingImageCounter from "./UploadingImageCounter.svelte"
 | 
				
			||||||
  import FileSelector from "../Base/FileSelector.svelte"
 | 
					    import FileSelector from "../Base/FileSelector.svelte"
 | 
				
			||||||
  import Camera_plus from "../../assets/svg/Camera_plus.svelte"
 | 
					    import Camera_plus from "../../assets/svg/Camera_plus.svelte"
 | 
				
			||||||
 | 
					    import LoginButton from "../Base/LoginButton.svelte"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let state: SpecialVisualizationState
 | 
					    export let state: SpecialVisualizationState
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let tags: Store<OsmTags>
 | 
					    export let tags: Store<OsmTags>
 | 
				
			||||||
  export let targetKey: string = undefined
 | 
					    export let targetKey: string = undefined
 | 
				
			||||||
  /**
 | 
					    /**
 | 
				
			||||||
   * Image to show in the button
 | 
					     * Image to show in the button
 | 
				
			||||||
   * NOT the image to upload!
 | 
					     * NOT the image to upload!
 | 
				
			||||||
   */
 | 
					     */
 | 
				
			||||||
  export let image: string = undefined
 | 
					    export let image: string = undefined
 | 
				
			||||||
  if (image === "") {
 | 
					    if (image === "") {
 | 
				
			||||||
    image = undefined
 | 
					        image = undefined
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
  export let labelText: string = undefined
 | 
					    export let labelText: string = undefined
 | 
				
			||||||
  const t = Translations.t.image
 | 
					    const t = Translations.t.image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let licenseStore = state?.userRelatedState?.imageLicense ?? new ImmutableStore("CC0")
 | 
					    let licenseStore = state?.userRelatedState?.imageLicense ?? new ImmutableStore("CC0")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function handleFiles(files: FileList) {
 | 
					    function handleFiles(files: FileList) {
 | 
				
			||||||
    for (let i = 0; i < files.length; i++) {
 | 
					        for (let i = 0; i < files.length; i++) {
 | 
				
			||||||
      const file = files.item(i)
 | 
					            const file = files.item(i)
 | 
				
			||||||
      console.log("Got file", file.name)
 | 
					            console.log("Got file", file.name)
 | 
				
			||||||
      try {
 | 
					            try {
 | 
				
			||||||
        state?.imageUploadManager.uploadImageAndApply(file, tags, targetKey)
 | 
					                state?.imageUploadManager.uploadImageAndApply(file, tags, targetKey)
 | 
				
			||||||
      } catch (e) {
 | 
					            } catch (e) {
 | 
				
			||||||
        alert(e)
 | 
					                alert(e)
 | 
				
			||||||
      }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<LoginToggle {state}>
 | 
					<LoginToggle {state}>
 | 
				
			||||||
  <Tr slot="not-logged-in" t={t.pleaseLogin} />
 | 
					  <LoginButton slot="not-logged-in" clss="small w-full">
 | 
				
			||||||
 | 
					    <Tr t={Translations.t.image.pleaseLogin} />
 | 
				
			||||||
 | 
					  </LoginButton>
 | 
				
			||||||
  <div class="flex flex-col">
 | 
					  <div class="flex flex-col">
 | 
				
			||||||
    <UploadingImageCounter {state} {tags} />
 | 
					    <UploadingImageCounter {state} {tags} />
 | 
				
			||||||
    <FileSelector
 | 
					    <FileSelector
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,95 +1,95 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  import LoginToggle from "../../Base/LoginToggle.svelte"
 | 
					    import LoginToggle from "../../Base/LoginToggle.svelte"
 | 
				
			||||||
  import type { SpecialVisualizationState } from "../../SpecialVisualization"
 | 
					    import type { SpecialVisualizationState } from "../../SpecialVisualization"
 | 
				
			||||||
  import Translations from "../../i18n/Translations"
 | 
					    import Translations from "../../i18n/Translations"
 | 
				
			||||||
  import Tr from "../../Base/Tr.svelte"
 | 
					    import Tr from "../../Base/Tr.svelte"
 | 
				
			||||||
  import { TrashIcon } from "@babeard/svelte-heroicons/mini"
 | 
					    import { TrashIcon } from "@babeard/svelte-heroicons/mini"
 | 
				
			||||||
  import type { OsmId, OsmTags } from "../../../Models/OsmFeature"
 | 
					    import type { OsmId, OsmTags } from "../../../Models/OsmFeature"
 | 
				
			||||||
  import DeleteConfig from "../../../Models/ThemeConfig/DeleteConfig"
 | 
					    import DeleteConfig from "../../../Models/ThemeConfig/DeleteConfig"
 | 
				
			||||||
  import TagRenderingQuestion from "../TagRendering/TagRenderingQuestion.svelte"
 | 
					    import TagRenderingQuestion from "../TagRendering/TagRenderingQuestion.svelte"
 | 
				
			||||||
  import type { Feature } from "geojson"
 | 
					    import type { Feature } from "geojson"
 | 
				
			||||||
  import { UIEventSource } from "../../../Logic/UIEventSource"
 | 
					    import { UIEventSource } from "../../../Logic/UIEventSource"
 | 
				
			||||||
  import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
 | 
					    import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
 | 
				
			||||||
  import { TagsFilter } from "../../../Logic/Tags/TagsFilter"
 | 
					    import { TagsFilter } from "../../../Logic/Tags/TagsFilter"
 | 
				
			||||||
  import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid"
 | 
					    import { XCircleIcon } from "@rgossiaux/svelte-heroicons/solid"
 | 
				
			||||||
  import { TagUtils } from "../../../Logic/Tags/TagUtils"
 | 
					    import { TagUtils } from "../../../Logic/Tags/TagUtils"
 | 
				
			||||||
  import OsmChangeAction from "../../../Logic/Osm/Actions/OsmChangeAction"
 | 
					    import OsmChangeAction from "../../../Logic/Osm/Actions/OsmChangeAction"
 | 
				
			||||||
  import DeleteAction from "../../../Logic/Osm/Actions/DeleteAction"
 | 
					    import DeleteAction from "../../../Logic/Osm/Actions/DeleteAction"
 | 
				
			||||||
  import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction"
 | 
					    import ChangeTagAction from "../../../Logic/Osm/Actions/ChangeTagAction"
 | 
				
			||||||
  import Loading from "../../Base/Loading.svelte"
 | 
					    import Loading from "../../Base/Loading.svelte"
 | 
				
			||||||
  import { DeleteFlowState } from "./DeleteFlowState"
 | 
					    import { DeleteFlowState } from "./DeleteFlowState"
 | 
				
			||||||
  import { twJoin } from "tailwind-merge"
 | 
					    import { twJoin } from "tailwind-merge"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let state: SpecialVisualizationState
 | 
					    export let state: SpecialVisualizationState
 | 
				
			||||||
  export let deleteConfig: DeleteConfig
 | 
					    export let deleteConfig: DeleteConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let tags: UIEventSource<OsmTags>
 | 
					    export let tags: UIEventSource<OsmTags>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let featureId: OsmId = <OsmId>tags.data.id
 | 
					    let featureId: OsmId = <OsmId>tags.data.id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let feature: Feature
 | 
					    export let feature: Feature
 | 
				
			||||||
  export let layer: LayerConfig
 | 
					    export let layer: LayerConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const deleteAbility = new DeleteFlowState(featureId, state, deleteConfig.neededChangesets)
 | 
					    const deleteAbility = new DeleteFlowState(featureId, state, deleteConfig.neededChangesets)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const canBeDeleted: UIEventSource<boolean | undefined> = deleteAbility.canBeDeleted
 | 
					    const canBeDeleted: UIEventSource<boolean | undefined> = deleteAbility.canBeDeleted
 | 
				
			||||||
  const canBeDeletedReason = deleteAbility.canBeDeletedReason
 | 
					    const canBeDeletedReason = deleteAbility.canBeDeletedReason
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const hasSoftDeletion = deleteConfig.softDeletionTags !== undefined
 | 
					    const hasSoftDeletion = deleteConfig.softDeletionTags !== undefined
 | 
				
			||||||
  let currentState: "start" | "confirm" | "applying" | "deleted" = "start"
 | 
					    let currentState: "start" | "confirm" | "applying" | "deleted" = "start"
 | 
				
			||||||
  $: {
 | 
					    $: {
 | 
				
			||||||
    deleteAbility.CheckDeleteability(true)
 | 
					        deleteAbility.CheckDeleteability(true)
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const t = Translations.t.delete
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  let selectedTags: TagsFilter
 | 
					 | 
				
			||||||
  let changedProperties = undefined
 | 
					 | 
				
			||||||
  $: changedProperties = TagUtils.changeAsProperties(selectedTags?.asChange(tags?.data ?? {}) ?? [])
 | 
					 | 
				
			||||||
  let isHardDelete = undefined
 | 
					 | 
				
			||||||
  $: isHardDelete = changedProperties[DeleteConfig.deleteReasonKey] !== undefined
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async function onDelete() {
 | 
					 | 
				
			||||||
    if (selectedTags === undefined) {
 | 
					 | 
				
			||||||
      return
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    currentState = "applying"
 | 
					 | 
				
			||||||
    let actionToTake: OsmChangeAction
 | 
					 | 
				
			||||||
    const changedProperties = TagUtils.changeAsProperties(selectedTags.asChange(tags?.data ?? {}))
 | 
					 | 
				
			||||||
    const deleteReason = changedProperties[DeleteConfig.deleteReasonKey]
 | 
					 | 
				
			||||||
    if (deleteReason) {
 | 
					 | 
				
			||||||
      // This is a proper, hard deletion
 | 
					 | 
				
			||||||
      actionToTake = new DeleteAction(
 | 
					 | 
				
			||||||
        featureId,
 | 
					 | 
				
			||||||
        deleteConfig.softDeletionTags,
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          theme: state?.layout?.id ?? "unknown",
 | 
					 | 
				
			||||||
          specialMotivation: deleteReason,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        canBeDeleted.data
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      // no _delete_reason is given, which implies that this is _not_ a deletion but merely a retagging via a nonDeleteMapping
 | 
					 | 
				
			||||||
      actionToTake = new ChangeTagAction(featureId, selectedTags, tags.data, {
 | 
					 | 
				
			||||||
        theme: state?.layout?.id ?? "unkown",
 | 
					 | 
				
			||||||
        changeType: "special-delete",
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await state.changes?.applyAction(actionToTake)
 | 
					    const t = Translations.t.delete
 | 
				
			||||||
    tags.data["_deleted"] = "yes"
 | 
					
 | 
				
			||||||
    tags.ping()
 | 
					    let selectedTags: TagsFilter
 | 
				
			||||||
    currentState = "deleted"
 | 
					    let changedProperties = undefined
 | 
				
			||||||
  }
 | 
					    $: changedProperties = TagUtils.changeAsProperties(selectedTags?.asChange(tags?.data ?? {}) ?? [])
 | 
				
			||||||
 | 
					    let isHardDelete = undefined
 | 
				
			||||||
 | 
					    $: isHardDelete = changedProperties[DeleteConfig.deleteReasonKey] !== undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async function onDelete() {
 | 
				
			||||||
 | 
					        if (selectedTags === undefined) {
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        currentState = "applying"
 | 
				
			||||||
 | 
					        let actionToTake: OsmChangeAction
 | 
				
			||||||
 | 
					        const changedProperties = TagUtils.changeAsProperties(selectedTags.asChange(tags?.data ?? {}))
 | 
				
			||||||
 | 
					        const deleteReason = changedProperties[DeleteConfig.deleteReasonKey]
 | 
				
			||||||
 | 
					        if (deleteReason) {
 | 
				
			||||||
 | 
					            // This is a proper, hard deletion
 | 
				
			||||||
 | 
					            actionToTake = new DeleteAction(
 | 
				
			||||||
 | 
					                featureId,
 | 
				
			||||||
 | 
					                deleteConfig.softDeletionTags,
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    theme: state?.layout?.id ?? "unknown",
 | 
				
			||||||
 | 
					                    specialMotivation: deleteReason,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                canBeDeleted.data,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // no _delete_reason is given, which implies that this is _not_ a deletion but merely a retagging via a nonDeleteMapping
 | 
				
			||||||
 | 
					            actionToTake = new ChangeTagAction(featureId, selectedTags, tags.data, {
 | 
				
			||||||
 | 
					                theme: state?.layout?.id ?? "unkown",
 | 
				
			||||||
 | 
					                changeType: "special-delete",
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await state.changes?.applyAction(actionToTake)
 | 
				
			||||||
 | 
					        tags.data["_deleted"] = "yes"
 | 
				
			||||||
 | 
					        tags.ping()
 | 
				
			||||||
 | 
					        currentState = "deleted"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					<LoginToggle ignoreLoading={true} {state}>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#if $canBeDeleted === false && !hasSoftDeletion}
 | 
					  {#if $canBeDeleted === false && !hasSoftDeletion}
 | 
				
			||||||
  <div class="low-interaction flex flex-col">
 | 
					    <div class="low-interaction flex flex-col">
 | 
				
			||||||
    <Tr t={$canBeDeletedReason} />
 | 
					      <Tr t={$canBeDeletedReason} />
 | 
				
			||||||
    <Tr cls="subtle" t={t.useSomethingElse} />
 | 
					      <Tr cls="subtle" t={t.useSomethingElse} />
 | 
				
			||||||
  </div>
 | 
					    </div>
 | 
				
			||||||
{:else}
 | 
					  {:else}
 | 
				
			||||||
  <LoginToggle ignoreLoading={true} {state}>
 | 
					 | 
				
			||||||
    {#if currentState === "start"}
 | 
					    {#if currentState === "start"}
 | 
				
			||||||
      <button
 | 
					      <button
 | 
				
			||||||
        class="flex items-center"
 | 
					        class="flex items-center"
 | 
				
			||||||
| 
						 | 
					@ -158,5 +158,5 @@
 | 
				
			||||||
        <Tr t={t.isDeleted} />
 | 
					        <Tr t={t.isDeleted} />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    {/if}
 | 
					    {/if}
 | 
				
			||||||
  </LoginToggle>
 | 
					  {/if}
 | 
				
			||||||
{/if}
 | 
					</LoginToggle>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,61 +1,63 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  /**
 | 
					    /**
 | 
				
			||||||
   * Show nearby images which can be clicked
 | 
					     * Show nearby images which can be clicked
 | 
				
			||||||
   */
 | 
					     */
 | 
				
			||||||
  import type { OsmTags } from "../../Models/OsmFeature"
 | 
					    import type { OsmTags } from "../../Models/OsmFeature"
 | 
				
			||||||
  import { Store, UIEventSource } from "../../Logic/UIEventSource"
 | 
					    import { Store, UIEventSource } from "../../Logic/UIEventSource"
 | 
				
			||||||
  import type { SpecialVisualizationState } from "../SpecialVisualization"
 | 
					    import type { SpecialVisualizationState } from "../SpecialVisualization"
 | 
				
			||||||
  import type { P4CPicture } from "../../Logic/Web/NearbyImagesSearch"
 | 
					    import type { P4CPicture } from "../../Logic/Web/NearbyImagesSearch"
 | 
				
			||||||
  import NearbyImagesSearch from "../../Logic/Web/NearbyImagesSearch"
 | 
					    import NearbyImagesSearch from "../../Logic/Web/NearbyImagesSearch"
 | 
				
			||||||
  import LinkableImage from "./LinkableImage.svelte"
 | 
					    import LinkableImage from "./LinkableImage.svelte"
 | 
				
			||||||
  import type { Feature } from "geojson"
 | 
					    import type { Feature } from "geojson"
 | 
				
			||||||
  import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
 | 
					    import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
 | 
				
			||||||
  import Loading from "../Base/Loading.svelte"
 | 
					    import Loading from "../Base/Loading.svelte"
 | 
				
			||||||
  import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
 | 
					    import AllImageProviders from "../../Logic/ImageProviders/AllImageProviders"
 | 
				
			||||||
  import Tr from "../Base/Tr.svelte"
 | 
					    import Tr from "../Base/Tr.svelte"
 | 
				
			||||||
  import Translations from "../i18n/Translations"
 | 
					    import Translations from "../i18n/Translations"
 | 
				
			||||||
 | 
					    import LoginToggle from "../Base/LoginToggle.svelte"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let tags: Store<OsmTags>
 | 
					    export let tags: Store<OsmTags>
 | 
				
			||||||
  export let state: SpecialVisualizationState
 | 
					    export let state: SpecialVisualizationState
 | 
				
			||||||
  export let lon: number
 | 
					    export let lon: number
 | 
				
			||||||
  export let lat: number
 | 
					    export let lat: number
 | 
				
			||||||
  export let feature: Feature
 | 
					    export let feature: Feature
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let linkable: boolean = true
 | 
					    export let linkable: boolean = true
 | 
				
			||||||
  export let layer: LayerConfig
 | 
					    export let layer: LayerConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let imagesProvider = new NearbyImagesSearch(
 | 
					    let imagesProvider = new NearbyImagesSearch(
 | 
				
			||||||
    {
 | 
					        {
 | 
				
			||||||
      lon,
 | 
					            lon,
 | 
				
			||||||
      lat,
 | 
					            lat,
 | 
				
			||||||
      allowSpherical: new UIEventSource<boolean>(false),
 | 
					            allowSpherical: new UIEventSource<boolean>(false),
 | 
				
			||||||
      blacklist: AllImageProviders.LoadImagesFor(tags),
 | 
					            blacklist: AllImageProviders.LoadImagesFor(tags),
 | 
				
			||||||
    },
 | 
					        },
 | 
				
			||||||
    state.indexedFeatures
 | 
					        state.indexedFeatures,
 | 
				
			||||||
  )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let images: Store<P4CPicture[]> = imagesProvider.store.map((images) => images.slice(0, 20))
 | 
					    let images: Store<P4CPicture[]> = imagesProvider.store.map((images) => images.slice(0, 20))
 | 
				
			||||||
  let allDone = imagesProvider.allDone
 | 
					    let allDone = imagesProvider.allDone
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					<LoginToggle {state}>
 | 
				
			||||||
<div class="interactive border-interactive rounded-2xl p-2">
 | 
					  <div class="interactive border-interactive rounded-2xl p-2">
 | 
				
			||||||
  <div class="flex justify-between">
 | 
					    <div class="flex justify-between">
 | 
				
			||||||
    <h4>
 | 
					      <h4>
 | 
				
			||||||
      <Tr t={Translations.t.image.nearby.title} />
 | 
					        <Tr t={Translations.t.image.nearby.title} />
 | 
				
			||||||
    </h4>
 | 
					      </h4>
 | 
				
			||||||
    <slot name="corner" />
 | 
					      <slot name="corner" />
 | 
				
			||||||
  </div>
 | 
					    </div>
 | 
				
			||||||
  {#if !$allDone}
 | 
					    {#if !$allDone}
 | 
				
			||||||
    <Loading />
 | 
					      <Loading />
 | 
				
			||||||
  {:else if $images.length === 0}
 | 
					    {:else if $images.length === 0}
 | 
				
			||||||
    <Tr t={Translations.t.image.nearby.noNearbyImages} cls="alert"/>
 | 
					      <Tr t={Translations.t.image.nearby.noNearbyImages} cls="alert" />
 | 
				
			||||||
  {:else}
 | 
					    {:else}
 | 
				
			||||||
    <div class="flex w-full space-x-1 overflow-x-auto" style="scroll-snap-type: x proximity">
 | 
					      <div class="flex w-full space-x-1 overflow-x-auto" style="scroll-snap-type: x proximity">
 | 
				
			||||||
      {#each $images as image (image.pictureUrl)}
 | 
					        {#each $images as image (image.pictureUrl)}
 | 
				
			||||||
        <span class="w-fit shrink-0" style="scroll-snap-align: start">
 | 
					        <span class="w-fit shrink-0" style="scroll-snap-align: start">
 | 
				
			||||||
          <LinkableImage {tags} {image} {state} {lon} {lat} {feature} {layer} {linkable} />
 | 
					          <LinkableImage {tags} {image} {state} {lon} {lat} {feature} {layer} {linkable} />
 | 
				
			||||||
        </span>
 | 
					        </span>
 | 
				
			||||||
      {/each}
 | 
					        {/each}
 | 
				
			||||||
    </div>
 | 
					      </div>
 | 
				
			||||||
  {/if}
 | 
					    {/if}
 | 
				
			||||||
</div>
 | 
					  </div>
 | 
				
			||||||
 | 
					</LoginToggle>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@
 | 
				
			||||||
  import { XCircleIcon } from "@babeard/svelte-heroicons/solid"
 | 
					  import { XCircleIcon } from "@babeard/svelte-heroicons/solid"
 | 
				
			||||||
  import exp from "constants"
 | 
					  import exp from "constants"
 | 
				
			||||||
  import Camera_plus from "../../assets/svg/Camera_plus.svelte"
 | 
					  import Camera_plus from "../../assets/svg/Camera_plus.svelte"
 | 
				
			||||||
 | 
					  import LoginToggle from "../Base/LoginToggle.svelte"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let tags: Store<OsmTags>
 | 
					  export let tags: Store<OsmTags>
 | 
				
			||||||
  export let state: SpecialVisualizationState
 | 
					  export let state: SpecialVisualizationState
 | 
				
			||||||
| 
						 | 
					@ -25,6 +26,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let expanded = false
 | 
					  let expanded = false
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					<LoginToggle {state}>
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
{#if expanded}
 | 
					{#if expanded}
 | 
				
			||||||
  <NearbyImages {tags} {state} {lon} {lat} {feature} {linkable}>
 | 
					  <NearbyImages {tags} {state} {lon} {lat} {feature} {linkable}>
 | 
				
			||||||
| 
						 | 
					@ -47,3 +49,4 @@
 | 
				
			||||||
    <Tr t={t.seeNearby} />
 | 
					    <Tr t={t.seeNearby} />
 | 
				
			||||||
  </button>
 | 
					  </button>
 | 
				
			||||||
{/if}
 | 
					{/if}
 | 
				
			||||||
 | 
					</LoginToggle>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue