Automic dark mode#346
Open
grische wants to merge 5 commits intofreifunk:mainfrom
Open
Conversation
Adds button.theme.{light,dark,auto} across en/de/fr/cz/ru/tr. Each
label names the current theme and, in parentheses, the theme the
next click will switch to ("Light (next: dark)"), giving both
sighted and screen-reader users the same state-plus-action signal
in a single short string. Polyglot is configured with
allowMissing: true, so all locales need the keys to avoid rendering
raw dotted strings to non-English users.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New standalone module lib/theme.ts owns theme state, storage, DOM class mutation, and matchMedia subscription. Exposes initTheme, getTheme, resolveTheme, cycleTheme, and themeIconSVG. Persists the user's choice in localStorage under meshviewer.theme (greenfield key — no prior storage usage in repo). All localStorage access is wrapped in try/catch so sandboxed iframes, Safari private mode, and file:// contexts fall back to in-memory state. On apply, toggles the existing theme_night class on <html> and dispatches a "themechange" CustomEvent on document.documentElement so other modules (the map's label canvas) can react without creating a direct dependency on this module. Auto mode subscribes to prefers-color-scheme changes so the UI flips live without a reload. Icons are inline SVG rather than font glyphs because the bundled meshviewer.woff2 is a 24-glyph subset of Ionicons and does not contain sun/moon/auto symbols. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the theme_* class manipulation from the baselayerchange handler. The theme is now a user preference owned by lib/theme.ts and no longer implicitly tied to tile-layer config. The label canvas renders colors derived from getComputedStyle on the body (lib/map/labellayer.js), so it still needs to refresh when the theme changes. LabelLayer subscribes to the themechange CustomEvent in its own onAdd / onRemove Leaflet lifecycle hooks, which ties the listener's lifetime to the layer and guarantees teardown when the layer is removed — map.ts keeps no theme-related code at all. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maurerle
reviewed
Apr 19, 2026
Adds a button that cycles light -> dark -> auto. The button icon
shows the current theme (sun / moon / half-circle) and the
aria-label carries the short "Light (next: dark)" string from the
locale file, so screen-reader users get the same state-plus-action
signal the icon conveys visually.
The same aria-label is the source for the button's hover tooltip
via the existing CSS rule (::after { content: attr(aria-label) }
on .content button), so no title attribute is set — that would
produce a duplicate native browser tooltip on top of the styled
one.
Calls initTheme() just before the button is rendered so the
matchMedia listener and storage state are active before any
click.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reads the stored theme preference synchronously in the document head and sets theme_night on <html> before any CSS resolves, so dark-mode users don't see a light-theme flash while Vite loads the main bundle. Read-only and wrapped in try/catch; the full theme module still owns writes and listeners. If localStorage access throws (sandboxed iframes, storage disabled, some file:// contexts), a nested try/catch still applies theme_night based on prefers-color-scheme alone, so OS-dark users also get the correct first paint without a late flip when lib/theme.ts boots. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
Member
|
I merged main into this to use the svg icons folder as well: Can you pleas update this PR to this? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This changes the current behaviour and decouples dark mode from the map layer.
The user can now select either dark, light or automatic by using the button on the top right.
The automatic theme switches depending on the system theme (without a reload).
Motivation and Context
As the map layer is not saved, it bothered my how my browser switched between dark and bright mode somewhat random.
This mode behaves similar to other apps (e.g. Github) and should be a lot more intuitive.
How Has This Been Tested?
Tested locally in Chrome with all variants of Themes.
Screenshots/links:
See it live here: https://map.ffmuc.net/
Checklist: