diff --git a/src/app/App.tsx b/src/app/App.tsx index cbbc4fc..4c2ce1b 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -13,6 +13,7 @@ import MediaManager from './components/MediaManager'; import logoSvg from '../imports/logo.svg'; import { useSettings } from './settings'; import { WsProvider } from './ws'; +import { LazyLoader } from './components/ui/lazy-loader'; // Three.js lives only in RealityOverridePage — keep lazy so it doesn't load on startup. // CodeMirror/syntax-highlighter/ReactMarkdown live in MediaViewerEditor — lazy-loaded @@ -47,13 +48,6 @@ type AppId = | 'reality-override' | 'reality-override-admin'; -function PageLoader() { - return ( -
- -
- ); -} export default function App() { const [currentPage, setCurrentPage] = useState('status'); @@ -314,7 +308,7 @@ function AppPage({ title, onBack }: { title: string; onBack: () => void }) {
- }> + }> {pages[currentPage]}
diff --git a/src/app/components/ui/lazy-loader.tsx b/src/app/components/ui/lazy-loader.tsx new file mode 100644 index 0000000..fac3eb4 --- /dev/null +++ b/src/app/components/ui/lazy-loader.tsx @@ -0,0 +1,38 @@ +import { useEffect, useState } from 'react'; +import { Loader2 } from 'lucide-react'; + +export function LazyLoader() { + const [pct, setPct] = useState(0); + + useEffect(() => { + const steps: [number, number][] = [ + [80, 30], + [400, 60], + [1200, 80], + [2500, 92], + ]; + const timers = steps.map(([delay, val]) => setTimeout(() => setPct(val), delay)); + return () => timers.forEach(clearTimeout); + }, []); + + const duration = + pct <= 30 ? '150ms' : + pct <= 60 ? '500ms' : + pct <= 80 ? '1000ms' : '1500ms'; + + return ( +
+
+
+
+ +
+ + Loading… +
+
+ ); +}