diff options
Diffstat (limited to 'pydis_site/static/js')
| -rw-r--r-- | pydis_site/static/js/base/themes.js | 94 | 
1 files changed, 94 insertions, 0 deletions
diff --git a/pydis_site/static/js/base/themes.js b/pydis_site/static/js/base/themes.js new file mode 100644 index 00000000..46dba7b9 --- /dev/null +++ b/pydis_site/static/js/base/themes.js @@ -0,0 +1,94 @@ +"use strict"; + +const defaultTheme = "light"; +const stylesheet = document.getElementById("bulma-css"); +const htmlTag = document.querySelector("html"); + +// We include the dark stylesheet in base template to include the rel="preload", +// but remove the actual rel="stylesheet" element here because we won't need it. +document.getElementById("bulma-css-dark").remove(); + +// 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 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": +            stylesheet.href = "/static/css/bulma.css"; +            break; +        case "dark": +            stylesheet.href = "/static/css/dark_bulma.css"; +            break; +    } + +    htmlTag.setAttribute("data-theme", newTheme); +} + +// 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"); +            knob.classList.add("light"); +            setTimeout(function() { +                switchToggle.classList.remove("dark"); +                switchToggle.classList.add("light"); +            }, 100); +            break; +        case "dark": +            knob.classList.remove("light"); +            knob.classList.add("dark"); +            setTimeout(function() { +                switchToggle.classList.remove("light"); +                switchToggle.classList.add("dark"); +            }, 100); +            break; +    } +} + +let theme; +const systemPrefersDark = window.matchMedia("(prefers-color-scheme: dark)"); + +if (systemPrefersDark.matches) +    theme = getCurrentTheme("dark"); +else +    theme = getCurrentTheme(); + +setStyleSheets(theme); + +// Executed when the page has finished loading. +document.addEventListener("DOMContentLoaded", () => { +    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 = htmlTag.getAttribute("data-theme") === "light" ? "dark" : "light"; +        localStorage.setItem("theme", newTheme); +        setStyleSheets(newTheme); +        toggleThemeSwitch(newTheme); +    }); +});  |