diff --git a/assets/js/restore-theme.js b/assets/js/restore-theme.js index f4c53a9c..fb8c66ca 100644 --- a/assets/js/restore-theme.js +++ b/assets/js/restore-theme.js @@ -14,8 +14,4 @@ try { cl.remove("light"); cl.add("dark"); } - - // TODO: fix real-time switching (works but bulb icon isn't updated) - // window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => e.matches && setDark(true)); - // window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", (e) => e.matches && setDark(false)); } catch (error) {} diff --git a/assets/js/src/components/ThemeToggle.js b/assets/js/src/components/ThemeToggle.js index a7c5b3d5..050ba273 100644 --- a/assets/js/src/components/ThemeToggle.js +++ b/assets/js/src/components/ThemeToggle.js @@ -1,14 +1,26 @@ import { h } from "preact"; -import { useState, useEffect } from "preact/hooks"; -import { isDark, setDarkPref } from "../utils/theme.js"; +import { useState, useEffect, useCallback } from "preact/hooks"; +import { isDark, getDarkPref, setDarkPref } from "../utils/theme.js"; // react components: import BulbOn from "../assets/bulb-on.svg"; import BulbOff from "../assets/bulb-off.svg"; const ThemeToggle = () => { - // sync button up with theme state after initialization + // sync button up with theme and preference states after initialization const [dark, setDark] = useState(isDark()); + const [saved, setSaved] = useState(!!getDarkPref()); + + // real-time switching between modes if preference isn't set (and it's supported by OS/browser) + const callback = useCallback((e) => setDark(e.matches), []); + useEffect(() => { + if (saved) { + // TODO: FIX THIS... + window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", callback, true); + } else { + window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", callback, true); + } + }, [saved, callback]); useEffect(() => { // sets appropriate `` @@ -19,6 +31,7 @@ const ThemeToggle = () => { const handleToggle = () => { // only update the local storage preference if the user explicitly presses the lightbulb setDarkPref(!dark); + setSaved(true); // set theme to the opposite of current theme setDark(!dark);