9router / src /shared /hooks /useTheme.js
2api
feat: configurable stream stall timeout + per-provider UI
88c4c60
Raw
History Blame Contribute Delete
1.71 kB
"use client";
import { useEffect, useState, useSyncExternalStore } from "react";
import useThemeStore from "@/store/themeStore";
// Subscribe to system theme changes
function subscribeToSystemTheme(callback) {
if (typeof window === "undefined") return () => {};
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
mediaQuery.addEventListener("change", callback);
return () => mediaQuery.removeEventListener("change", callback);
}
// Get current system theme preference
function getSystemThemeSnapshot() {
if (typeof window === "undefined") return false;
return window.matchMedia("(prefers-color-scheme: dark)").matches;
}
// Server snapshot always returns false
function getServerSnapshot() {
return false;
}
export function useTheme() {
const { theme, setTheme, toggleTheme, initTheme } = useThemeStore();
// Use useSyncExternalStore to safely subscribe to system theme
const systemPrefersDark = useSyncExternalStore(
subscribeToSystemTheme,
getSystemThemeSnapshot,
getServerSnapshot
);
useEffect(() => {
initTheme();
}, [initTheme]);
// Listen for system theme changes when theme is "system"
useEffect(() => {
if (theme !== "system") return;
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const handleChange = () => initTheme();
mediaQuery.addEventListener("change", handleChange);
return () => mediaQuery.removeEventListener("change", handleChange);
}, [theme, initTheme]);
// Compute isDark from current state (no effect needed)
const isDark = theme === "dark" || (theme === "system" && systemPrefersDark);
return {
theme,
setTheme,
toggleTheme,
isDark,
};
}