diff --git a/src/App.tsx b/src/App.tsx index b1de73a9..382c77fb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { createHead, UnheadProvider } from '@unhead/react/client'; import { InferSeoMetaPlugin } from '@unhead/addons'; -import { Suspense, useEffect } from 'react'; +import { useEffect } from 'react'; import NostrProvider from '@/components/NostrProvider'; import { NostrSync } from '@/components/NostrSync'; import { NativeNotifications } from '@/components/NativeNotifications'; @@ -99,9 +99,7 @@ export function App() { - - - + diff --git a/src/components/MainLayout.tsx b/src/components/MainLayout.tsx index e83b085b..05042dca 100644 --- a/src/components/MainLayout.tsx +++ b/src/components/MainLayout.tsx @@ -1,4 +1,4 @@ -import { useState, useMemo } from 'react'; +import { Suspense, useState, useMemo } from 'react'; import { Outlet } from 'react-router-dom'; import { LeftSidebar } from '@/components/LeftSidebar'; import { RightSidebar } from '@/components/RightSidebar'; @@ -6,9 +6,60 @@ import { MobileTopBar } from '@/components/MobileTopBar'; import { MobileBottomNav } from '@/components/MobileBottomNav'; import { MobileDrawer } from '@/components/MobileDrawer'; import { FloatingComposeButton } from '@/components/FloatingComposeButton'; +import { Skeleton } from '@/components/ui/skeleton'; import { LayoutStore, LayoutStoreContext, useLayoutSnapshot } from '@/contexts/LayoutContext'; import { cn } from '@/lib/utils'; +/** Skeleton shown in the content area while a lazy page chunk is loading. */ +function PageSkeleton() { + return ( + <> + {/* Main column skeleton */} +
+ {/* Header skeleton */} +
+ +
+ {/* Content skeletons */} +
+ {Array.from({ length: 4 }).map((_, i) => ( +
+
+ +
+ + +
+
+
+ + +
+
+ ))} +
+
+ {/* Right sidebar skeleton */} + + + ); +} + /** Inner component that reads layout options from the context store. */ function MainLayoutInner() { const { rightSidebar, showFAB = false, noBottomSpacer = false, wrapperClassName } = useLayoutSnapshot(); @@ -29,11 +80,11 @@ function MainLayoutInner() { - {/* Main content area - swapped by the router */} - - - {/* Desktop right sidebar - handled internally with hidden lg:block */} - {rightSidebar ?? } + {/* Main content + right sidebar: inside Suspense so the left sidebar persists while lazy pages load */} + }> + + {rightSidebar ?? } + {/* Mobile bottom nav - only on small screens */}