import { lazy, Suspense } from "react"; import { BrowserRouter, Navigate, Route, Routes, useLocation, useParams, } from "react-router"; import { RestrictedGuest } from "./pages/RestrictedGuest.tsx"; import { RestrictedLoggedIn } from "./pages/RestrictedLoggedIn.tsx"; import { useAuth } from "./hooks/useAuth.ts"; import { useDefaultFeedTab } from "./hooks/useDefaultFeedTab.ts"; import { DEFAULT_FEED_TAB } from "./config/feedTabs.ts"; import { AuthProvider } from "./contexts/AuthProvider.tsx"; import { PlayerProvider } from "./contexts/PlayerProvider.tsx"; import { WSProvider } from "./contexts/WSProvider.tsx"; import { FollowProvider } from "./contexts/FollowProvider.tsx"; import { CategoriesProvider } from "./contexts/CategoriesProvider.tsx"; import { ThemeProvider } from "./contexts/ThemeProvider.tsx"; import { ChatProvider } from "./contexts/ChatProvider.tsx"; import { GlobalPlayer } from "./components/player/GlobalPlayer.tsx"; import { DumpFab } from "./components/layout/DumpFab.tsx"; import { ChatFab } from "./components/layout/ChatFab.tsx"; import "./App.css"; const Index = lazy(() => import("./pages/Index.tsx").then((m) => ({ default: m.Index })) ); const Dump = lazy(() => import("./pages/Dump.tsx").then((m) => ({ default: m.Dump })) ); const DumpEdit = lazy(() => import("./pages/DumpEdit.tsx").then((m) => ({ default: m.DumpEdit })) ); const UserLogin = lazy(() => import("./pages/UserLogin.tsx").then((m) => ({ default: m.UserLogin })) ); const UserPublicProfile = lazy(() => import("./pages/UserPublicProfile.tsx").then((m) => ({ default: m.UserPublicProfile, })) ); const UserRegister = lazy(() => import("./pages/UserRegister.tsx").then((m) => ({ default: m.UserRegister })) ); const UserDumps = lazy(() => import("./pages/UserDumps.tsx").then((m) => ({ default: m.UserDumps })) ); const UserUpvoted = lazy(() => import("./pages/UserUpvoted.tsx").then((m) => ({ default: m.UserUpvoted })) ); const UserPlaylists = lazy(() => import("./pages/UserPlaylists.tsx").then((m) => ({ default: m.UserPlaylists, })) ); const PlaylistDetail = lazy(() => import("./pages/PlaylistDetail.tsx").then((m) => ({ default: m.PlaylistDetail, })) ); const Notifications = lazy(() => import("./pages/Notifications.tsx").then((m) => ({ default: m.Notifications, })) ); const Search = lazy(() => import("./pages/Search.tsx").then((m) => ({ default: m.Search })) ); const ResetPassword = lazy(() => import("./pages/ResetPassword.tsx").then((m) => ({ default: m.ResetPassword, })) ); const NotFound = lazy(() => import("./pages/NotFound.tsx").then((m) => ({ default: m.NotFound })) ); // Default feed tab for the current viewer ("followed" needs a session). function useResolvedDefaultTab() { const { user } = useAuth(); const [preferredTab] = useDefaultFeedTab(); return preferredTab === "followed" && !user ? DEFAULT_FEED_TAB : preferredTab; } // The query string has to survive the hop: the Web Share Target posts to "/", // so an Android share arrives here as `/?share_url=…` and the feed below is the // only thing that can act on it. function IndexRedirect() { const { search } = useLocation(); return ; } // Bare `/` lands on that category's default feed tab. function CategoryRedirect() { const { categorySlug } = useParams(); const { search } = useLocation(); return ( ); } // Both `/~/:feedTab` (all) and `/:categorySlug/:feedTab` render the same feed. // Keying by scope remounts the feed when switching categories so it refetches, // while switching tabs within a scope keeps it mounted (client-side re-sort). function ScopedIndex() { const { categorySlug } = useParams(); return ; } function AppRoutes() { return ( <> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); } function App() { return ( ); } export default App;