From d7104386d95da47e6da81c8599710c420aa7293c Mon Sep 17 00:00:00 2001 From: Arne Baeumler Date: Sun, 7 Jun 2026 20:18:54 +0200 Subject: [PATCH] feat: add dark mode toggle --- src/server/request-handler.ts | 206 ++++++++++++++++++++++++++++------ 1 file changed, 169 insertions(+), 37 deletions(-) diff --git a/src/server/request-handler.ts b/src/server/request-handler.ts index dc6f262..71b1d4c 100644 --- a/src/server/request-handler.ts +++ b/src/server/request-handler.ts @@ -62,18 +62,91 @@ function htmlPage(): string { /> - +

mapy-mg

Load photos, read EXIF locally in the browser, and show them on OpenStreetMap.

-
Client-side import · no image storage on the server
+
+
Client-side import · no image storage on the server
+ +
@@ -828,6 +928,9 @@ function htmlPage(): string { const timelineAxis = mustGet("timeline-axis"); const timelineRange = mustGet("timeline-range"); const timelineUnit = mustGet("timeline-unit"); + const themeToggle = mustGet("theme-toggle"); + const themeToggleIcon = mustGet("theme-toggle-icon"); + const themeToggleLabel = mustGet("theme-toggle-label"); const shareUrl = mustGet("share-url"); const shareStatus = mustGet("share-status"); const loadShare = mustGet("load-share"); @@ -841,6 +944,35 @@ function htmlPage(): string { return element; } + function setTheme(theme) { + const resolvedTheme = theme === "light" ? "light" : "dark"; + document.body.dataset.theme = resolvedTheme; + localStorage.setItem("theme", resolvedTheme); + + if (resolvedTheme === "dark") { + themeToggleLabel.textContent = "Light mode"; + themeToggle.setAttribute("aria-label", "Switch to light mode"); + themeToggleIcon.innerHTML = + '' + + '' + + ""; + } else { + themeToggleLabel.textContent = "Dark mode"; + themeToggle.setAttribute("aria-label", "Switch to dark mode"); + themeToggleIcon.innerHTML = + '' + + '' + + '' + + ""; + } + } + + const storedTheme = localStorage.getItem("theme"); + setTheme(storedTheme === "light" ? "light" : "dark"); + themeToggle.addEventListener("click", () => { + setTheme(document.body.dataset.theme === "dark" ? "light" : "dark"); + }); + function formatDate(value) { if (!value) { return "no timestamp";