import { Suspense, useState, useMemo } from 'react'; import { Outlet } from 'react-router-dom'; import { LeftSidebar } from '@/components/LeftSidebar'; import { RightSidebar } from '@/components/RightSidebar'; import { MobileTopBar } from '@/components/MobileTopBar'; import { MobileBottomNav } from '@/components/MobileBottomNav'; import { MobileDrawer } from '@/components/MobileDrawer'; import { FloatingComposeButton } from '@/components/FloatingComposeButton'; import { CursorFireEffect } from '@/components/CursorFireEffect'; import { Skeleton } from '@/components/ui/skeleton'; import { LayoutStore, LayoutStoreContext, useLayoutSnapshot } from '@/contexts/LayoutContext'; import { useAppContext } from '@/hooks/useAppContext'; 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, fabKind = 1, fabHref, onFabClick, noBottomSpacer = false, wrapperClassName, fabHidden } = useLayoutSnapshot(); const [drawerOpen, setDrawerOpen] = useState(false); const { config } = useAppContext(); return ( <> {/* Magic Mouse fire particle overlay */} {config.magicMouse && } {/* Mobile top bar - only on small screens */} setDrawerOpen(true)} /> {/* Mobile drawer */} {/* Main layout - three column on desktop */}
{/* Desktop left sidebar - hidden below sidebar breakpoint */}
{/* Main content + right sidebar: inside Suspense so the left sidebar persists while lazy pages load */} }> {/* Wrap the center column in a relative container for the FAB */}
{showFAB && (
)}
{rightSidebar ?? }
{/* Mobile bottom nav - only on small screens */} {/* Bottom padding spacer for mobile bottom nav */} {!noBottomSpacer &&
} ); } /** * Persistent layout shell rendered once by the router. * Provides a LayoutStore so child pages can configure layout options * (e.g. showFAB, custom right sidebar) via the `useLayoutOptions` hook. */ export function MainLayout() { const store = useMemo(() => new LayoutStore(), []); return ( ); }