feat: toggle map route visibility
This commit is contained in:
@@ -367,25 +367,43 @@ function htmlPage(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle {
|
.theme-toggle {
|
||||||
position: fixed;
|
|
||||||
top: 16px;
|
|
||||||
right: 16px;
|
|
||||||
z-index: 900;
|
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
justify-content: center;
|
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);
|
background: var(--timeline-surface-soft);
|
||||||
color: var(--timeline-text);
|
color: var(--timeline-text);
|
||||||
border: 1px solid var(--timeline-border);
|
border: 1px solid var(--timeline-border);
|
||||||
box-shadow: var(--shadow-soft);
|
box-shadow: var(--shadow-soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle:hover {
|
.theme-toggle:hover,
|
||||||
|
.route-toggle:hover {
|
||||||
background: var(--timeline-surface-strong);
|
background: var(--timeline-surface-strong);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle .button-icon {
|
.theme-toggle .button-icon,
|
||||||
|
.route-toggle .button-icon {
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
@@ -980,6 +998,11 @@ function htmlPage(): string {
|
|||||||
right: 12px;
|
right: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top-right-controls {
|
||||||
|
top: 12px;
|
||||||
|
right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
max-height: min(52vh, 420px);
|
max-height: min(52vh, 420px);
|
||||||
--photo-thumb-size: 64px;
|
--photo-thumb-size: 64px;
|
||||||
@@ -1007,14 +1030,25 @@ function htmlPage(): string {
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body data-theme="light">
|
<body data-theme="light">
|
||||||
<button class="secondary theme-toggle" id="theme-toggle" type="button" aria-label="Switch to dark mode">
|
<div class="top-right-controls">
|
||||||
<span class="button-icon" id="theme-toggle-icon" aria-hidden="true">
|
<button class="secondary theme-toggle" id="theme-toggle" type="button" aria-label="Switch to dark mode">
|
||||||
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<span class="button-icon" id="theme-toggle-icon" aria-hidden="true">
|
||||||
<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"/>
|
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<circle cx="8" cy="8" r="3.2" stroke="currentColor" stroke-width="1.4"/>
|
<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"/>
|
||||||
</svg>
|
<circle cx="8" cy="8" r="3.2" stroke="currentColor" stroke-width="1.4"/>
|
||||||
</span>
|
</svg>
|
||||||
</button>
|
</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>
|
<main>
|
||||||
<section class="map-panel">
|
<section class="map-panel">
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
@@ -1182,11 +1216,13 @@ function htmlPage(): string {
|
|||||||
color: "#2d6cdf",
|
color: "#2d6cdf",
|
||||||
weight: 4,
|
weight: 4,
|
||||||
opacity: 0.85
|
opacity: 0.85
|
||||||
}).addTo(map);
|
});
|
||||||
const routeColors = {
|
const routeColors = {
|
||||||
light: "#2d6cdf",
|
light: "#2d6cdf",
|
||||||
dark: "#7dd3fc"
|
dark: "#7dd3fc"
|
||||||
};
|
};
|
||||||
|
const ROUTE_VISIBLE_STORAGE_KEY = "routeVisible";
|
||||||
|
let routeVisible = localStorage.getItem(ROUTE_VISIBLE_STORAGE_KEY) !== "false";
|
||||||
|
|
||||||
const overlay = mustGet("overlay");
|
const overlay = mustGet("overlay");
|
||||||
const overlayTitle = mustGet("overlay-title");
|
const overlayTitle = mustGet("overlay-title");
|
||||||
@@ -1194,6 +1230,8 @@ function htmlPage(): string {
|
|||||||
const overlayLoading = mustGet("overlay-loading");
|
const overlayLoading = mustGet("overlay-loading");
|
||||||
const overlayLoadingText = mustGet("overlay-loading-text");
|
const overlayLoadingText = mustGet("overlay-loading-text");
|
||||||
const closeOverlay = mustGet("close-overlay");
|
const closeOverlay = mustGet("close-overlay");
|
||||||
|
const routeToggle = mustGet("route-toggle");
|
||||||
|
const routeToggleIcon = mustGet("route-toggle-icon");
|
||||||
const photoList = mustGet("photo-list");
|
const photoList = mustGet("photo-list");
|
||||||
const emptyState = mustGet("empty-state");
|
const emptyState = mustGet("empty-state");
|
||||||
const photoCount = mustGet("photo-count");
|
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() {
|
function scheduleMapResize() {
|
||||||
window.clearTimeout(scheduleMapResize.timeoutId);
|
window.clearTimeout(scheduleMapResize.timeoutId);
|
||||||
scheduleMapResize.timeoutId = window.setTimeout(() => {
|
scheduleMapResize.timeoutId = window.setTimeout(() => {
|
||||||
@@ -1416,6 +1484,10 @@ function htmlPage(): string {
|
|||||||
themeToggle.addEventListener("click", () => {
|
themeToggle.addEventListener("click", () => {
|
||||||
setTheme(document.body.dataset.theme === "dark" ? "light" : "dark");
|
setTheme(document.body.dataset.theme === "dark" ? "light" : "dark");
|
||||||
});
|
});
|
||||||
|
setRouteVisible(routeVisible);
|
||||||
|
routeToggle.addEventListener("click", () => {
|
||||||
|
setRouteVisible(!routeVisible);
|
||||||
|
});
|
||||||
|
|
||||||
const storedSidebarCollapsed = localStorage.getItem("sidebarCollapsed") === "true";
|
const storedSidebarCollapsed = localStorage.getItem("sidebarCollapsed") === "true";
|
||||||
setSidebarCollapsed(storedSidebarCollapsed);
|
setSidebarCollapsed(storedSidebarCollapsed);
|
||||||
|
|||||||
Reference in New Issue
Block a user