diff --git a/src/utils/setup/App.tsx b/src/utils/setup/App.tsx new file mode 100644 index 00000000..ff37550b --- /dev/null +++ b/src/utils/setup/App.tsx @@ -0,0 +1,185 @@ +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 { useOnlineListener } from "@/hooks/usePing"; +import { AboutPage } from "@/pages/About"; +import { AdminPage } from "@/pages/admin/AdminPage"; +import VideoTesterView from "@/pages/developer/VideoTesterView"; +import { DmcaPage, shouldHaveDmcaPage } from "@/pages/Dmca"; +import MaintenancePage from "@/pages/errors/MaintenancePage"; +import { NotFoundPage } from "@/pages/errors/NotFoundPage"; +import { HomePage } from "@/pages/HomePage"; +import { LoginPage } from "@/pages/Login"; +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 { TopFlix } from "@/pages/TopFlix"; +import { TopSources } from "@/pages/TopSources"; +import { Layout } from "@/setup/Layout"; +import { useHistoryListener } from "@/stores/history"; +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/${query}`, { replace: true }); + } else { + navigate("/", { replace: true }); + } + }, [query, navigate]); + + return null; +} + +// Duplicate of @/src/setup/App.tsx +function App() { + useHistoryListener(); + useOnlineListener(); + const maintenance = false; // Changing to true shows maintenance 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 */} + + + + + + } + /> + + + + + + } + /> + } /> + } /> + } /> + } /> + } /> + } /> + } + /> + } /> + {shouldHaveDmcaPage() ? ( + } /> + ) : null} + {/* Support page */} + } /> + {/* Top flix page */} + } /> + } /> + {/* Settings page */} + + + + } + /> + {/* admin routes */} + } /> + {/* other */} + } /> + } /> + {/* developer routes that can abuse workers are disabled in production */} + {process.env.NODE_ENV === "development" ? ( + } /> + ) : null} + } /> + + )} + {showDowntime && ( + + )} + + ); +} +