perf: make splash non-blocking and session-aware

This commit is contained in:
afterhours247
2026-07-22 05:24:17 +08:00
parent ea72934716
commit 159e07543d
+27 -6
View File
@@ -5,23 +5,44 @@ import { ThemeProvider } from '@/components/ThemeToggle'
import { ToastProvider } from '@/hooks/use-toast' import { ToastProvider } from '@/hooks/use-toast'
import { SplashScreen } from '@/components/SplashScreen' import { SplashScreen } from '@/components/SplashScreen'
const SPLASH_SESSION_KEY = 'offlineacademy:splash-seen'
export function Providers({ children }: { children: React.ReactNode }) { export function Providers({ children }: { children: React.ReactNode }) {
const [showSplash, setShowSplash] = React.useState(true) const [showSplash, setShowSplash] = React.useState(true)
// Safety fallback: force hide after 5 seconds max React.useLayoutEffect(() => {
try {
if (sessionStorage.getItem(SPLASH_SESSION_KEY) === 'true') {
setShowSplash(false)
}
} catch {
setShowSplash(false)
}
}, [])
React.useEffect(() => { React.useEffect(() => {
const timer = setTimeout(() => setShowSplash(false), 5000) if (!showSplash) return
return () => clearTimeout(timer) const timer = window.setTimeout(() => setShowSplash(false), 2500)
return () => window.clearTimeout(timer)
}, [showSplash])
const completeSplash = React.useCallback(() => {
try {
sessionStorage.setItem(SPLASH_SESSION_KEY, 'true')
} catch {
// Storage can be unavailable in hardened/private browser modes.
}
setShowSplash(false)
}, []) }, [])
return ( return (
<ThemeProvider> <ThemeProvider>
<ToastProvider> <ToastProvider>
{children}
{showSplash && ( {showSplash && (
<SplashScreen onComplete={() => setShowSplash(false)} minDuration={1500} /> <SplashScreen onComplete={completeSplash} minDuration={550} />
)} )}
{!showSplash && children}
</ToastProvider> </ToastProvider>
</ThemeProvider> </ThemeProvider>
) )
} }