mirror of
https://github.com/HumanAIGC-Engineering/gradio-webrtc.git
synced 2026-02-05 18:09:23 +08:00
sync code of fastrtc, add text support through datachannel, fix safari connect problem support chat without camera or mic
102 lines
2.4 KiB
TypeScript
102 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, useContext, useEffect, useState } from "react";
|
|
|
|
type Theme = "light" | "dark" | "system";
|
|
|
|
type ThemeProviderProps = {
|
|
children: React.ReactNode;
|
|
defaultTheme?: Theme;
|
|
storageKey?: string;
|
|
attribute?: string;
|
|
enableSystem?: boolean;
|
|
disableTransitionOnChange?: boolean;
|
|
};
|
|
|
|
type ThemeProviderState = {
|
|
theme: Theme;
|
|
setTheme: (theme: Theme) => void;
|
|
};
|
|
|
|
const initialState: ThemeProviderState = {
|
|
theme: "system",
|
|
setTheme: () => null,
|
|
};
|
|
|
|
const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
|
|
|
|
export function ThemeProvider({
|
|
children,
|
|
defaultTheme = "system",
|
|
storageKey = "theme",
|
|
attribute = "class",
|
|
enableSystem = true,
|
|
disableTransitionOnChange = false,
|
|
...props
|
|
}: ThemeProviderProps) {
|
|
const [theme, setTheme] = useState<Theme>(defaultTheme);
|
|
|
|
useEffect(() => {
|
|
const savedTheme = localStorage.getItem(storageKey) as Theme | null;
|
|
|
|
if (savedTheme) {
|
|
setTheme(savedTheme);
|
|
} else if (defaultTheme === "system" && enableSystem) {
|
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
? "dark"
|
|
: "light";
|
|
setTheme(systemTheme);
|
|
}
|
|
}, [defaultTheme, storageKey, enableSystem]);
|
|
|
|
useEffect(() => {
|
|
const root = window.document.documentElement;
|
|
|
|
if (disableTransitionOnChange) {
|
|
root.classList.add("no-transitions");
|
|
|
|
// Force a reflow
|
|
window.getComputedStyle(root).getPropertyValue("opacity");
|
|
|
|
setTimeout(() => {
|
|
root.classList.remove("no-transitions");
|
|
}, 0);
|
|
}
|
|
|
|
root.classList.remove("light", "dark");
|
|
|
|
if (theme === "system" && enableSystem) {
|
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
? "dark"
|
|
: "light";
|
|
root.classList.add(systemTheme);
|
|
} else {
|
|
root.classList.add(theme);
|
|
}
|
|
|
|
localStorage.setItem(storageKey, theme);
|
|
}, [theme, storageKey, enableSystem, disableTransitionOnChange]);
|
|
|
|
const value = {
|
|
theme,
|
|
setTheme: (theme: Theme) => {
|
|
setTheme(theme);
|
|
},
|
|
};
|
|
|
|
return (
|
|
<ThemeProviderContext.Provider {...props} value={value}>
|
|
{children}
|
|
</ThemeProviderContext.Provider>
|
|
);
|
|
}
|
|
|
|
export const useTheme = () => {
|
|
const context = useContext(ThemeProviderContext);
|
|
|
|
if (context === undefined)
|
|
throw new Error("useTheme must be used within a ThemeProvider");
|
|
|
|
return context;
|
|
};
|