diff --git a/frontend/js/main.js b/frontend/js/main.js index 82bff91..912e1fd 100644 --- a/frontend/js/main.js +++ b/frontend/js/main.js @@ -808,53 +808,60 @@ function showModal(html, onSubmit) { `; document.body.appendChild(overlay); + // Simple history stack: each open = pushState, each back = popState pops it. + // Modal = 1 entry. Fullscreen map/chart inside modal = 1 more entry each. + // Back always pops the top entry. No re-pushing, no flags. + let _historyDepth = 1; // how many entries this modal owns history.pushState({ modal: true }, ""); + const popHandler = () => { - // Fullscreen map inside modal? Collapse it, stay in modal. + _historyDepth--; + + // Check what's on top and collapse it const fsMap = overlay.querySelector(".sd-map-full"); if (fsMap) { fsMap.classList.remove("sd-map-full"); - // Update expand button icon const expandBtn = fsMap.querySelector(".sd-map-expand-btn"); if (expandBtn) expandBtn.innerHTML = "⛶"; - // Reset map controls and size try { const mapObj = fsMap._leafletMap; if (mapObj) { mapObj.dragging.disable(); mapObj.scrollWheelZoom.disable(); - setTimeout(() => { - mapObj.invalidateSize(); - const bounds = fsMap._bounds; - if (bounds) mapObj.fitBounds(bounds); - }, 100); + setTimeout(() => { mapObj.invalidateSize(); if (fsMap._bounds) mapObj.fitBounds(fsMap._bounds); }, 100); } } catch {} - // Stay in modal — re-push entry that back consumed - history.pushState({ modal: true }, ""); - return; + return; // stay in modal, depth already decremented } - // Fullscreen chart inside modal? Collapse it, stay in modal. + const fsChart = overlay.querySelector(".chart-full"); if (fsChart) { fsChart.classList.remove("chart-full"); const btn = fsChart.querySelector(".chart-close-btn"); if (btn) btn.remove(); - history.pushState({ modal: true }, ""); - return; + return; // stay in modal } - // Nothing fullscreen — close modal. Set flag so global handler skips this event. + + // Nothing fullscreen — close modal _modalPopHandled = true; window.removeEventListener("popstate", popHandler); overlay.remove(); }; window.addEventListener("popstate", popHandler); + // Called when fullscreen opens inside this modal — push 1 entry + overlay._pushFullscreen = function() { + _historyDepth++; + history.pushState({ modalFs: true }, ""); + }; + function closeModal() { - _modalPopHandled = true; // prevent global handler from also processing the back window.removeEventListener("popstate", popHandler); overlay.remove(); - history.back(); // pops {modal: true}, returns to previous screen + // Pop all entries this modal owns + if (_historyDepth > 0) { + for (let i = 0; i < _historyDepth; i++) history.back(); + } } overlay.querySelector("#modal-back").onclick = () => closeModal(); @@ -2606,19 +2613,18 @@ async function showSessionDetail(sessionId) { // Fullscreen map toggle function toggleMapFs() { if (mapEl.classList.contains("sd-map-full")) { - // Collapse - mapEl.classList.remove("sd-map-full"); - fsDiv.innerHTML = "⛶"; - map.dragging.disable(); - map.scrollWheelZoom.disable(); - setTimeout(() => { map.invalidateSize(); map.fitBounds(L.latLngBounds(allCoords).pad(0.05)); }, 100); + // Collapse via history.back() — popHandler will handle the CSS + history.back(); } else { - // Expand + // Expand — push to history stack mapEl.classList.add("sd-map-full"); fsDiv.innerHTML = "✕"; map.dragging.enable(); map.scrollWheelZoom.enable(); setTimeout(() => { map.invalidateSize(); map.fitBounds(L.latLngBounds(allCoords).pad(0.05)); }, 100); + // Push fullscreen entry — back will pop it + const modal = mapEl.closest(".modal-overlay"); + if (modal && modal._pushFullscreen) modal._pushFullscreen(); } } @@ -2786,18 +2792,19 @@ async function showSessionDetail(sessionId) { if (exp) exp.onclick = () => GPS.exportGPX(sessionId); // Chart fullscreen toggle — tap to expand, tap X or back to collapse - // Chart fullscreen in modal — NO pushState. Modal popHandler handles back. + // Chart fullscreen in modal — pushState so back collapses it document.querySelectorAll(".chart-wrap").forEach(wrap => { wrap.onclick = () => { if (wrap.classList.contains("chart-full")) return; wrap.classList.add("chart-full"); + const modal = wrap.closest(".modal-overlay"); + if (modal && modal._pushFullscreen) modal._pushFullscreen(); const closeBtn = document.createElement("div"); closeBtn.className = "chart-close-btn"; closeBtn.innerHTML = "✕"; closeBtn.onclick = (e) => { e.stopPropagation(); - wrap.classList.remove("chart-full"); - closeBtn.remove(); + history.back(); // popHandler will collapse }; wrap.appendChild(closeBtn); };