import { useEffect, useMemo } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { ThemeProvider as NextThemesProvider } from "next-themes";
import { DesensitizeWordsLoader } from "@/components/desensitize-words-loader";
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 { fetchYLogConfig } from "@/core/log/y-log-config";
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 {
resolveForcedEmbedTheme,
syncEmbedSessionFromSearch,
} from "@/core/embed/embed-session";
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 DashboardStandalonePage from "@/roundtable-planning/pages/DashboardStandalonePage";
import PositionRoundtablePage from "@/position-roundtable/pages/PositionRoundtablePage";
import WeKnoraWikiPageView from "@/strategy-components/components/resource-management/llmwiki/WeKnoraWikiPageView";
import {
isPositionRoundtableStandaloneMode,
POSITION_ROUNDTABLE_ROUTE,
} from "@/position-roundtable/demo/position-roundtable-demo-config";
import { ChatRuntime } from "./pages/WorkspaceRoutes";
import { NotFoundPage } from "./pages/NotFoundPage";
import OfficialDeerFlowEntry from "./pages/OfficialDeerFlowEntry";
const PUBLIC_EMBED_PREFIXES = [
"/share/",
"/public/",
"/roundtable-share/",
"/embed/knowledge/",
];
function AppProviders({ children }: { children: React.ReactNode }) {
const locale = useMemo(() => detectLocale(), []);
const location = useLocation();
const publicEmbedTheme = usePublicEmbedTheme();
const positionStandaloneMode = isPositionRoundtableStandaloneMode();
// iframe 嵌入会话(按标签页 sessionStorage)集中在此同步:任何带 `&embed=1` 的入口(深链登录页
// 或直接深链路由)一进来就启用、`embed=0` 关闭,后续干净路由靠会话维持去 chrome + 强制主题。
useEffect(() => {
syncEmbedSessionFromSearch(location.search);
}, [location.search]);
// 操作日志(Y-Log):启动早期预热上报配置,使 writeYLog 同步读缓存即可工作
// (刷新后 module 缓存清空,token 登录用户也能继续上报)。失败静默。
useEffect(() => {
if (positionStandaloneMode) return;
void fetchYLogConfig();
}, [positionStandaloneMode]);
const forcedTheme = useMemo(() => {
// iframe 嵌入模式(外部系统 `&embed=1`)最高优先:按本标签页的嵌入主题强制明/暗。
// 走 next-themes forcedTheme(不写 localStorage)→ 同浏览器另开的正常系统页不受影响。
const embedTheme = resolveForcedEmbedTheme(location.search);
if (embedTheme) return embedTheme;
const routeTheme = resolveForcedThemeForPath(
location.pathname,
location.search,
);
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 (
{!positionStandaloneMode && }
{children}
);
}
/**
* 根路由 `/` → `/login` 重定向,**保留 query string**。
* 外部系统的任务深链落在 `#/?taskId=...&goPath=...`,裸 `` 会丢掉
* query,导致 LoginPage 读不到参数;这里把 search 一并带过去。
*/
function RootRedirect() {
const { search } = useLocation();
if (isPositionRoundtableStandaloneMode()) {
return ;
}
return ;
}
export function App() {
const positionStandaloneMode = isPositionRoundtableStandaloneMode();
const standaloneLoginRedirect = (
);
const pageElement = positionStandaloneMode ? (
) : (
);
return (
} />
}
/>
}
/>
} />
} />
} />
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
} />
}
/>
}
/>
} />
} />
);
}