2024-11-17 17:17:40 +08:00
|
|
|
import {
|
|
|
|
Links,
|
|
|
|
Meta,
|
|
|
|
Outlet,
|
2024-11-27 19:52:49 +08:00
|
|
|
Scripts,
|
2024-11-17 17:17:40 +08:00
|
|
|
ScrollRestoration,
|
|
|
|
} from "@remix-run/react";
|
2024-12-03 01:37:02 +08:00
|
|
|
import { NotificationProvider } from "hooks/notification";
|
|
|
|
import { Theme } from '@radix-ui/themes';
|
|
|
|
import { useEffect, useState } from "react";
|
2024-11-17 17:17:40 +08:00
|
|
|
|
2024-11-27 19:52:49 +08:00
|
|
|
import "~/index.css";
|
2024-11-17 17:17:40 +08:00
|
|
|
|
2024-12-03 01:37:02 +08:00
|
|
|
export function Layout() {
|
|
|
|
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
// 初始化主题
|
|
|
|
const isDark = document.documentElement.classList.contains('dark');
|
|
|
|
setTheme(isDark ? 'dark' : 'light');
|
|
|
|
|
|
|
|
// 监听主题变化
|
|
|
|
const handleThemeChange = (event: CustomEvent<{ theme: 'light' | 'dark' }>) => {
|
|
|
|
setTheme(event.detail.theme);
|
|
|
|
};
|
|
|
|
|
|
|
|
window.addEventListener('theme-change', handleThemeChange as EventListener);
|
|
|
|
return () => window.removeEventListener('theme-change', handleThemeChange as EventListener);
|
|
|
|
}, []);
|
|
|
|
|
2024-11-17 17:17:40 +08:00
|
|
|
return (
|
2024-12-03 01:37:02 +08:00
|
|
|
<html
|
|
|
|
lang="en"
|
|
|
|
className="h-full"
|
|
|
|
suppressHydrationWarning={true}
|
|
|
|
>
|
2024-11-17 17:17:40 +08:00
|
|
|
<head>
|
|
|
|
<meta charSet="utf-8" />
|
2024-11-30 22:24:35 +08:00
|
|
|
<meta
|
|
|
|
name="viewport"
|
|
|
|
content="width=device-width, initial-scale=1"
|
|
|
|
/>
|
|
|
|
<meta
|
|
|
|
name="generator"
|
|
|
|
content="echoes"
|
|
|
|
/>
|
2024-11-17 17:17:40 +08:00
|
|
|
<Meta />
|
|
|
|
<Links />
|
2024-11-30 22:24:35 +08:00
|
|
|
<script
|
|
|
|
dangerouslySetInnerHTML={{
|
|
|
|
__html: `
|
2024-12-03 01:37:02 +08:00
|
|
|
(function() {
|
|
|
|
document.documentElement.classList.remove('dark');
|
|
|
|
const savedTheme = localStorage.getItem('theme-preference');
|
|
|
|
if (savedTheme) {
|
|
|
|
document.documentElement.classList.toggle('dark', savedTheme === 'dark');
|
|
|
|
} else {
|
|
|
|
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
document.documentElement.classList.toggle('dark', darkModeMediaQuery.matches);
|
|
|
|
}
|
|
|
|
})()
|
|
|
|
`,
|
2024-11-30 22:24:35 +08:00
|
|
|
}}
|
|
|
|
/>
|
2024-12-03 01:37:02 +08:00
|
|
|
</head>
|
|
|
|
<body
|
|
|
|
className="h-full"
|
|
|
|
suppressHydrationWarning={true}
|
|
|
|
>
|
|
|
|
<Theme
|
|
|
|
appearance={theme}
|
|
|
|
accentColor="blue"
|
|
|
|
grayColor="slate"
|
|
|
|
radius="medium"
|
|
|
|
scaling="100%"
|
|
|
|
>
|
|
|
|
<NotificationProvider>
|
|
|
|
<Outlet />
|
|
|
|
</NotificationProvider>
|
|
|
|
</Theme>
|
|
|
|
<ScrollRestoration />
|
2024-11-30 22:24:35 +08:00
|
|
|
<Scripts />
|
2024-11-17 17:17:40 +08:00
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
);
|
|
|
|
}
|
2024-12-03 01:37:02 +08:00
|
|
|
|
2024-11-17 17:17:40 +08:00
|
|
|
export default function App() {
|
2024-12-03 01:37:02 +08:00
|
|
|
return <Layout />;
|
2024-11-17 17:17:40 +08:00
|
|
|
}
|