import { lazy, Suspense, useMemo } from 'react'; import { BrowserRouter, Routes, Route, Navigate, useSearchParams, useLocation, useParams } from 'react-router-dom'; import { AuthProvider } from './auth/AuthProvider'; import { useAuth } from './auth/useAuth'; import { PostViewProvider } from './settings/PostViewProvider'; import { ProfileViewProvider } from './settings/ProfileViewProvider'; import { ThemeProvider } from './settings/ThemeProvider'; import { useThemeMode } from './settings/useThemeMode'; import { CustomColorsProvider } from './settings/CustomColorsProvider'; import { PostViewerProvider } from './components/PostViewerProvider'; import { ProfileViewerProvider } from './components/ProfileViewerProvider'; import { ReplyStyleProvider } from './components/ReplyStyleProvider'; import { VideoAutoplayProvider } from './components/VideoAutoplayProvider'; import { VideoVolumeProvider } from './settings/VideoVolumeProvider'; import { ImageProxyProvider } from './settings/ImageProxyProvider'; import { PostLabelsProvider } from './settings/PostLabelsProvider'; import { AppViewUrlsProvider } from './settings/AppViewUrlsProvider'; import { NotificationCountProvider } from './components/NotificationCountProvider'; import { NavigationMemoryProvider } from './components/NavigationMemoryProvider'; import { useNavigationMemory } from './components/useNavigationMemory'; import BookmarkProvider from './components/BookmarkProvider'; import MuteBlockProvider from './components/MuteBlockProvider'; import { useProfileViewMode } from './settings/useProfileViewMode'; import { usePostViewMode } from './settings/usePostViewMode'; import { useAndroidBackButton } from './hooks/useAndroidBackButton'; import Layout from './components/Layout'; import Login from './components/Login'; import Feed from './components/Feed'; import PostThread from './components/PostThread'; import ProfilePage from './components/ProfilePage'; import SearchPage from './components/SearchPage'; import NotificationsPage from './components/NotificationsPage'; import SavedPage from './components/SavedPage'; import FeedViewerPage from './components/FeedViewerPage'; import PostViewerModal from './components/PostViewerModal'; import PostViewerSide from './components/PostViewerSide'; import ProfileSidePanel from './components/ProfileSidePanel'; import DrawerAutoOpener from './components/DrawerAutoOpener'; import LoadingScreen from './components/LoadingScreen'; const SettingsPage = lazy(() => import('./settings/SettingsPage')); function ProfilePostRedirect() { const { actor, rkey } = useParams<{ actor: string; rkey: string }>(); return ; } function PostThreadRoute() { const { handle, rkey, uri } = useParams<{ handle?: string; rkey?: string; uri?: string }>(); const key = handle && rkey ? `${handle}/${rkey}` : uri; return ; } function ProfilePageWrapper() { const { actor } = useParams<{ actor?: string }>(); return ; } function MainContentRoutes() { const location = useLocation(); const { mainContentPath, mainContentSearch } = useNavigationMemory(); const { mode: profileViewMode } = useProfileViewMode(); const { mode: postViewMode } = usePostViewMode(); const isDrawerUrl = useMemo(() => { const { pathname } = location; if (pathname.startsWith('/post/') && postViewMode !== 'page') return true; const profileMatch = pathname.match(/^\/profile\/[^/]+$/); if (profileMatch) { return profileViewMode === 'side'; } return false; }, [location, postViewMode, profileViewMode]); const effectiveLocation = isDrawerUrl ? { pathname: mainContentPath, search: mainContentSearch, hash: '', state: null, key: 'default' } : location; return ( } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> Loading settings…}> } /> } /> ); } function AuthenticatedRoutes() { const { session, loading } = useAuth(); if (loading) return ; if (!session) { try { const currentPath = window.location.pathname + window.location.search + window.location.hash; if (currentPath !== '/' && currentPath !== '/login') { sessionStorage.setItem('foxsky_oauth_redirect', currentPath); } } catch {} return ; } return ( ); } function AppRoutes() { const { session, loading } = useAuth(); const [searchParams] = useSearchParams(); if (loading) return ; const addingAccount = searchParams.get('add_account') === '1'; return ( : } /> } /> ); } function ThemeColorsWrapper({ children }: { children: React.ReactNode }) { const { resolvedTheme } = useThemeMode(); return ( {children} ); } export default function App() { useAndroidBackButton(); return ( ); }