feat(webui): add initial webui with websocket chat flow

This commit is contained in:
Xubin Ren
2026-04-18 18:51:53 +00:00
parent 6bfb75ed03
commit 9ed3031a42
76 changed files with 7088 additions and 38 deletions
+48
View File
@@ -0,0 +1,48 @@
import { useCallback, useEffect, useState } from "react";
type Theme = "light" | "dark";
const STORAGE_KEY = "nanobot-webui.theme";
function readStored(): Theme | null {
try {
const v = localStorage.getItem(STORAGE_KEY);
return v === "light" || v === "dark" ? v : null;
} catch {
return null;
}
}
function applyTheme(theme: Theme): void {
const root = document.documentElement;
if (theme === "dark") root.classList.add("dark");
else root.classList.remove("dark");
}
export function useTheme(): { theme: Theme; toggle: () => void; setTheme: (t: Theme) => void } {
const [theme, setThemeState] = useState<Theme>(() => {
const stored = readStored();
if (stored) return stored;
if (typeof window !== "undefined" && window.matchMedia) {
return window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
}
return "light";
});
useEffect(() => {
applyTheme(theme);
try {
localStorage.setItem(STORAGE_KEY, theme);
} catch {
// ignore
}
}, [theme]);
const setTheme = useCallback((t: Theme) => setThemeState(t), []);
const toggle = useCallback(
() => setThemeState((t) => (t === "dark" ? "light" : "dark")),
[],
);
return { theme, toggle, setTheme };
}