import "./assets/main.css" import "./i18n" import { StrictMode } from "react" import { createRoot } from "react-dom/client" import App from "./App" import { ClientContext } from "./ClientContext" import { StudentService } from "./services/StudentService" import { ServiceProvider } from "./contexts/ServiceContext" import { api } from "./preload/types" if (!(window as any).api) { ;(window as any).api = api } const ctx = new ClientContext() new StudentService(ctx) const safeWriteLog = (payload: { level: "debug" | "info" | "warn" | "error" message: string meta?: any }) => { try { const api = (window as any).api if (!api?.writeLog) return Promise.resolve(api.writeLog(payload)).catch(() => void 0) } catch { return } } const patchConsole = () => { const c = window.console as any const original = { log: typeof c.log === "function" ? c.log.bind(c) : undefined, info: typeof c.info === "function" ? c.info.bind(c) : undefined, warn: typeof c.warn === "function" ? c.warn.bind(c) : undefined, debug: typeof c.debug === "function" ? c.debug.bind(c) : undefined, error: typeof c.error === "function" ? c.error.bind(c) : undefined, trace: typeof c.trace === "function" ? c.trace.bind(c) : undefined, table: typeof c.table === "function" ? c.table.bind(c) : undefined, } const set = (name: string, fn: (...args: any[]) => void) => { try { c[name] = fn } catch { void 0 } } set("log", (...args: any[]) => { safeWriteLog({ level: "info", message: String(args[0] ?? ""), meta: args.slice(1) }) original.log?.(...args) }) set("info", (...args: any[]) => { safeWriteLog({ level: "info", message: String(args[0] ?? ""), meta: args.slice(1) }) original.info?.(...args) }) set("warn", (...args: any[]) => { safeWriteLog({ level: "warn", message: String(args[0] ?? ""), meta: args.slice(1) }) original.warn?.(...args) }) set("debug", (...args: any[]) => { safeWriteLog({ level: "debug", message: String(args[0] ?? ""), meta: args.slice(1) }) original.debug?.(...args) }) set("error", (...args: any[]) => { const first = args[0] if (first instanceof Error) { safeWriteLog({ level: "error", message: first.message, meta: { stack: first.stack, args: args.slice(1) }, }) original.error?.(...args) return } safeWriteLog({ level: "error", message: String(first ?? ""), meta: args.slice(1) }) original.error?.(...args) }) set("trace", (...args: any[]) => { safeWriteLog({ level: "debug", message: "console.trace", meta: { args, stack: new Error("console.trace").stack }, }) original.trace?.(...args) }) set("table", (...args: any[]) => { safeWriteLog({ level: "info", message: "console.table", meta: args }) original.table?.(...args) }) } patchConsole() const disableTouchZoom = () => { let lastTouchEnd = 0 // iOS Safari/WebView 手势事件,直接阻止页面缩放 for (const type of ["gesturestart", "gesturechange", "gestureend"]) { document.addEventListener( type, (event) => { event.preventDefault() }, { passive: false } ) } // 双指触摸移动时阻止缩放 document.addEventListener( "touchmove", (event) => { if (event.touches.length > 1) { event.preventDefault() } }, { passive: false } ) // 连续快速双击时阻止浏览器放大 document.addEventListener( "touchend", (event) => { const now = Date.now() if (now - lastTouchEnd <= 300) { event.preventDefault() } lastTouchEnd = now }, { passive: false } ) // 部分环境下双击会触发 dblclick,补充阻止 document.addEventListener( "dblclick", (event) => { event.preventDefault() }, { passive: false } ) } disableTouchZoom() const platform = navigator.userAgent.toLowerCase() const isIos = /iphone|ipad|ipod/.test(platform) const isAndroid = platform.includes("android") const isMacDesktop = platform.includes("mac") && !isIos if (isMacDesktop) { document.documentElement.classList.add("platform-macos") } if (isIos) { document.documentElement.classList.add("platform-ios") } if (isAndroid) { document.documentElement.classList.add("platform-android") } window.addEventListener("error", (e: any) => { const error = e?.error safeWriteLog({ level: "error", message: "renderer:error", meta: { message: error?.message || e?.message, stack: error?.stack, filename: e?.filename, lineno: e?.lineno, colno: e?.colno, }, }) }) window.addEventListener("unhandledrejection", (e: any) => { const reason = e?.reason safeWriteLog({ level: "error", message: "renderer:unhandledrejection", meta: reason instanceof Error ? { message: reason.message, stack: reason.stack } : { reason }, }) }) createRoot(document.getElementById("root")!).render( )