- Fix hydration mismatches and initialization errors - Add /v1/models endpoint for OpenAI clients - Add Codex response translator (Responses → OpenAI) - Fix circular dependencies and PropTypes - Add Material Symbols font and CSS fixes - Update README with deployment guide Co-merged from PR #18 (14/15 commits, skipped debug)
61 lines
1.7 KiB
JavaScript
61 lines
1.7 KiB
JavaScript
"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,
|
|
};
|
|
}
|
|
|