import { ReactElement, Suspense, lazy, useEffect, useState } from "react"; import { lazyWithPreload } from "react-lazy-with-preload"; import { Navigate, Route, Routes, useLocation, useNavigate, useParams, } from "react-router-dom"; import { convertLegacyUrl, isLegacyUrl } from "@/backend/metadata/getmeta"; import { generateQuickSearchMediaUrl } from "@/backend/metadata/tmdb"; import { DetailsModal } from "@/components/overlays/detailsModal"; import { KeyboardCommandsEditModal } from "@/components/overlays/KeyboardCommandsEditModal"; import { KeyboardCommandsModal } from "@/components/overlays/KeyboardCommandsModal"; import { NotificationModal } from "@/components/overlays/notificationsModal"; import { SupportInfoModal } from "@/components/overlays/SupportInfoModal"; import { useGlobalKeyboardEvents } from "@/hooks/useGlobalKeyboardEvents"; import { useOnlineListener } from "@/hooks/usePing"; import { AboutPage } from "@/pages/About"; import { AdminPage } from "@/pages/admin/AdminPage"; import { AllBookmarks } from "@/pages/bookmarks/AllBookmarks"; import VideoTesterView from "@/pages/developer/VideoTesterView"; import { DiscoverMore } from "@/pages/discover/AllMovieLists"; import { Discover } from "@/pages/discover/Discover"; import { MoreContent } from "@/pages/discover/MoreContent"; import MaintenancePage from "@/pages/errors/MaintenancePage"; import { NotFoundPage } from "@/pages/errors/NotFoundPage"; import { HomePage } from "@/pages/HomePage"; import { JipPage } from "@/pages/Jip"; import { LegalPage, shouldHaveLegalPage } from "@/pages/Legal"; import { LoginPage } from "@/pages/Login"; import { MigrationPage } from "@/pages/migration/Migration"; import { MigrationDirectPage } from "@/pages/migration/MigrationDirect"; import { MigrationDownloadPage } from "@/pages/migration/MigrationDownload"; import { MigrationUploadPage } from "@/pages/migration/MigrationUpload"; import { OnboardingPage } from "@/pages/onboarding/Onboarding"; import { OnboardingExtensionPage } from "@/pages/onboarding/OnboardingExtension"; import { OnboardingProxyPage } from "@/pages/onboarding/OnboardingProxy"; import { RegisterPage } from "@/pages/Register"; import { SupportPage } from "@/pages/Support"; import { Layout } from "@/setup/Layout"; import { useHistoryListener } from "@/stores/history"; import { useClearModalsOnNavigation } from "@/stores/interface/overlayStack"; import { LanguageProvider } from "@/stores/language"; const DeveloperPage = lazy(() => import("@/pages/DeveloperPage")); const TestView = lazy(() => import("@/pages/developer/TestView")); const PlayerView = lazyWithPreload(() => import("@/pages/PlayerView")); const SettingsPage = lazyWithPreload(() => import("@/pages/Settings")); PlayerView.preload(); SettingsPage.preload(); function LegacyUrlView({ children }: { children: ReactElement }) { const location = useLocation(); const navigate = useNavigate(); useEffect(() => { const url = location.pathname; if (!isLegacyUrl(url)) return; convertLegacyUrl(location.pathname).then((convertedUrl) => { navigate(convertedUrl ?? "/", { replace: true }); }); }, [location.pathname, navigate]); if (isLegacyUrl(location.pathname)) return null; return children; } function QuickSearch() { const { query } = useParams<{ query: string }>(); const navigate = useNavigate(); useEffect(() => { if (query) { generateQuickSearchMediaUrl(query).then((url) => { navigate(url ?? "/", { replace: true }); }); } else { navigate("/", { replace: true }); } }, [query, navigate]); return null; } function QueryView() { const { query } = useParams<{ query: string }>(); const navigate = useNavigate(); useEffect(() => { if (query) { navigate(`/browse/${encodeURIComponent(query)}`, { replace: true }); } else { navigate("/", { replace: true }); } }, [query, navigate]); return null; } export const maintenanceTime = "March 31th 11:00 PM - 5:00 AM EST"; function App() { useHistoryListener(); useOnlineListener(); useGlobalKeyboardEvents(); useClearModalsOnNavigation(); const maintenance = false; // Shows maintance page const [showDowntime, setShowDowntime] = useState(maintenance); const handleButtonClick = () => { setShowDowntime(false); }; useEffect(() => { const sessionToken = sessionStorage.getItem("downtimeToken"); if (!sessionToken && maintenance) { setShowDowntime(true); sessionStorage.setItem("downtimeToken", "true"); } }, [setShowDowntime, maintenance]); return ( {!showDowntime && ( {/* functional routes */} } /> } /> } /> {/* pages */} } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> {/* Migration pages - awaiting import and export fixes */} } /> } /> } /> } /> {shouldHaveLegalPage() ? ( } /> ) : null} {/* Support page */} } /> } /> {/* Discover pages */} } /> } /> } /> } /> } /> {/* Bookmarks page */} } /> {/* Settings page */} } /> {/* admin routes */} } /> {/* other */} } /> } /> {/* developer routes that can abuse workers are disabled in production */} {process.env.NODE_ENV === "development" ? ( } /> ) : null} } /> )} {showDowntime && ( )} ); } export default App;