sudo-archive/src/index.tsx

143 lines
4.3 KiB
TypeScript
Raw Normal View History

import "core-js/stable";
2023-11-19 19:03:35 +00:00
import "./stores/__old/imports";
import "@/setup/ga";
import "@/setup/index.css";
import React, { Suspense, useCallback } from "react";
2023-09-01 13:37:03 +00:00
import type { ReactNode } from "react";
2022-02-16 20:30:12 +00:00
import ReactDOM from "react-dom";
import { HelmetProvider } from "react-helmet-async";
import { BrowserRouter, HashRouter } from "react-router-dom";
import { useAsync } from "react-use";
2023-02-24 19:12:20 +00:00
import { registerSW } from "virtual:pwa-register";
2023-01-07 20:36:18 +00:00
import { Button } from "@/components/Button";
import { Icon, Icons } from "@/components/Icon";
import { Loading } from "@/components/layout/Loading";
import { useAuthRestore } from "@/hooks/auth/useAuthRestore";
import { useBackendUrl } from "@/hooks/auth/useBackendUrl";
import { ErrorBoundary } from "@/pages/errors/ErrorBoundary";
import { MigrationPart } from "@/pages/parts/migrations/MigrationPart";
import { LargeTextPart } from "@/pages/parts/util/LargeTextPart";
2023-01-07 20:36:18 +00:00
import App from "@/setup/App";
2023-10-21 20:14:54 +00:00
import { conf } from "@/setup/config";
2023-06-18 12:10:26 +00:00
import i18n from "@/setup/i18n";
import { useAuthStore } from "@/stores/auth";
2023-11-19 19:03:35 +00:00
import { BookmarkSyncer } from "@/stores/bookmarks/BookmarkSyncer";
import { useLanguageStore } from "@/stores/language";
import { ProgressSyncer } from "@/stores/progress/ProgressSyncer";
import { SettingsSyncer } from "@/stores/subtitles/SettingsSyncer";
import { useThemeStore } from "@/stores/theme";
2023-01-25 20:44:15 +00:00
import { initializeChromecast } from "./setup/chromecast";
import { initializeOldStores } from "./stores/__old/migrations";
2022-12-29 17:25:57 +00:00
// initialize
const key =
(window as any)?.__CONFIG__?.VITE_KEY ?? import.meta.env.VITE_KEY ?? null;
if (key) {
2023-02-22 20:41:13 +00:00
(window as any).initMW(conf().PROXY_URLS, key);
2022-12-29 17:25:57 +00:00
}
2023-01-25 20:44:15 +00:00
initializeChromecast();
2023-02-24 19:12:20 +00:00
registerSW({
immediate: true,
2023-02-24 19:12:20 +00:00
});
2021-07-13 22:31:37 +00:00
function LoadingScreen(props: { type: "user" | "lazy" }) {
return (
<LargeTextPart iconSlot={<Loading />}>Loading {props.type}</LargeTextPart>
);
}
function ErrorScreen(props: {
children: ReactNode;
showResetButton?: boolean;
}) {
const setBackendUrl = useAuthStore((s) => s.setBackendUrl);
const resetBackend = useCallback(() => {
setBackendUrl(null);
// eslint-disable-next-line no-restricted-globals
location.reload();
}, [setBackendUrl]);
return (
<LargeTextPart
iconSlot={
<Icon className="text-type-danger text-2xl" icon={Icons.WARNING} />
}
>
{props.children}
{props.showResetButton ? (
<div className="mt-6">
<Button theme="secondary" onClick={resetBackend}>
Reset back-end
</Button>
</div>
) : null}
</LargeTextPart>
);
}
function AuthWrapper() {
const status = useAuthRestore();
const backendUrl = conf().BACKEND_URL;
const userBackendUrl = useBackendUrl();
if (status.loading) return <LoadingScreen type="user" />;
if (status.error)
return (
<ErrorScreen showResetButton={backendUrl !== userBackendUrl}>
{backendUrl !== userBackendUrl
? "Failed to fetch user data. Try resetting the backend URL"
: "Failed to fetch user data."}
</ErrorScreen>
);
return <App />;
}
function MigrationRunner() {
const status = useAsync(async () => {
i18n.changeLanguage(useLanguageStore.getState().language);
await initializeOldStores();
}, []);
if (status.loading) return <MigrationPart />;
if (status.error)
return <ErrorScreen>Failed to migrate your data.</ErrorScreen>;
return <AuthWrapper />;
}
function TheRouter(props: { children: ReactNode }) {
const normalRouter = conf().NORMAL_ROUTER;
if (normalRouter) return <BrowserRouter>{props.children}</BrowserRouter>;
return <HashRouter>{props.children}</HashRouter>;
}
function ThemeProvider(props: { children: ReactNode }) {
const theme = useThemeStore((s) => s.theme);
const themeSelector = theme ? `theme-${theme}` : undefined;
return <div className={themeSelector}>{props.children}</div>;
}
2021-07-13 22:31:37 +00:00
ReactDOM.render(
2022-02-16 20:30:12 +00:00
<React.StrictMode>
<ErrorBoundary>
<HelmetProvider>
<Suspense fallback={<LoadingScreen type="lazy" />}>
<ThemeProvider>
<ProgressSyncer />
2023-11-19 19:03:35 +00:00
<BookmarkSyncer />
<SettingsSyncer />
<TheRouter>
<MigrationRunner />
</TheRouter>
</ThemeProvider>
</Suspense>
</HelmetProvider>
2022-02-16 20:30:12 +00:00
</ErrorBoundary>
</React.StrictMode>,
document.getElementById("root")
2021-07-13 22:31:37 +00:00
);