MapComplete/src/UI/Popup/MoveWizard.svelte

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

174 lines
6.3 KiB
Svelte
Raw Normal View History

<script lang="ts">
2023-12-19 16:35:11 +01:00
import { UIEventSource } from "../../Logic/UIEventSource"
import type { MoveReason } from "./MoveWizardState"
import { MoveWizardState } from "./MoveWizardState"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import Tr from "../Base/Tr.svelte"
import Translations from "../i18n/Translations"
import Move from "../../assets/svg/Move.svelte"
import Move_not_allowed from "../../assets/svg/Move_not_allowed.svelte"
import type { MapProperties } from "../../Models/MapProperties"
import type { Feature, Point } from "geojson"
import { GeoOperations } from "../../Logic/GeoOperations"
import OpenBackgroundSelectorButton from "../BigComponents/OpenBackgroundSelectorButton.svelte"
import If from "../Base/If.svelte"
import Constants from "../../Models/Constants"
import LoginToggle from "../Base/LoginToggle.svelte"
2024-06-18 03:33:11 +02:00
import AccordionSingle from "../Flowbite/AccordionSingle.svelte"
import ChevronLeft from "@babeard/svelte-heroicons/solid/ChevronLeft"
import ThemeViewState from "../../Models/ThemeViewState"
2024-08-01 20:44:37 +02:00
import Icon from "../Map/Icon.svelte"
import NewPointLocationInput from "../BigComponents/NewPointLocationInput.svelte"
import type { WayId } from "../../Models/OsmFeature"
2023-12-19 16:35:11 +01:00
2024-06-18 03:33:11 +02:00
export let state: ThemeViewState
2023-12-19 16:35:11 +01:00
export let layer: LayerConfig
export let featureToMove: Feature<Point>
let id: string = featureToMove.properties.id
2024-06-18 03:33:11 +02:00
let currentStep: "reason" | "pick_location" | "moved" = "reason"
2023-12-19 16:35:11 +01:00
const t = Translations.t.move
2024-06-18 03:33:11 +02:00
let reason = new UIEventSource<MoveReason>(undefined)
2023-12-19 16:35:11 +01:00
let [lon, lat] = GeoOperations.centerpointCoordinates(featureToMove)
let newLocation = new UIEventSource<{ lon: number; lat: number }>(undefined)
let snappedTo = new UIEventSource<WayId | undefined>(undefined)
function initMapProperties(reason: MoveReason) {
return <any>{
allowMoving: new UIEventSource(true),
allowRotating: new UIEventSource(false),
allowZooming: new UIEventSource(true),
bounds: new UIEventSource(undefined),
location: new UIEventSource({ lon, lat }),
minzoom: new UIEventSource(reason.minZoom),
rasterLayer: state.mapProperties.rasterLayer,
zoom: new UIEventSource(reason?.startZoom ?? 16),
2023-12-19 16:35:11 +01:00
}
}
let moveWizardState = new MoveWizardState(id, layer.allowMove, layer, state)
2024-06-20 04:21:29 +02:00
if (moveWizardState.reasons.length === 1) {
2024-06-18 03:33:11 +02:00
reason.setData(moveWizardState.reasons[0])
}
2023-12-19 16:35:11 +01:00
let notAllowed = moveWizardState.moveDisallowedReason
let currentMapProperties: MapProperties = undefined
</script>
2024-02-20 13:33:38 +01:00
{#if moveWizardState.reasons.length > 0}
<LoginToggle {state}>
2024-02-20 13:33:38 +01:00
{#if $notAllowed}
<div class="m-2 flex rounded-lg bg-gray-200 p-2">
<Move_not_allowed class="m-2 h-8 w-8" />
<div class="flex flex-col">
<Tr t={t.cannotBeMoved} />
<Tr t={$notAllowed} />
</div>
</div>
2024-06-18 03:33:11 +02:00
{:else}
<AccordionSingle>
<span slot="header" class="flex">
{#if moveWizardState.reasons.length === 1}
2024-08-14 13:53:56 +02:00
<Icon icon={moveWizardState.reasons[0].icon} clss="w-6 h-6" />
2024-06-18 03:33:11 +02:00
<Tr t={Translations.T(moveWizardState.reasons[0].invitingText)} />
{:else}
2024-06-20 04:21:29 +02:00
<Move class="h-6 w-6" />
<Tr t={t.inviteToMove.generic} />
2024-06-18 03:33:11 +02:00
{/if}
</span>
<span class="flex flex-col p-2">
{#if currentStep === "reason" && moveWizardState.reasons.length > 1}
{#each moveWizardState.reasons as reasonSpec}
2024-10-19 14:44:55 +02:00
<button
class="flex justify-start"
2024-06-18 03:33:11 +02:00
on:click={() => {
2024-06-20 04:21:29 +02:00
reason.setData(reasonSpec)
currentStep = "pick_location"
}}
2024-06-18 03:33:11 +02:00
>
2024-08-14 13:53:56 +02:00
<Icon icon={reasonSpec.icon} clss="w-12 h-12" />
2024-06-18 03:33:11 +02:00
<Tr t={Translations.T(reasonSpec.text)} />
</button>
{/each}
{:else if currentStep === "pick_location" || currentStep === "reason"}
<div class="relative h-64 w-full">
<NewPointLocationInput
mapProperties={(currentMapProperties = initMapProperties($reason))}
2024-06-18 03:33:11 +02:00
value={newLocation}
{state}
coordinate={{ lon, lat }}
{snappedTo}
maxSnapDistance={$reason.maxSnapDistance ?? 5}
snapToLayers={$reason.snapTo}
targetLayer={layer}
dontShow={[id]}
maxDistanceInMeters={$reason.maxSnapDistance ?? Infinity}
2024-06-18 03:33:11 +02:00
/>
<div class="absolute bottom-0 left-0">
<OpenBackgroundSelectorButton {state} />
</div>
</div>
2024-06-18 03:33:11 +02:00
{#if $reason.includeSearch}
2024-10-19 14:44:55 +02:00
<!-- TODO -->
2024-06-18 03:33:11 +02:00
{/if}
2024-02-20 13:33:38 +01:00
2024-06-18 03:33:11 +02:00
<div class="flex flex-wrap">
<If
condition={currentMapProperties.zoom.mapD(
2024-06-20 04:21:29 +02:00
(zoom) => zoom >= Constants.minZoomLevelToAddNewPoint
)}
2024-06-18 03:33:11 +02:00
>
<button
2024-06-20 04:21:29 +02:00
class="primary w-full"
2024-06-18 03:33:11 +02:00
on:click={() => {
2024-10-19 14:44:55 +02:00
moveWizardState.moveFeature(
newLocation.data,
snappedTo.data,
reason.data,
featureToMove
)
2024-06-20 04:21:29 +02:00
currentStep = "moved"
}}
2024-06-18 03:33:11 +02:00
>
<Tr t={t.confirmMove} />
</button>
2024-02-20 13:33:38 +01:00
2024-06-18 03:33:11 +02:00
<div slot="else" class="alert w-full">
<Tr t={t.zoomInFurther} />
</div>
</If>
{#if moveWizardState.reasons.length > 1}
2024-06-20 04:21:29 +02:00
<button
class="w-full"
on:click={() => {
currentStep = "reason"
}}
>
<ChevronLeft class="h-6 w-6" />
2024-06-18 03:33:11 +02:00
<Tr t={t.cancel} />
</button>
{/if}
2024-06-20 04:21:29 +02:00
</div>
2024-06-18 03:33:11 +02:00
{:else if currentStep === "moved"}
<div class="flex flex-col">
<Tr cls="thanks" t={t.pointIsMoved} />
<button
on:click={() => {
2024-06-20 04:21:29 +02:00
currentStep = "reason"
}}
2024-06-18 03:33:11 +02:00
>
<Move class="h-6 w-6 pr-2" />
<Tr t={t.inviteToMoveAgain} />
</button>
2024-02-20 13:33:38 +01:00
</div>
2024-06-18 03:33:11 +02:00
{/if}
</span>
</AccordionSingle>
2024-02-20 13:33:38 +01:00
{/if}
</LoginToggle>
{/if}