Drag-and-drop waypoint reordering in sidebar list

This commit is contained in:
Davide Scaini
2026-05-22 14:23:19 +02:00
parent fa6225d2cd
commit 15a993ecc6
+49 -2
View File
@@ -391,6 +391,40 @@
fetchRoute();
}
let dragSrcIdx = $state(null);
let dragOverIdx = $state(null);
function onDragStart(e, i) {
dragSrcIdx = i;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', i);
}
function onDragOver(e, i) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
dragOverIdx = i;
}
function onDrop(e, i) {
e.preventDefault();
if (dragSrcIdx === null || dragSrcIdx === i) { dragSrcIdx = null; dragOverIdx = null; return; }
const arr = [...waypoints];
const [moved] = arr.splice(dragSrcIdx, 1);
arr.splice(i, 0, moved);
waypoints = arr;
waypoints.forEach((wp, idx) => { wp.marker.getElement().textContent = idx + 1; });
activePlanId = null;
fetchRoute();
dragSrcIdx = null;
dragOverIdx = null;
}
function onDragEnd() {
dragSrcIdx = null;
dragOverIdx = null;
}
function removeWaypoint(i) {
waypoints[i].marker.remove();
waypoints = waypoints.filter((_, idx) => idx !== i);
@@ -1094,7 +1128,16 @@ ${trkpts}
{:else}
<ul class="wp-list">
{#each waypoints as wp, i}
<li>
<li
draggable="true"
class:wp-drag-over={dragOverIdx === i && dragSrcIdx !== i}
class:wp-dragging={dragSrcIdx === i}
ondragstart={(e) => onDragStart(e, i)}
ondragover={(e) => onDragOver(e, i)}
ondrop={(e) => onDrop(e, i)}
ondragend={onDragEnd}
>
<span class="wp-drag-handle" title="Drag to reorder"></span>
<span class="wp-num" style={wp.gpxSnapped ? `background:${gpxColor}` : ''}>{i + 1}</span>
<span class="wp-coord">{wp.lat.toFixed(4)}, {wp.lng.toFixed(4)}</span>
{#if waypoints.length > 1}
@@ -1463,7 +1506,11 @@ ${trkpts}
.pill.active { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
.wp-list { list-style: none; margin: 0 0 0.5rem; padding: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.wp-list li { display: flex; align-items: center; gap: 0.375rem; font-size: 0.75rem; }
.wp-list li { display: flex; align-items: center; gap: 0.375rem; font-size: 0.75rem; cursor: grab; border-radius: 0.25rem; transition: background 0.1s, opacity 0.1s; }
.wp-list li:active { cursor: grabbing; }
.wp-dragging { opacity: 0.4; }
.wp-drag-over { background: var(--accent-dim); outline: 1px dashed var(--accent); }
.wp-drag-handle { color: var(--text-5); font-size: 0.75rem; cursor: grab; flex-shrink: 0; user-select: none; }
.wp-num { width: 1.25rem; height: 1.25rem; border-radius: 50%; background: var(--accent); color: #000; font-size: 0.65rem; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.wp-coord { flex: 1; color: var(--text-4); font-variant-numeric: tabular-nums; }
.remove-btn { background: none; border: none; color: var(--text-5); cursor: pointer; font-size: 1rem; line-height: 1; padding: 0 0.125rem; }