返回 DeepSeek-Reasonix
main.tsx
根目录 / desktop / frontend / src / main.tsx
1 import "./lib/compat";
2 import { StrictMode } from "react";
3 import { createRoot } from "react-dom/client";
4 import App from "./App";
5 import { ErrorBoundary } from "./components/ErrorBoundary";
6 import { installGlobalCrashHandlers, installPerformancePressureMonitor } from "./lib/crash";
7 import { installWailsNonFileDragErrorSuppression } from "./lib/bridge";
8 import { installBreadcrumbConsoleHook } from "./lib/breadcrumbs";
9 import { installMessageSelectionCopy } from "./lib/messageSelectionCopy";
10 import { LocaleProvider, preloadDetectedLocale } from "./lib/i18n";
11 import { ToastProvider } from "./lib/toast";
12 import { initFontFamily } from "./lib/fontFamily";
13 import { initTextSize } from "./lib/textSize";
14 import { initTypographyPreferences } from "./lib/typographyPreferences";
15 import { initTheme } from "./lib/theme";
16 import { initConversationWidth } from "./lib/conversationWidth";
17 import "./styles.css";
18
19 // Install first so startup/runtime failures paint a useful error instead of a
20 // featureless webview background, with the recent console trail attached.
21 installWailsNonFileDragErrorSuppression();
22 installGlobalCrashHandlers();
23 installBreadcrumbConsoleHook();
24 installPerformancePressureMonitor();
25
26 // Apply the saved appearance (auto/light/dark) before the first paint.
27 function initTypographyPlatform() {
28 if (typeof document === "undefined" || typeof navigator === "undefined") return;
29 const params = new URLSearchParams(window.location.search);
30 const override = params.get("platform");
31 const marker = `${navigator.platform} ${navigator.userAgent}`;
32 const platform =
33 override === "darwin" || override === "windows" || override === "linux"
34 ? override
35 : /Win/i.test(marker)
36 ? "windows"
37 : /Mac/i.test(marker)
38 ? "darwin"
39 : "linux";
40 document.documentElement.setAttribute("data-platform", platform);
41 }
42
43 initTypographyPlatform();
44 initTheme();
45 initConversationWidth();
46 initTextSize();
47 initFontFamily();
48 initTypographyPreferences();
49
50 // Pre-warm font fallback stacks so the first frame doesn't flicker between the
51 // browser default font and the app's configured typeface. Inserting a hidden span
52 // with CJK + emoji + math glyphs forces the OS font subsystem to resolve and
53 // cache the fallback chains before React mounts.
54 function prewarmFontFallbacks() {
55 const span = document.createElement("span");
56 span.style.cssText = "position:absolute;visibility:hidden;font-size:1px;pointer-events:none";
57 span.textContent = "中文日本語한국어 математика 😀🎉✓⚠∑∏∫";
58 document.body.appendChild(span);
59 // Force layout so the browser resolves font fallback chains.
60 void span.offsetHeight;
61 requestAnimationFrame(() => {
62 requestAnimationFrame(() => {
63 span.remove();
64 });
65 });
66 }
67 prewarmFontFallbacks();
68
69 installMessageSelectionCopy(document);
70
71 // Inside the Wails shell, suppress the webview's default right-click menu — its
72 // Reload / Back / Inspect entries are easy to hit by accident and can reset or
73 // navigate away from the app. Text inputs keep their native Cut/Copy/Paste menu.
74 // Left alone in a plain browser (pnpm dev) so devtools stay reachable.
75 if (typeof window !== "undefined" && window.runtime) {
76 window.addEventListener("contextmenu", (e) => {
77 const target = e.target as HTMLElement | null;
78 if (!target?.closest("input, textarea")) e.preventDefault();
79 });
80 }
81
82 const root = document.getElementById("root");
83 if (!root) throw new Error("missing #root");
84 const rootElement = root;
85
86 async function mountApp() {
87 try {
88 await preloadDetectedLocale();
89 } catch (error) {
90 console.error("failed to preload desktop locale", error);
91 }
92 createRoot(rootElement).render(
93 <StrictMode>
94 <ErrorBoundary>
95 <LocaleProvider>
96 <ToastProvider>
97 <App />
98 </ToastProvider>
99 </LocaleProvider>
100 </ErrorBoundary>
101 </StrictMode>,
102 );
103 }
104
105 void mountApp();
106
106 lines Plain Text