diff --git a/web/src/lib/i18n/locales/de.json b/web/src/lib/i18n/locales/de.json index 1377a43e..85e01b3f 100644 --- a/web/src/lib/i18n/locales/de.json +++ b/web/src/lib/i18n/locales/de.json @@ -53,6 +53,7 @@ "contribute": "Mitwirken", "copy-link": "Link kopieren", "create-new-list": "Neue Liste erstellen", + "create-waypoint": "", "creation-date": "Erstellungsdatum", "current-password": "Aktuelles Passwort", "cycling": "Radfahren", diff --git a/web/src/lib/i18n/locales/en.json b/web/src/lib/i18n/locales/en.json index 94c16297..0d0d6f5c 100644 --- a/web/src/lib/i18n/locales/en.json +++ b/web/src/lib/i18n/locales/en.json @@ -53,6 +53,7 @@ "contribute": "Contribute", "copy-link": "Copy Link", "create-new-list": "Create new list", + "create-waypoint": "Create waypoint", "creation-date": "Creation date", "current-password": "Current password", "cycling": "Cycling", diff --git a/web/src/lib/i18n/locales/es.json b/web/src/lib/i18n/locales/es.json index 33c8df6a..1db20164 100644 --- a/web/src/lib/i18n/locales/es.json +++ b/web/src/lib/i18n/locales/es.json @@ -53,6 +53,7 @@ "contribute": "Contribuir", "copy-link": "Copiar Enlace", "create-new-list": "Crear una nueva lista", + "create-waypoint": "", "creation-date": "Fecha de creación", "current-password": "Contraseña actual", "cycling": "Ciclismo", diff --git a/web/src/lib/i18n/locales/fr.json b/web/src/lib/i18n/locales/fr.json index 778f4ba9..e8438f2a 100644 --- a/web/src/lib/i18n/locales/fr.json +++ b/web/src/lib/i18n/locales/fr.json @@ -53,6 +53,7 @@ "contribute": "Contribuer", "copy-link": "Copier le lien", "create-new-list": "Créer une nouvelle liste", + "create-waypoint": "", "creation-date": "Date de création", "current-password": "Mot de passe actuel", "cycling": "Vélo", diff --git a/web/src/lib/i18n/locales/hu.json b/web/src/lib/i18n/locales/hu.json index 4a7a980a..a967525e 100644 --- a/web/src/lib/i18n/locales/hu.json +++ b/web/src/lib/i18n/locales/hu.json @@ -53,6 +53,7 @@ "contribute": "Hozzájárulás", "copy-link": "Copy Link", "create-new-list": "Új lista létrehozása", + "create-waypoint": "", "creation-date": "létrehozás dátuma", "current-password": "Current password", "cycling": "Cycling", diff --git a/web/src/lib/i18n/locales/it.json b/web/src/lib/i18n/locales/it.json index dfbfa0eb..210c109f 100644 --- a/web/src/lib/i18n/locales/it.json +++ b/web/src/lib/i18n/locales/it.json @@ -53,6 +53,7 @@ "contribute": "Contribuisci", "copy-link": "Copia link", "create-new-list": "Crea nuova lista", + "create-waypoint": "", "creation-date": "Data di creazione", "current-password": "Password attuale", "cycling": "Ciclismo", diff --git a/web/src/lib/i18n/locales/nl.json b/web/src/lib/i18n/locales/nl.json index 29ae0953..8b575e6d 100644 --- a/web/src/lib/i18n/locales/nl.json +++ b/web/src/lib/i18n/locales/nl.json @@ -53,6 +53,7 @@ "contribute": "Bijdragen", "copy-link": "Copy Link", "create-new-list": "Nieuwe lijst", + "create-waypoint": "", "creation-date": "Aanmaakdatum", "current-password": "Huidig wachtwoord", "cycling": "Fietsen", diff --git a/web/src/lib/i18n/locales/pl.json b/web/src/lib/i18n/locales/pl.json index 3e0137af..053b04be 100644 --- a/web/src/lib/i18n/locales/pl.json +++ b/web/src/lib/i18n/locales/pl.json @@ -53,6 +53,7 @@ "contribute": "Kontrybuuj", "copy-link": "Kopiuj link", "create-new-list": "Stwórz nową listę", + "create-waypoint": "", "creation-date": "Data dodania", "current-password": "Obecne hasło", "cycling": "Rower", diff --git a/web/src/lib/i18n/locales/pt.json b/web/src/lib/i18n/locales/pt.json index 8d48c81e..9f5c3df9 100644 --- a/web/src/lib/i18n/locales/pt.json +++ b/web/src/lib/i18n/locales/pt.json @@ -53,6 +53,7 @@ "contribute": "Contribuir", "copy-link": "Copiar ligação", "create-new-list": "Criar nova lista", + "create-waypoint": "", "creation-date": "Data de criação", "current-password": "Senha atual", "cycling": "Ciclismo", diff --git a/web/src/lib/i18n/locales/zh.json b/web/src/lib/i18n/locales/zh.json index 890846ae..92380ab7 100644 --- a/web/src/lib/i18n/locales/zh.json +++ b/web/src/lib/i18n/locales/zh.json @@ -53,6 +53,7 @@ "contribute": "贡献", "copy-link": "复制链接", "create-new-list": "创建新列表", + "create-waypoint": "", "creation-date": "创建日期", "current-password": "当前密码", "cycling": "骑行", diff --git a/web/src/lib/util/maplibre_util.ts b/web/src/lib/util/maplibre_util.ts index 31f9a173..62900fcb 100644 --- a/web/src/lib/util/maplibre_util.ts +++ b/web/src/lib/util/maplibre_util.ts @@ -136,6 +136,35 @@ export function createAnchorMarker(lat: number, lon: number, index: number, return marker } +export function createEditTrailMapPopup(lnglat: M.LngLat, onCreateWaypointClick: () => void) { + const popup = new M.Popup({ closeOnClick: false }) + .setLngLat(lnglat) + + const popupContent = document.createElement("div"); + popupContent.className = "pt-1 pb-3 pl-3" + const popupH = document.createElement("h5") + popupH.classList.add("text-base", "font-medium", "mb-2"); + popupH.textContent = `${lnglat.lat.toFixed(4)}, ${lnglat.lng.toFixed(4)}`; + + const createWaypointButton = document.createElement("button"); + createWaypointButton.className = "btn-secondary w-full mt-2 text-sm"; + const deleteButtonIcon = document.createElement("i") + deleteButtonIcon.classList.add("fa", "fa-location-dot", "mr-2") + createWaypointButton.appendChild(deleteButtonIcon) + const createWaypointButtonText = document.createElement("span") + createWaypointButtonText.textContent = get(_)("create-waypoint") + createWaypointButton.appendChild(deleteButtonIcon) + createWaypointButton.appendChild(createWaypointButtonText) + createWaypointButton.addEventListener("click", onCreateWaypointClick) + + popupContent.appendChild(popupH) + popupContent.appendChild(createWaypointButton) + + popup.setDOMContent(popupContent) + + return popup +} + export function createPopupFromTrail(trail: Trail) { const thumbnail = trail.photos.length ? getFileURL(trail, trail.photos[trail.thumbnail ?? 0]) diff --git a/web/src/routes/trail/edit/[id]/+page.svelte b/web/src/routes/trail/edit/[id]/+page.svelte index 5b634aed..c1a3a8b9 100644 --- a/web/src/routes/trail/edit/[id]/+page.svelte +++ b/web/src/routes/trail/edit/[id]/+page.svelte @@ -53,14 +53,23 @@ } from "$lib/util/format_util"; import { fromFile, gpx2trail } from "$lib/util/gpx_util"; + import { page } from "$app/state"; import emptyStateTrailDark from "$lib/assets/svgs/empty_states/empty_state_trail_dark.svg"; import emptyStateTrailLight from "$lib/assets/svgs/empty_states/empty_state_trail_light.svg"; + import type { DropdownItem } from "$lib/components/base/dropdown.svelte"; import Search, { type SearchItem, } from "$lib/components/base/search.svelte"; + import { + searchLocationReverse, + searchLocations, + } from "$lib/stores/search_store.js"; import { theme } from "$lib/stores/theme_store.js"; - import { country_codes } from "$lib/util/country_code_util.js"; - import { createAnchorMarker } from "$lib/util/maplibre_util"; + import { getIconForLocation } from "$lib/util/icon_util.js"; + import { + createAnchorMarker, + createEditTrailMapPopup, + } from "$lib/util/maplibre_util"; import { validator } from "@felte/validator-zod"; import cryptoRandomString from "crypto-random-string"; import { createForm } from "felte"; @@ -70,17 +79,11 @@ import { backInOut } from "svelte/easing"; import { scale } from "svelte/transition"; import { z } from "zod"; - import { page } from "$app/state"; - import type { DropdownItem } from "$lib/components/base/dropdown.svelte"; - import { - searchLocationReverse, - searchLocations, - } from "$lib/stores/search_store.js"; - import { getIconForLocation } from "$lib/util/icon_util.js"; let { data } = $props(); let map: M.Map | undefined = $state(); + let mapPopup: M.Popup | undefined; let mapTrail: Trail[] = $state([]); let lists = $state(data.lists); @@ -389,12 +392,12 @@ } } - function beforeWaypointModalOpen() { + function beforeWaypointModalOpen(lat?: number, lon?: number) { if (!map) { return; } const mapCenter = map.getCenter(); - waypoint.set(new Waypoint(mapCenter.lat, mapCenter.lng)); + waypoint.set(new Waypoint(lat ?? mapCenter.lat, lon ?? mapCenter.lng)); waypointModal.openModal(); } @@ -536,14 +539,24 @@ } async function handleMapClick(e: M.MapMouseEvent) { - if (!drawingActive) { - return; - } - const anchorCount = anchors.length; - if (anchorCount == 0) { - addAnchor(e.lngLat.lat, e.lngLat.lng, anchors.length); + if (!drawingActive) { + if ((e.originalEvent.target as HTMLElement).tagName.toLowerCase() !== "canvas") { + return; + } + mapPopup?.remove(); + + mapPopup = createEditTrailMapPopup(e.lngLat, () => { + mapPopup?.remove(); + beforeWaypointModalOpen(e.lngLat.lat, e.lngLat.lng); + }); + mapPopup.addTo(map!); } else { - await addAnchorAndRecalculate(e.lngLat.lat, e.lngLat.lng); + const anchorCount = anchors.length; + if (anchorCount == 0) { + addAnchor(e.lngLat.lat, e.lngLat.lng, anchors.length); + } else { + await addAnchorAndRecalculate(e.lngLat.lat, e.lngLat.lng); + } } } @@ -1030,7 +1043,7 @@