diff options
author | 2024-01-05 13:57:44 +0800 | |
---|---|---|
committer | 2024-01-05 13:57:44 +0800 | |
commit | eaaf1efff1f5d9b47658541496fb948a3292fe48 (patch) | |
tree | 6ab10c932308513bc5c0445e7f78cf736f39f9ff /pydis_site/static/js/base/navbar.js | |
parent | Dark: Refactor toggle handling JS (diff) |
Dark: Support system color scheme preference
Added features
- When no preference already stored when page loads, we'll take into
account the system setting and set the theme automatically.
- When the system setting is modified while the site is active, switch
theme automatically.
- The system preference takes lower precedence than saved preference
from the switch toggle, unless the setting is modified while the site
is active.
Miscellaneous refactor.
Diffstat (limited to 'pydis_site/static/js/base/navbar.js')
-rw-r--r-- | pydis_site/static/js/base/navbar.js | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/pydis_site/static/js/base/navbar.js b/pydis_site/static/js/base/navbar.js index 9a1641aa..04850add 100644 --- a/pydis_site/static/js/base/navbar.js +++ b/pydis_site/static/js/base/navbar.js @@ -1,32 +1,42 @@ "use strict"; const defaultTheme = "light"; -const lightCssElement = document.getElementById("bulma-css"); -const darkCssElement = document.getElementById("bulma-css-dark"); +const lightStylesheet = document.getElementById("bulma-css"); +const darkStylesheet = document.getElementById("bulma-css-dark"); -function getCurrentTheme() { +// Get saved preference for the site in local storage, optionally accounting +// for system preference used when a page loads. +function getCurrentTheme(systemPrefers) { const theme = localStorage.getItem("theme"); - if (theme === null || theme === "") - return defaultTheme; - return theme; + + if (theme !== null && theme !== "") + return theme; + + if (systemPrefers !== undefined) + return systemPrefers; + + return defaultTheme; } +// Disable & enable the correct CSS stylesheets based on chosen theme. function setStyleSheets(newTheme) { switch (newTheme) { case "light": - lightCssElement.disabled = false; - darkCssElement.disabled = true; + lightStylesheet.disabled = false; + darkStylesheet.disabled = true; break; case "dark": - lightCssElement.disabled = true; - darkCssElement.disabled = false; + lightStylesheet.disabled = true; + darkStylesheet.disabled = false; break; } } +// Reflect chosen theme on the switch toggle. function toggleThemeSwitch(newTheme) { const switchToggle = document.getElementById("theme-switch"); const knob = document.getElementById("theme-knob"); + switch (newTheme) { case "light": knob.classList.remove("dark"); @@ -49,14 +59,29 @@ function toggleThemeSwitch(newTheme) { // Executed when the page has finished loading. document.addEventListener("DOMContentLoaded", () => { - const theme = getCurrentTheme() + let theme; + const systemPrefersDark = window.matchMedia("(prefers-color-scheme: dark)"); + + if (systemPrefersDark.matches) + theme = getCurrentTheme("dark"); + else + theme = getCurrentTheme(); + setStyleSheets(theme); toggleThemeSwitch(theme); + systemPrefersDark.addEventListener("change", ({matches: isDark}) => { + const newTheme = isDark ? "dark" : "light"; + // Let the new system preference take precedence over toggle preference + // on page reloads. + localStorage.removeItem("theme"); + setStyleSheets(newTheme); + toggleThemeSwitch(newTheme); + }) + const switchToggle = document.getElementById("theme-switch"); switchToggle.addEventListener("click", () => { const newTheme = getCurrentTheme() === "light" ? "dark" : "light"; - console.log(newTheme); localStorage.setItem("theme", newTheme); setStyleSheets(newTheme); toggleThemeSwitch(newTheme); |