Files
deerflow-code/frontend-web/src/App.tsx
T

130 lines
4.7 KiB
TypeScript

import { useMemo } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { ThemeProvider as NextThemesProvider } from "next-themes";
import { FontScaleApplier } from "@/components/font-scale";
import { QueryClientProvider } from "@/components/query-client-provider";
import { AuthSyncWatcher } from "@/core/auth/sync";
import { I18nProvider } from "@/core/i18n/context";
import { detectLocale } from "@/core/i18n/locale";
import { resolveForcedThemeForPath } from "@/core/page-layout/chats-iframe-route";
import { ChatProvider } from "@/contexts/ChatContext";
import { ThemeProvider } from "@/contexts/ThemeContext";
import {
resolveEmbedRoundtableTheme,
resolveEmbedTheme,
} from "@/core/embed/params";
import { usePublicEmbedTheme } from "@/core/embed/background";
import { readWujieProps } from "@/core/embed/wujie";
import { HashRouter, useLocation } from "react-router-dom";
import LandingPage from "./pages/LandingPage";
import LoginPage from "./pages/LoginPage";
import PageRoutes from "./pages/PageRoutes";
import PublicScheduledTaskPage, {
PublicScheduledTaskFullscreenPage,
} from "./pages/PublicScheduledTaskPage";
import PublicSharePage from "./pages/PublicSharePage";
import PublicLeaderboardPage from "./pages/PublicLeaderboardPage";
import PublicRoundtableSharePage from "./pages/PublicRoundtableSharePage";
import EmbedChatPage from "./pages/EmbedChatPage";
import EmbedRoundtablePage from "./pages/EmbedRoundtablePage";
import { ChatRuntime } from "./pages/WorkspaceRoutes";
import { NotFoundPage } from "./pages/NotFoundPage";
const PUBLIC_EMBED_PREFIXES = ["/share/", "/public/", "/roundtable-share/"];
function AppProviders({ children }: { children: React.ReactNode }) {
const locale = useMemo(() => detectLocale(), []);
const location = useLocation();
const publicEmbedTheme = usePublicEmbedTheme();
const forcedTheme = useMemo(() => {
const routeTheme = resolveForcedThemeForPath(location.pathname);
if (routeTheme) return routeTheme;
if (location.pathname === "/embed/roundtable") {
const wp = readWujieProps();
const raw =
(typeof wp.theme === "string" && wp.theme.trim()) ||
new URLSearchParams(location.search).get("theme")?.trim() ||
"dark";
return resolveEmbedRoundtableTheme(raw);
}
if (location.pathname.startsWith("/embed/chats")) {
const raw = new URLSearchParams(location.search).get("theme")?.trim();
return raw ? resolveEmbedTheme(raw) : undefined;
}
if (PUBLIC_EMBED_PREFIXES.some((p) => location.pathname.startsWith(p))) {
return publicEmbedTheme;
}
return undefined;
}, [location.pathname, location.search, publicEmbedTheme]);
return (
<NextThemesProvider
attribute="class"
storageKey="strategy-theme"
defaultTheme="light"
enableSystem={false}
disableTransitionOnChange
forcedTheme={forcedTheme}
>
<QueryClientProvider>
<I18nProvider initialLocale={locale}>
<ThemeProvider>
<ChatProvider>
<AuthSyncWatcher />
<FontScaleApplier />
{children}
</ChatProvider>
</ThemeProvider>
</I18nProvider>
</QueryClientProvider>
</NextThemesProvider>
);
}
export function App() {
return (
<HashRouter>
<AppProviders>
<Routes>
<Route path="/" element={<Navigate to="/login" replace />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/login/:username" element={<LoginPage />} />
<Route path="/landing" element={<LandingPage />} />
<Route path="/share/:shareCode" element={<PublicSharePage />} />
<Route path="/public/leaderboard" element={<PublicLeaderboardPage />} />
<Route
path="/roundtable-share/:shareCode"
element={<PublicRoundtableSharePage />}
/>
<Route
path="/roundtable-share/:shareCode/report"
element={<PublicRoundtableSharePage report />}
/>
<Route
path="/public/scheduled-tasks/:taskId"
element={<PublicScheduledTaskPage />}
/>
<Route
path="/public/scheduled-tasks/:taskId/runs/:runId/fullscreen"
element={<PublicScheduledTaskFullscreenPage />}
/>
<Route
path="/embed/chats/:thread_id"
element={
<ChatRuntime>
<EmbedChatPage />
</ChatRuntime>
}
/>
<Route path="/embed/roundtable" element={<EmbedRoundtablePage />} />
<Route path="/page/*" element={<PageRoutes />} />
<Route path="*" element={<NotFoundPage />} />
</Routes>
</AppProviders>
</HashRouter>
);
}