feat: toggle map route visibility
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user