diff --git a/frontend/js/main.js b/frontend/js/main.js index 612216d..07fd1d8 100644 --- a/frontend/js/main.js +++ b/frontend/js/main.js @@ -94,8 +94,8 @@ async function init() { // Add padding entries so first back doesn't exit for (let i = 0; i < 3; i++) history.pushState({ screen: navStack[navStack.length - 1] }, ""); - // Restore last screen - renderScreen(navStack[navStack.length - 1]); + // Restore last screen (fromPopstate=true to avoid duplicate navStack push) + renderScreen(navStack[navStack.length - 1], true); } // --------------------------------------------------------------------------- @@ -642,18 +642,29 @@ function showModal(html, onSubmit) { history.pushState({ modal: true }, ""); const popHandler = () => { - // Fullscreen map inside modal? Collapse it first. + // Fullscreen map inside modal? Collapse it, stay in modal. const fsMap = overlay.querySelector(".sd-map-full"); if (fsMap) { fsMap.classList.remove("sd-map-full"); const expandBtn = fsMap.querySelector(".sd-map-expand-btn"); if (expandBtn) expandBtn.innerHTML = "⛶"; - try { map.dragging.disable(); map.scrollWheelZoom.disable(); } catch {} + 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); + } + } catch {} history.pushState({ modal: true }, ""); return; } - // Fullscreen chart inside modal? Collapse it first. - const fsChart = document.querySelector(".chart-full"); + // 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"); @@ -663,23 +674,21 @@ function showModal(html, onSubmit) { } // Nothing fullscreen — close modal window.removeEventListener("popstate", popHandler); - closeModal(false); + overlay.remove(); }; window.addEventListener("popstate", popHandler); - function closeModal(goBack) { - overlay.remove(); + function closeModal() { window.removeEventListener("popstate", popHandler); - if (goBack) history.back(); - // Ensure history isn't empty after modal close (prevents app exit on next back) - history.replaceState({ screen: state.screen }, ""); + overlay.remove(); + history.back(); // pops {modal: true}, returns to previous screen } - overlay.querySelector("#modal-back").onclick = () => closeModal(true); - overlay.querySelector("#modal-cancel").onclick = () => closeModal(true); + overlay.querySelector("#modal-back").onclick = () => closeModal(); + overlay.querySelector("#modal-cancel").onclick = () => closeModal(); overlay.querySelector("#modal-ok").onclick = async () => { const ok = await onSubmit(overlay); - if (ok !== false) { closeModal(true); renderScreen(state.screen); } + if (ok !== false) { closeModal(); renderScreen(state.screen); } }; setTimeout(() => overlay.querySelector("input")?.focus(), 50); } @@ -2182,6 +2191,7 @@ async function showSessionDetail(sessionId) { L.Icon.Default.imagePath = "lib/"; const map = L.map(mapEl, { attributionControl: false, zoomControl: false, scrollWheelZoom: false, dragging: false, tap: false, touchZoom: true }); + mapEl._leafletMap = map; // save for popHandler map collapse // Ctrl+wheel zoom on desktop mapEl.addEventListener("wheel", (e) => { if (e.ctrlKey) { e.preventDefault(); map.setZoom(map.getZoom() + (e.deltaY < 0 ? 1 : -1)); } @@ -2225,6 +2235,7 @@ async function showSessionDetail(sessionId) { } const allCoords = sortedCoords; + mapEl._bounds = L.latLngBounds(sortedCoords).pad(0.1); // save for collapse fitBounds // Fullscreen toggle button on map // Fullscreen map toggle @@ -2417,12 +2428,11 @@ 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. document.querySelectorAll(".chart-wrap").forEach(wrap => { wrap.onclick = () => { if (wrap.classList.contains("chart-full")) return; wrap.classList.add("chart-full"); - // Push history so back gesture collapses chart, not modal - history.pushState({ chartFull: true }, ""); const closeBtn = document.createElement("div"); closeBtn.className = "chart-close-btn"; closeBtn.innerHTML = "✕";