1- import '@mantine/core/styles.css' ;
2-
31import { ColorSchemeScript , mantineHtmlProps , MantineProvider } from '@mantine/core' ;
2+ import { useMemo } from 'react' ;
43import {
54 isRouteErrorResponse ,
65 Links ,
@@ -10,9 +9,15 @@ import {
109 ScrollRestoration ,
1110} from 'react-router' ;
1211
12+ import { useClientStatus } from '~/hooks/use-client' ;
13+ import { useHydrated } from '~/hooks/use-hydrated' ;
14+ import { waitUntilClientReady } from '~/libs/client' ;
15+
1316import type { Route } from './+types/root' ;
1417import { theme } from './theme' ;
1518
19+ import '@mantine/core/styles.css' ;
20+
1621export function Layout ( { children } : { children : React . ReactNode } ) {
1722 return (
1823 < html lang = "zh-CN" { ...mantineHtmlProps } >
@@ -40,6 +45,41 @@ export default function App() {
4045 return < Outlet /> ;
4146}
4247
48+ // Block all client-side data fetching until the client is initialized.
49+ export const clientMiddleware : Route . ClientMiddlewareFunction [ ] = [
50+ async ( ) => {
51+ console . log ( 'Waiting for OIerDbClient to be ready in client middleware...' ) ;
52+ await waitUntilClientReady ( ) ;
53+ console . log ( 'OIerDbClient is ready, continuing client middleware...' ) ;
54+ } ,
55+ ] ;
56+
57+ // Global loading UI while hydrating or while the root is waiting for client initialization
58+ export function HydrateFallback ( _props : Route . HydrateFallbackProps ) {
59+ // Render SSR-stable text on the first client render; switch to live status after hydration
60+ const hydrated = useHydrated ( ) ;
61+ const status = useClientStatus ( ) ;
62+ const text = useMemo ( ( ) => ( hydrated ? status ?. text || '请稍候' : '请稍候' ) , [ hydrated , status ] ) ;
63+
64+ return (
65+ < div
66+ style = { {
67+ minHeight : '100dvh' ,
68+ display : 'flex' ,
69+ alignItems : 'center' ,
70+ justifyContent : 'center' ,
71+ padding : 16 ,
72+ fontSize : 16 ,
73+ } }
74+ >
75+ < div >
76+ < div style = { { fontWeight : 600 , marginBottom : 8 } } > 正在准备应用…</ div >
77+ < div style = { { opacity : 0.75 } } > { text } </ div >
78+ </ div >
79+ </ div >
80+ ) ;
81+ }
82+
4383export function ErrorBoundary ( { error } : Route . ErrorBoundaryProps ) {
4484 let message = 'Oops!' ;
4585 let details = 'An unexpected error occurred.' ;
0 commit comments