Skip to content
Snippets Groups Projects
Commit 9f97c0e7 authored by Simon Künzel's avatar Simon Künzel
Browse files

Add ThemeProvider

parent fac49a9b
No related branches found
No related tags found
No related merge requests found
......@@ -6,6 +6,7 @@ import { AuthStatusProvider } from "@/videoag/authentication/AuthStatus";
import { showErrorToast } from "@/videoag/error/ErrorDisplay";
import { LanguageProvider } from "@/videoag/localization/LanguageProvider";
import { ReloadBoundary } from "@/videoag/miscellaneous/ReloadBoundary";
import { ThemeProvider } from "@/videoag/miscellaneous/Theme";
import Title from "@/videoag/miscellaneous/TitleComponent";
import { RealBackendProvider } from "@/videoag/api/ApiProvider";
import { EditModeProvider } from "@/videoag/object_management/EditModeProvider";
......@@ -40,10 +41,12 @@ export default function App({ Component, pageProps }: AppProps) {
<AuthStatusProvider>
<EditModeProvider>
<LanguageProvider>
<ThemeProvider>
<ToastContainer />
<DefaultLayout>
<Component {...pageProps} />
</DefaultLayout>
</ThemeProvider>
</LanguageProvider>
</EditModeProvider>
</AuthStatusProvider>
......
import type React from "react";
import { createContext, useContext, useEffect } from "react";
import { useLocalStorageState } from "@/videoag/miscellaneous/Storage";
type ThemeContextType = {
theme: string;
setTheme: (newValue: string | ((oldValue: string) => string)) => void;
};
const ThemeContext = createContext<ThemeContextType>({
theme: "dark",
setTheme: () => {},
});
export function ThemeProvider({ children }: { children: React.ReactNode }) {
const [theme, setTheme] = useLocalStorageState<string>("theme", "dark");
useEffect(() => {
try {
let currentTheme = document.documentElement.getAttribute("data-bs-theme");
if (theme !== currentTheme) {
document.documentElement.classList.add("no-transition");
document.documentElement.setAttribute("data-bs-theme", theme);
document.documentElement.classList.remove("no-transition");
}
} catch (e) {
console.error("Could not update theme on document", e);
}
}, [theme]);
return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>;
}
export function useTheme() {
return useContext(ThemeContext);
}
......@@ -13,9 +13,9 @@ import UserField from "@/videoag/authentication/UserField";
import { showErrorToast, ErrorComponent } from "@/videoag/error/ErrorDisplay";
import { FallbackErrorBoundary } from "@/videoag/error/FallbackErrorBoundary";
import { useLanguage } from "@/videoag/localization/LanguageProvider";
import { storageGetOrDefault, storageSet } from "@/videoag/miscellaneous/Storage";
import { ReloadBoundary } from "@/videoag/miscellaneous/ReloadBoundary";
import { StylizedText } from "@/videoag/miscellaneous/StylizedText";
import { useTheme } from "@/videoag/miscellaneous/Theme";
import { useEditMode } from "@/videoag/object_management/EditModeProvider";
import AnnouncementComponent from "@/videoag/site/AnnouncementComponent";
import { basePath } from "@/../basepath";
......@@ -108,38 +108,9 @@ export function Search({
function NavBar({ status }: { status?: GetStatusResponse }) {
const [navbarOpen, setNavbarOpen] = useState(false);
const { setTheme } = useTheme();
const { language, setLanguageCode } = useLanguage();
useEffect(() => {
try {
let currentTheme = document.documentElement.getAttribute("data-bs-theme");
if (storageGetOrDefault("theme", currentTheme) !== currentTheme) {
document.documentElement.classList.add("no-transition");
document.documentElement.setAttribute(
"data-bs-theme",
storageGetOrDefault("theme", currentTheme),
);
document.documentElement.classList.remove("no-transition");
}
} catch (e) {
console.error("Could not load theme from local storage", e);
}
}, []);
const switchTheme = () => {
const theme = document.documentElement.getAttribute("data-bs-theme");
if (theme === "dark") {
document.documentElement.setAttribute("data-bs-theme", "light");
} else {
document.documentElement.setAttribute("data-bs-theme", "dark");
}
try {
storageSet("theme", theme === "dark" ? "light" : "dark");
} catch (e) {
console.error("Could not save theme to local storage", e);
}
};
const switchLanguage = () => {
setLanguageCode(language.getCode() === "de" ? "en" : "de");
};
......@@ -267,7 +238,15 @@ function NavBar({ status }: { status?: GetStatusResponse }) {
<UserField isUnavailable={status?.status === "unavailable"} />
<div>
<button className={"btn"} type="button" onClick={switchTheme}>
<button
className={"btn"}
type="button"
onClick={() =>
setTheme((oldValue) =>
oldValue === "dark" ? "light" : "dark",
)
}
>
<span aria-hidden="true" className={"bi bi-moon-stars"} />
</button>
</div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment