adds search to trail edit

This commit is contained in:
Christian Beutel
2025-01-12 15:29:51 +01:00
parent 7005b3677f
commit 8536ba422c
12 changed files with 144 additions and 9 deletions

View File

@@ -94,6 +94,25 @@
border-color: rgba(var(--primary)) transparent rgba(var(--primary)) transparent;
}
.spinner-light:after {
border: 6px solid #fff;
border-color: #fff transparent #fff transparent;
}
.spinner-small {
width: 24px;
height: 24px;
display: grid;
align-content: center;
justify-content: center;
}
.spinner-small:after {
border-width: 2px;
width: 16px;
height: 16px;
}
@keyframes spinner {
0% {
transform: rotate(0deg);

View File

@@ -80,6 +80,7 @@
"edit": "Bearbeiten",
"edit-entry": "Eintrag bearbeiten",
"edit-list": "Liste bearbeiten",
"edit-route": "",
"edit-waypoint": "Wegpunkt bearbeiten",
"edited": "bearbeitet",
"elevation-gain": "Höhenunterschied (aufw.)",
@@ -259,6 +260,7 @@
"speed": "Geschwindigkeit",
"statistics": "Statistiken",
"stop-drawing": "Zeichnen beenden",
"stop-editing": "",
"summit-book": "Gipfelbuch",
"table": "Tabelle",
"text": "Text",
@@ -270,6 +272,7 @@
"units": "Einheiten",
"upload-file": "Datei hochladen",
"upload-gpx": "GPX hochladen",
"upload-new-file": "",
"uploaded": "hochgeladen",
"username": "Nutzername",
"view": "Ansehen",

View File

@@ -80,6 +80,7 @@
"edit": "Edit",
"edit-entry": "Edit Entry",
"edit-list": "Edit List",
"edit-route": "Edit route",
"edit-waypoint": "Edit Waypoint",
"edited": "edited",
"elevation-gain": "Elevation Gain",
@@ -259,6 +260,7 @@
"speed": "Speed",
"statistics": "Statistics",
"stop-drawing": "Stop drawing",
"stop-editing": "Stop editing",
"summit-book": "Summit Book",
"table": "Table",
"text": "Text",
@@ -270,6 +272,7 @@
"units": "Units",
"upload-file": "Upload file",
"upload-gpx": "Upload GPX",
"upload-new-file": "Upload new file",
"uploaded": "uploaded",
"username": "Username",
"view": "View",

View File

@@ -80,6 +80,7 @@
"edit": "Editar",
"edit-entry": "Editar entrada",
"edit-list": "Editar Lista",
"edit-route": "",
"edit-waypoint": "Editar Punto de Interés",
"edited": "editado",
"elevation-gain": "Ascenso",
@@ -259,6 +260,7 @@
"speed": "Velocidad",
"statistics": "Estadísticas",
"stop-drawing": "Parar de diseñar",
"stop-editing": "",
"summit-book": "Libro de ascensos",
"table": "Tabla",
"text": "Texto",
@@ -270,6 +272,7 @@
"units": "Unidades",
"upload-file": "Cargar archivo",
"upload-gpx": "Cargar GPX",
"upload-new-file": "",
"uploaded": "cargado",
"username": "Nombre de usuario",
"view": "Ver",

View File

@@ -80,6 +80,7 @@
"edit": "Editer",
"edit-entry": "Éditer une entrée",
"edit-list": "Éditer la liste",
"edit-route": "",
"edit-waypoint": "Éditer le point de repère",
"edited": "edited",
"elevation-gain": "Dénivelé positif",
@@ -259,6 +260,7 @@
"speed": "Vitesse",
"statistics": "Statistics",
"stop-drawing": "Arrêter de tracer",
"stop-editing": "",
"summit-book": "Liste des ascensions",
"table": "Tableau",
"text": "Texte",
@@ -270,6 +272,7 @@
"units": "Unités",
"upload-file": "Importer un fichier",
"upload-gpx": "Envoyer un GPX",
"upload-new-file": "",
"uploaded": "téléchargé",
"username": "Nom d'utilisateur",
"view": "Afficher",

View File

@@ -80,6 +80,7 @@
"edit": "Szerkesztés",
"edit-entry": "Bejegyzés szerkesztése",
"edit-list": "Lista szerkesztése",
"edit-route": "",
"edit-waypoint": "Útvonalpont szerkesztése",
"edited": "edited",
"elevation-gain": "Magasságnövekedés",
@@ -259,6 +260,7 @@
"speed": "Speed",
"statistics": "Statistics",
"stop-drawing": "Stop drawing",
"stop-editing": "",
"summit-book": "Csúcspont könyv",
"table": "Táblázat",
"text": "Szöveg",
@@ -270,6 +272,7 @@
"units": "Mértékegységek",
"upload-file": "Fájl feltöltése",
"upload-gpx": "GPX feltöltése",
"upload-new-file": "",
"uploaded": "uploaded",
"username": "Felhasználónév",
"view": "View",

View File

@@ -80,6 +80,7 @@
"edit": "Modifica",
"edit-entry": "Modifica voce",
"edit-list": "Modifica lista",
"edit-route": "",
"edit-waypoint": "Modifica waypoint",
"edited": "modificato",
"elevation-gain": "Guadagno di quota",
@@ -259,6 +260,7 @@
"speed": "Velocità",
"statistics": "Statistiche",
"stop-drawing": "Smettere di disegnare",
"stop-editing": "",
"summit-book": "Libro di vetta",
"table": "Tavolo",
"text": "Testo",
@@ -270,6 +272,7 @@
"units": "Unità",
"upload-file": "Carica file",
"upload-gpx": "Carica file GPX",
"upload-new-file": "",
"uploaded": "caricato",
"username": "Nome utente",
"view": "Visualizza",

View File

@@ -80,6 +80,7 @@
"edit": "Bewerken",
"edit-entry": "Item bewerken",
"edit-list": "Lijst aanpassen",
"edit-route": "",
"edit-waypoint": "Routepunt aanpassen",
"edited": "edited",
"elevation-gain": "Hoogteverschil",
@@ -259,6 +260,7 @@
"speed": "Speed",
"statistics": "Statistics",
"stop-drawing": "Stop drawing",
"stop-editing": "",
"summit-book": "Bergtopboek",
"table": "Tabel",
"text": "Tekst",
@@ -270,6 +272,7 @@
"units": "Eenheden",
"upload-file": "Bestand uploaden",
"upload-gpx": "GPX-bestand uploaden",
"upload-new-file": "",
"uploaded": "uploaded",
"username": "Gebruikersnaam",
"view": "View",

View File

@@ -80,6 +80,7 @@
"edit": "Edytuj",
"edit-entry": "Edytuj pozycję",
"edit-list": "Edytuj Listę",
"edit-route": "",
"edit-waypoint": "Edytuj Punkt",
"edited": "edited",
"elevation-gain": "Przyrost wysokości",
@@ -259,6 +260,7 @@
"speed": "Prędkość",
"statistics": "Statystyki",
"stop-drawing": "Przestań rysować",
"stop-editing": "",
"summit-book": "Logbook",
"table": "Tabela",
"text": "Tekst",
@@ -270,6 +272,7 @@
"units": "Jednostki",
"upload-file": "Przesyłanie pliku",
"upload-gpx": "Importuj GPX",
"upload-new-file": "",
"uploaded": "wgrany",
"username": "Nazwa Użytkownika",
"view": "Widok",

View File

@@ -80,6 +80,7 @@
"edit": "Editar",
"edit-entry": "Editar entrada",
"edit-list": "Editar lista",
"edit-route": "",
"edit-waypoint": "Editar ponto de passagem",
"edited": "edited",
"elevation-gain": "Ganho de elevação",
@@ -259,6 +260,7 @@
"speed": "Velocidade",
"statistics": "Statistics",
"stop-drawing": "Parar desenho",
"stop-editing": "",
"summit-book": "Livro da cimeira",
"table": "Tabela",
"text": "Texto",
@@ -270,6 +272,7 @@
"units": "Unidades",
"upload-file": "Subir arquivo",
"upload-gpx": "Carregar GPX",
"upload-new-file": "",
"uploaded": "carregado",
"username": "Nome de utilizador",
"view": "Ver",

View File

@@ -80,6 +80,7 @@
"edit": "编辑",
"edit-entry": "编辑日程",
"edit-list": "编辑列表",
"edit-route": "",
"edit-waypoint": "编辑坐标",
"edited": "edited",
"elevation-gain": "上升海拔",
@@ -259,6 +260,7 @@
"speed": "速度",
"statistics": "Statistics",
"stop-drawing": "停止绘制",
"stop-editing": "",
"summit-book": "详细日程",
"table": "表格",
"text": "文本",
@@ -270,6 +272,7 @@
"units": "单位",
"upload-file": "上传文件",
"upload-gpx": "上传 GPX",
"upload-new-file": "",
"uploaded": "已上传",
"username": "用户名",
"view": "查看",

View File

@@ -70,6 +70,10 @@
import { backInOut } from "svelte/easing";
import { scale } from "svelte/transition";
import { z } from "zod";
import Search, {
type SearchItem,
} from "$lib/components/base/search.svelte";
import { country_codes } from "$lib/util/country_code_util.js";
export let data;
@@ -96,6 +100,8 @@
let overwriteGPX = false;
let draggingMarker = false;
let searchDropdownItems: SearchItem[] = [];
const ClientTrailCreateSchema = TrailCreateSchema.extend({
expand: z
.object({
@@ -523,6 +529,12 @@
addAnchor(e.lngLat.lat, e.lngLat.lng, anchors.length);
} else {
const previousAnchor = anchors[anchorCount - 1];
const anchor = addAnchor(
e.lngLat.lat,
e.lngLat.lng,
anchors.length,
);
const markerText = startAnchorLoading(anchor);
try {
const routeWaypoints = await calculateRouteBetween(
previousAnchor.lat,
@@ -533,7 +545,6 @@
autoRouting,
);
insertIntoRoute(routeWaypoints);
addAnchor(e.lngLat.lat, e.lngLat.lng, anchors.length);
updateTrailWithRouteData();
} catch (e) {
console.error(e);
@@ -542,6 +553,8 @@
icon: "close",
type: "error",
});
} finally {
stopAnchorLoading(anchor, markerText);
}
}
}
@@ -567,14 +580,16 @@
(e) => {
draggingMarker = true;
},
(_) => {
async (_) => {
if (!drawingActive) {
return;
}
const position = marker.getLngLat();
anchor.lat = position.lat;
anchor.lon = position.lng;
recalculateRoute(anchors.findIndex((a) => a.id == anchor.id));
await recalculateRoute(
anchors.findIndex((a) => a.id == anchor.id),
);
draggingMarker = false;
},
);
@@ -587,7 +602,32 @@
return anchor;
}
function removeAnchor(anchorIndex: number) {
function startAnchorLoading(anchor: ValhallaAnchor) {
const markerIcon = anchor.marker?.getElement();
if (!markerIcon) {
return null;
}
markerIcon.classList.add("spinner", "spinner-light", "spinner-small");
const savedMarkerNumber = markerIcon.textContent;
markerIcon.textContent = "";
return savedMarkerNumber;
}
function stopAnchorLoading(anchor: ValhallaAnchor, index: string | null) {
const markerIcon = anchor.marker?.getElement();
if (!markerIcon || !index) {
return;
}
markerIcon.classList.remove(
"spinner",
"spinner-light",
"spinner-small",
);
markerIcon.textContent = index;
}
async function removeAnchor(anchorIndex: number) {
if (!drawingActive) {
return;
}
@@ -610,11 +650,13 @@
updateTrailWithRouteData();
} else {
deleteFromRoute(anchorIndex - 1);
recalculateRoute(anchorIndex);
await recalculateRoute(anchorIndex);
}
}
async function recalculateRoute(anchorIndex: number) {
const markerText = startAnchorLoading(anchors[anchorIndex]);
const anchor = anchors[anchorIndex];
if (!anchor) {
return;
@@ -661,6 +703,8 @@
icon: "close",
type: "error",
});
} finally {
stopAnchorLoading(anchors[anchorIndex], markerText);
}
}
@@ -676,6 +720,8 @@
data.event.lngLat.lng,
data.segment + 1,
);
const markerText = startAnchorLoading(anchor);
for (let i = data.segment + 2; i < anchors.length; i++) {
const anchor = anchors[i];
const markerIcon = anchor.marker?.getElement();
@@ -716,6 +762,8 @@
icon: "close",
type: "error",
});
} finally {
stopAnchorLoading(anchor, markerText);
}
}
@@ -735,6 +783,30 @@
function updateTrailOnMap() {
mapTrail = [$formData as Trail];
}
function handleSearchClick(item: SearchItem) {
map.flyTo({
center: [item.value._geo.lng, item.value._geo.lat],
zoom: 13,
animate: false,
});
}
async function searchCities(q: string) {
const r = await fetch("/api/v1/search/cities500", {
method: "POST",
body: JSON.stringify({ q: q, options: { limit: 5 } }),
});
const result = await r.json();
searchDropdownItems = result.hits.map((h: Record<string, any>) => ({
text: h.name,
description: `${h.division ? `${h.division} | ` : ""}${
country_codes[h["country code"] as keyof typeof country_codes]
}`,
value: h,
icon: "city",
}));
}
</script>
<svelte:head>
@@ -750,12 +822,22 @@
class="overflow-y-auto overflow-x-hidden flex flex-col gap-4 px-8 order-1 md:order-none mt-8 md:mt-0"
use:form
>
<Search
on:update={(e) => searchCities(e.detail)}
on:click={(e) => handleSearchClick(e.detail)}
placeholder="{$_('search-cities')}..."
items={searchDropdownItems}
></Search>
<hr class="border-input-border" />
<h3 class="text-xl font-semibold">{$_("pick-a-trail")}</h3>
<Button
primary={true}
type="button"
disabled={drawingActive}
on:click={openFileBrowser}>{$_("upload-file")}</Button
on:click={openFileBrowser}
>{$formData.expand?.gpx_data
? $_("upload-new-file")
: $_("upload-file")}</Button
>
{#if PUBLIC_VALHALLA_URL}
<div class="flex gap-4 items-center w-full">
@@ -768,9 +850,13 @@
type="button"
on:click={drawingActive ? stopDrawing : startDrawing}
>
{drawingActive
? $_("stop-drawing")
: $_("draw-a-route")}</button
{$formData.expand?.gpx_data
? drawingActive
? $_("stop-editing")
: $_("edit-route")
: drawingActive
? $_("stop-drawing")
: $_("draw-a-route")}</button
>
{/if}
<input