2022-05-04 19:10:19 +10:00
|
|
|
import { useEffect } from "react";
|
|
|
|
|
import { useAtom } from "jotai";
|
|
|
|
|
import { Helmet } from "react-helmet-async";
|
2022-07-18 14:01:29 +10:00
|
|
|
import { Outlet } from "react-router-dom";
|
2022-05-04 19:10:19 +10:00
|
|
|
|
|
|
|
|
import { useMediaQuery, ThemeProvider, CssBaseline } from "@mui/material";
|
|
|
|
|
import Favicon from "@src/assets/Favicon";
|
|
|
|
|
|
|
|
|
|
import {
|
2022-07-18 14:40:46 +10:00
|
|
|
projectScope,
|
2022-05-04 19:10:19 +10:00
|
|
|
themeAtom,
|
|
|
|
|
themeOverriddenAtom,
|
|
|
|
|
customizedThemesAtom,
|
2022-07-18 14:40:46 +10:00
|
|
|
} from "@src/atoms/projectScope";
|
2022-05-04 19:10:19 +10:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Injects the MUI theme with customizations from project and user settings.
|
|
|
|
|
* Also adds dark mode support.
|
|
|
|
|
*/
|
|
|
|
|
export default function RowyThemeProvider({
|
|
|
|
|
children,
|
|
|
|
|
}: React.PropsWithChildren<{}>) {
|
2022-07-18 14:40:46 +10:00
|
|
|
const [theme, setTheme] = useAtom(themeAtom, projectScope);
|
|
|
|
|
const [themeOverridden] = useAtom(themeOverriddenAtom, projectScope);
|
|
|
|
|
const [customizedThemes] = useAtom(customizedThemesAtom, projectScope);
|
2022-05-04 19:10:19 +10:00
|
|
|
|
|
|
|
|
// Infer theme based on system settings
|
|
|
|
|
const prefersDarkTheme = useMediaQuery("(prefers-color-scheme: dark)", {
|
|
|
|
|
noSsr: true,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Update theme when system settings change
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (themeOverridden) return;
|
|
|
|
|
setTheme(prefersDarkTheme ? "dark" : "light");
|
|
|
|
|
}, [prefersDarkTheme, themeOverridden, setTheme]);
|
|
|
|
|
|
|
|
|
|
// Sync theme to body data-theme attribute for Feedback Fin
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
document.body.setAttribute("data-theme", theme);
|
|
|
|
|
}, [theme]);
|
|
|
|
|
|
|
|
|
|
const fontCssUrls = customizedThemes[theme].typography.fontCssUrls;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{Array.isArray(fontCssUrls) && (
|
|
|
|
|
<Helmet>
|
|
|
|
|
{fontCssUrls!.map((url) => (
|
|
|
|
|
<link key={url} rel="stylesheet" href={url} />
|
|
|
|
|
))}
|
|
|
|
|
</Helmet>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
<ThemeProvider theme={customizedThemes[theme]}>
|
|
|
|
|
<Favicon />
|
|
|
|
|
<CssBaseline />
|
|
|
|
|
{children}
|
2022-07-18 14:01:29 +10:00
|
|
|
<Outlet />
|
2022-05-04 19:10:19 +10:00
|
|
|
</ThemeProvider>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}
|