feat: toggle map route visibility

This commit is contained in:
2026-06-13 08:02:20 +02:00
parent f3fdf15a3e
commit ab8cad1931

View File

@@ -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 {
</style>
</head>
<body data-theme="light">
<button class="secondary theme-toggle" id="theme-toggle" type="button" aria-label="Switch to dark mode">
<span class="button-icon" id="theme-toggle-icon" aria-hidden="true">
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 1.8V3.1M8 12.9v1.3M3.1 3.1l.9.9M12 12l.9.9M1.8 8H3.1M12.9 8h1.3M3.1 12.9l.9-.9M12 4l.9-.9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>
<circle cx="8" cy="8" r="3.2" stroke="currentColor" stroke-width="1.4"/>
</svg>
</span>
</button>
<div class="top-right-controls">
<button class="secondary theme-toggle" id="theme-toggle" type="button" aria-label="Switch to dark mode">
<span class="button-icon" id="theme-toggle-icon" aria-hidden="true">
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 1.8V3.1M8 12.9v1.3M3.1 3.1l.9.9M12 12l.9.9M1.8 8H3.1M12.9 8h1.3M3.1 12.9l.9-.9M12 4l.9-.9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/>
<circle cx="8" cy="8" r="3.2" stroke="currentColor" stroke-width="1.4"/>
</svg>
</span>
</button>
<button class="secondary route-toggle" id="route-toggle" type="button" aria-label="Hide route line">
<span class="button-icon" id="route-toggle-icon" aria-hidden="true">
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 11.5 6.2 8.2c.4-.4 1-.5 1.5-.2l1.1.7c.5.3 1.1.2 1.5-.2L13 5.8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="3" cy="11.5" r="1" fill="currentColor"/>
<circle cx="13" cy="5.8" r="1" fill="currentColor"/>
</svg>
</span>
</button>
</div>
<main>
<section class="map-panel">
<div id="map"></div>
@@ -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 =
'<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">' +
'<path d="M3 11.5 6.2 8.2c.4-.4 1-.5 1.5-.2l1.1.7c.5.3 1.1.2 1.5-.2L13 5.8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>' +
'<circle cx="3" cy="11.5" r="1" fill="currentColor"/>' +
'<circle cx="13" cy="5.8" r="1" fill="currentColor"/>' +
"</svg>";
} else {
if (map.hasLayer(route)) {
map.removeLayer(route);
}
routeToggle.setAttribute("aria-label", "Show route line");
routeToggleIcon.innerHTML =
'<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">' +
'<path d="M3 11.5 6.2 8.2c.4-.4 1-.5 1.5-.2l1.1.7c.5.3 1.1.2 1.5-.2L13 5.8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>' +
'<circle cx="3" cy="11.5" r="1" fill="currentColor"/>' +
'<circle cx="13" cy="5.8" r="1" fill="currentColor"/>' +
'<path d="M3 13 13 3" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>' +
"</svg>";
}
}
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);