diff options
| author | 2024-01-05 13:57:44 +0800 | |
|---|---|---|
| committer | 2024-01-05 13:57:44 +0800 | |
| commit | eaaf1efff1f5d9b47658541496fb948a3292fe48 (patch) | |
| tree | 6ab10c932308513bc5c0445e7f78cf736f39f9ff | |
| 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 '')
| -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);  |