diff --git a/src/server/request-handler.ts b/src/server/request-handler.ts index 3b38361..7abcd65 100644 --- a/src/server/request-handler.ts +++ b/src/server/request-handler.ts @@ -367,25 +367,43 @@ function htmlPage(): string { } .theme-toggle { - position: fixed; - top: 16px; - right: 16px; - z-index: 900; width: 40px; height: 40px; padding: 0; justify-content: center; + } + + .top-right-controls { + position: fixed; + top: 16px; + right: 16px; + z-index: 900; + display: grid; + gap: 8px; + } + + .route-toggle { + width: 40px; + height: 40px; + padding: 0; + justify-content: center; + } + + .theme-toggle, + .route-toggle { background: var(--timeline-surface-soft); color: var(--timeline-text); border: 1px solid var(--timeline-border); box-shadow: var(--shadow-soft); } - .theme-toggle:hover { + .theme-toggle:hover, + .route-toggle:hover { background: var(--timeline-surface-strong); } - .theme-toggle .button-icon { + .theme-toggle .button-icon, + .route-toggle .button-icon { width: 18px; height: 18px; } @@ -980,6 +998,11 @@ function htmlPage(): string { right: 12px; } + .top-right-controls { + top: 12px; + right: 12px; + } + .list { max-height: min(52vh, 420px); --photo-thumb-size: 64px; @@ -1007,14 +1030,25 @@ function htmlPage(): string { - +
+ + +
@@ -1182,11 +1216,13 @@ function htmlPage(): string { color: "#2d6cdf", weight: 4, opacity: 0.85 - }).addTo(map); + }); const routeColors = { light: "#2d6cdf", dark: "#7dd3fc" }; + const ROUTE_VISIBLE_STORAGE_KEY = "routeVisible"; + let routeVisible = localStorage.getItem(ROUTE_VISIBLE_STORAGE_KEY) !== "false"; const overlay = mustGet("overlay"); const overlayTitle = mustGet("overlay-title"); @@ -1194,6 +1230,8 @@ function htmlPage(): string { const overlayLoading = mustGet("overlay-loading"); const overlayLoadingText = mustGet("overlay-loading-text"); const closeOverlay = mustGet("close-overlay"); + const routeToggle = mustGet("route-toggle"); + const routeToggleIcon = mustGet("route-toggle-icon"); const photoList = mustGet("photo-list"); const emptyState = mustGet("empty-state"); const photoCount = mustGet("photo-count"); @@ -1362,6 +1400,36 @@ function htmlPage(): string { }); } + function setRouteVisible(visible) { + routeVisible = Boolean(visible); + localStorage.setItem(ROUTE_VISIBLE_STORAGE_KEY, routeVisible ? "true" : "false"); + + if (routeVisible) { + if (!map.hasLayer(route)) { + route.addTo(map); + } + routeToggle.setAttribute("aria-label", "Hide route line"); + routeToggleIcon.innerHTML = + '' + + '' + + '' + + '' + + ""; + } else { + if (map.hasLayer(route)) { + map.removeLayer(route); + } + routeToggle.setAttribute("aria-label", "Show route line"); + routeToggleIcon.innerHTML = + '' + + '' + + '' + + '' + + '' + + ""; + } + } + function scheduleMapResize() { window.clearTimeout(scheduleMapResize.timeoutId); scheduleMapResize.timeoutId = window.setTimeout(() => { @@ -1416,6 +1484,10 @@ function htmlPage(): string { themeToggle.addEventListener("click", () => { setTheme(document.body.dataset.theme === "dark" ? "light" : "dark"); }); + setRouteVisible(routeVisible); + routeToggle.addEventListener("click", () => { + setRouteVisible(!routeVisible); + }); const storedSidebarCollapsed = localStorage.getItem("sidebarCollapsed") === "true"; setSidebarCollapsed(storedSidebarCollapsed);