diff --git a/custom_for_logged_in.js b/custom_for_logged_in.js index ff6c283..e4bdbfb 100644 --- a/custom_for_logged_in.js +++ b/custom_for_logged_in.js @@ -1,6 +1,6 @@ -const darkModeDefault = false; +const darkModeDefault = 'auto'; -// CSS class used to set Dark Mode properties +// CSS class used to set Dark Mode properties const DARK_MODE_CSS = 'dark-mode'; // LocalStorage key used to store Dark Mode state @@ -12,12 +12,15 @@ const DARK_MODE_ICON = "icon-darkmode"; // could be `icon-${DARK_MODE_CSS}`; // CSS id used for Dark Mode button const DARK_MODE_BUTTON = "dark-mode-button"; // could be `button-${DARK_MODE_CSS}`; -const darkModeSymbol = ` - -`; // moon icon -const lightModeSymbol = ` - -`; // sun icon +const DARK_MODE_MODES = ["auto", "dark", "light"]; + +const systemModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); + +const modeSymbols = { + 'dark': ` `, // moon icon + 'light': ` `, // sun icon + 'auto': ` ` // sun / moon icon +} const darkModeToggleText = { 'en': 'Toggle Dark Mode', @@ -36,21 +39,53 @@ const darkModeToggleText = { const toggleButton = ``; -function isDarkModeSet() { - return localStorage.getItem(DARK_MODE_STORAGE) === 'true'; +function getDarkModeSetting() { + let mode = localStorage.getItem(DARK_MODE_STORAGE); + if (mode === null || DARK_MODE_MODES.indexOf(mode) == -1) { + // If the setting is missing or not one of the valid options initialize storage to the default + localStorage.setItem(DARK_MODE_STORAGE, darkModeDefault); + } + return localStorage.getItem(DARK_MODE_STORAGE); } function getDarkModeIcon() { return ``; } function toggleDarkMode() { - document.body.classList.toggle(DARK_MODE_CSS); - const setting = (!isDarkModeSet()).toString(); - localStorage.setItem(DARK_MODE_STORAGE, setting); + // Cycle through modes + const nextMode = DARK_MODE_MODES[(DARK_MODE_MODES.indexOf(getDarkModeSetting()) + 1) % DARK_MODE_MODES.length]; + localStorage.setItem(DARK_MODE_STORAGE, nextMode); + maybeModeChange(); + updateButton(nextMode); +} + +function switchToMode(targetMode) { + if (targetMode == 'dark') { + document.body.classList.add(DARK_MODE_CSS); + } else { + document.body.classList.remove(DARK_MODE_CSS); + } +} + +function maybeModeChange() { + const userMode = getDarkModeSetting(); + const systemMode = (systemModeMediaQuery.matches ? 'dark' : 'light'); + + if (userMode === "auto") { + switchToMode(systemMode); + } else { + switchToMode(userMode); + } +} + +function updateButton(mode) { + const darkModeButton = $(`#${DARK_MODE_BUTTON}`); + darkModeButton.html(getDarkModeIcon()); + darkModeButton.attr('data-title', `${darkModeToggleText}, current: ${mode}`); } function addDarkModeToggle() { @@ -71,24 +106,18 @@ function addDarkModeToggle() { } darkModeButton = $(toggleButton).prependTo(sidebarToolbar); - darkModeButton.html(getDarkModeIcon()); + updateButton(getDarkModeSetting()); darkModeButton.on('click', function() { toggleDarkMode(); - darkModeButton.html(getDarkModeIcon()); $(this).blur(); }); -} -if (darkModeDefault) { - if (localStorage.getItem(DARK_MODE_STORAGE) === null) { - localStorage.setItem(DARK_MODE_STORAGE, 'true'); - } + // Switch mode on system theme changes + systemModeMediaQuery.addEventListener("change", maybeModeChange); + + // Trigger initial mode change if necessary + maybeModeChange(); } $(addDarkModeToggle); - -// Apply dark mode immediately if it's been set previously -if(localStorage.getItem(DARK_MODE_STORAGE) === 'true') { - document.body.classList.add(DARK_MODE_CSS); -} \ No newline at end of file