diff --git a/src/palettes/changeTheme/index.js b/src/palettes/changeTheme/index.js index b76e88f1d..5d6417053 100644 --- a/src/palettes/changeTheme/index.js +++ b/src/palettes/changeTheme/index.js @@ -2,9 +2,7 @@ import "./style.scss"; import palette from "components/palette"; import config from "lib/config"; import appSettings from "lib/settings"; -import { isDeviceDarkTheme } from "lib/systemConfiguration"; -import themes from "theme/list"; -import { updateSystemTheme } from "theme/preInstalled"; +import themes, { updateSystemThemeWatcher } from "theme/list"; import changeEditorTheme from "../changeEditorTheme"; export default function changeTheme(type = "editor") { @@ -41,44 +39,6 @@ function generateHints(type) { }); } -let previousDark = isDeviceDarkTheme(); -const updateTimeMs = 2000; - -let intervalId = null; - -function syncSystemTheme() { - if (appSettings.value.appTheme.toLowerCase() === "system") { - const isDark = isDeviceDarkTheme(); - if (isDark !== previousDark) { - previousDark = isDark; - updateSystemTheme(isDark); - } - } -} - -function startSystemThemeWatcher() { - if (intervalId) return; - intervalId = setInterval(syncSystemTheme, updateTimeMs); -} - -function stopSystemThemeWatcher() { - if (!intervalId) return; - clearInterval(intervalId); - intervalId = null; -} - -function updateSystemThemeWatcher(theme) { - if (String(theme).toLowerCase() === "system") { - startSystemThemeWatcher(); - syncSystemTheme(); - return; - } - stopSystemThemeWatcher(); -} - -updateSystemThemeWatcher(appSettings.value.appTheme); -appSettings.on("update:appTheme", updateSystemThemeWatcher); - function onselect(value) { if (!value) return; diff --git a/src/theme/list.js b/src/theme/list.js index 5d52cfccd..fca3f9c2c 100644 --- a/src/theme/list.js +++ b/src/theme/list.js @@ -11,8 +11,13 @@ const appThemes = new Map(); let themeApplied = false; let firstTime = true; +const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); +let systemThemeWatcherActive = false; + function init() { themes.forEach((theme) => add(theme)); + updateSystemThemeWatcher(settings.value.appTheme); + settings.on("update:appTheme", updateSystemThemeWatcher); } /** @@ -159,6 +164,45 @@ export function update(theme) { }); } +function syncSystemTheme(event) { + if (settings.value.appTheme.toLowerCase() !== "system") return; + const isDark = event ? event.matches : darkModeMediaQuery.matches; + updateSystemTheme(isDark); +} + +function startSystemThemeWatcher() { + if (systemThemeWatcherActive) return; + systemThemeWatcherActive = true; + if (typeof darkModeMediaQuery.addEventListener === "function") { + darkModeMediaQuery.addEventListener("change", syncSystemTheme); + } else { + darkModeMediaQuery.addListener(syncSystemTheme); + } +} + +function stopSystemThemeWatcher() { + if (!systemThemeWatcherActive) return; + systemThemeWatcherActive = false; + if (typeof darkModeMediaQuery.removeEventListener === "function") { + darkModeMediaQuery.removeEventListener("change", syncSystemTheme); + } else { + darkModeMediaQuery.removeListener(syncSystemTheme); + } +} + +/** + * Start or stop syncing the app theme with the OS color scheme + * @param {string} theme + */ +export function updateSystemThemeWatcher(theme) { + if (String(theme).toLowerCase() === "system") { + startSystemThemeWatcher(); + syncSystemTheme(); + return; + } + stopSystemThemeWatcher(); +} + export default { get applied() { return themeApplied; @@ -169,4 +213,5 @@ export default { add, apply, update, + updateSystemThemeWatcher, }; diff --git a/src/theme/preInstalled.js b/src/theme/preInstalled.js index 6e3165744..8eb266e96 100644 --- a/src/theme/preInstalled.js +++ b/src/theme/preInstalled.js @@ -280,6 +280,7 @@ export function updateSystemTheme(darkTheme) { if (appSettings?.value?.appTheme === "system") { apply(system.id); + appSettings.update({ editorTheme: system.preferredEditorTheme }, false); } }