Avoid map zoom-out when navigating between routes
Route links (route_master list, other directions) now intercept clicks and call loadRoute() + history.pushState() instead of doing a full page reload, so the map stays at its current position and zooms smoothly into the new route. Ctrl/cmd/middle-click still opens in a new tab via href. Introduce currentRelationId (mutable) to track the loaded relation so loadSegment() uses the correct ID after in-page navigation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3223d4b063
commit
f6dd68ed75
1 changed files with 20 additions and 1 deletions
|
|
@ -22,6 +22,7 @@ let routeMasterLayers = []; // coloured polylines when viewing a route_master
|
|||
|
||||
// ── State ─────────────────────────────────────────────────────────────────
|
||||
|
||||
let currentRelationId = RELATION_ID; // tracks the currently loaded relation
|
||||
let routeData = null; // response from /api/route/
|
||||
let segmentGeoJson = null; // last response from /api/segment/ (always includes stops)
|
||||
let activeSlot = 'from'; // 'from' | 'to' | null
|
||||
|
|
@ -301,6 +302,21 @@ document.getElementById('include-stops').addEventListener('change', () => {
|
|||
document.getElementById('slot-from').addEventListener('click', () => setActiveSlot('from'));
|
||||
document.getElementById('slot-to').addEventListener('click', () => setActiveSlot('to'));
|
||||
|
||||
// ── Navigation ─────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Load a relation without a full page reload, updating the browser URL.
|
||||
* Allows middle-click / ctrl-click to still open in a new tab via the href.
|
||||
* @param {number} id
|
||||
* @param {MouseEvent} e
|
||||
*/
|
||||
function navigateTo(id, e) {
|
||||
if (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0) return;
|
||||
e.preventDefault();
|
||||
history.pushState(null, '', `/${id}`);
|
||||
loadRoute(id);
|
||||
}
|
||||
|
||||
// ── API calls ──────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
|
|
@ -320,6 +336,7 @@ async function loadRoute(relationId) {
|
|||
return;
|
||||
}
|
||||
routeData = data;
|
||||
currentRelationId = relationId;
|
||||
// Clean up any previous route_master view
|
||||
for (const l of routeMasterLayers) l.remove();
|
||||
routeMasterLayers = [];
|
||||
|
|
@ -358,6 +375,7 @@ async function loadRoute(relationId) {
|
|||
a.href = `/${dir.id}`;
|
||||
a.className = 'stop-item d-block text-decoration-none';
|
||||
a.textContent = dir.name;
|
||||
a.addEventListener('click', (e) => navigateTo(dir.id, e));
|
||||
dirList.appendChild(a);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -373,7 +391,7 @@ async function loadRoute(relationId) {
|
|||
*/
|
||||
async function loadSegment() {
|
||||
if (!selectedFrom || !selectedTo || !routeData) return;
|
||||
const rid = RELATION_ID;
|
||||
const rid = currentRelationId;
|
||||
const params = new URLSearchParams({ from: selectedFrom, to: selectedTo, stops: '1' });
|
||||
try {
|
||||
const resp = await fetch(`/api/segment/${rid}?${params}`);
|
||||
|
|
@ -444,6 +462,7 @@ async function loadRouteMaster(relationId) {
|
|||
a.href = `/${route.id}`;
|
||||
a.className = 'text-decoration-none text-reset flex-grow-1';
|
||||
a.textContent = route.name;
|
||||
a.addEventListener('click', (e) => navigateTo(route.id, e));
|
||||
|
||||
div.appendChild(dot);
|
||||
div.appendChild(a);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue