import ReactDOM from "react-dom/client"; import Root from "./root"; import "./index.css"; import { createBrowserRouter, isRouteErrorResponse, redirect, RouterProvider, useRouteError, } from "react-router-dom"; import DeviceRoute, { LocalDevice } from "@routes/devices.$id"; import DevicesRoute, { loader as DeviceListLoader } from "@routes/devices"; import SetupRoute from "@routes/devices.$id.setup"; import LoginRoute from "@routes/login"; import SignupRoute from "@routes/signup"; import AdoptRoute from "@routes/adopt"; import DeviceIdRename from "@routes/devices.$id.rename"; import DevicesIdDeregister from "@routes/devices.$id.deregister"; import NotFoundPage from "@components/NotFoundPage"; import EmptyCard from "@components/EmptyCard"; import { ExclamationTriangleIcon } from "@heroicons/react/16/solid"; import Card from "@components/Card"; import DevicesAlreadyAdopted from "@routes/devices.already-adopted"; import Notifications from "./notifications"; import LoginLocalRoute from "./routes/login-local"; import WelcomeLocalModeRoute from "./routes/welcome-local.mode"; import WelcomeRoute, { DeviceStatus } from "./routes/welcome-local"; import WelcomeLocalPasswordRoute from "./routes/welcome-local.password"; import { CLOUD_API, DEVICE_API } from "./ui.config"; import OtherSessionRoute from "./routes/devices.$id.other-session"; import MountRoute from "./routes/devices.$id.mount"; import * as SettingsRoute from "./routes/devices.$id.settings"; import SettingsKeyboardMouseRoute from "./routes/devices.$id.settings.mouse"; import api from "./api"; import * as SettingsIndexRoute from "./routes/devices.$id.settings._index"; import SettingsAdvancedRoute from "./routes/devices.$id.settings.advanced"; import * as SettingsAccessIndexRoute from "./routes/devices.$id.settings.access._index"; import SettingsHardwareRoute from "./routes/devices.$id.settings.hardware"; import SettingsVideoRoute from "./routes/devices.$id.settings.video"; import SettingsAppearanceRoute from "./routes/devices.$id.settings.appearance"; import * as SettingsGeneralIndexRoute from "./routes/devices.$id.settings.general._index"; import SettingsGeneralUpdateRoute from "./routes/devices.$id.settings.general.update"; import SecurityAccessLocalAuthRoute from "./routes/devices.$id.settings.access.local-auth"; export const isOnDevice = import.meta.env.MODE === "device"; export const isInCloud = !isOnDevice; export async function checkCloudAuth() { const res = await fetch(`${CLOUD_API}/me`, { mode: "cors", credentials: "include", headers: { "Content-Type": "application/json" }, }); if (res.status === 401) { throw redirect(`/login?returnTo=${window.location.href}`); } return await res.json(); } export async function checkDeviceAuth() { const res = await api .GET(`${DEVICE_API}/device/status`) .then(res => res.json() as Promise); if (!res.isSetup) return redirect("/welcome"); const deviceRes = await api.GET(`${DEVICE_API}/device`); if (deviceRes.status === 401) return redirect("/login-local"); if (deviceRes.ok) { const device = (await deviceRes.json()) as LocalDevice; return { authMode: device.authMode }; } throw new Error("Error fetching device"); } export async function checkAuth() { return import.meta.env.MODE === "device" ? checkDeviceAuth() : checkCloudAuth(); } let router; if (isOnDevice) { router = createBrowserRouter([ { path: "/welcome/mode", element: , action: WelcomeLocalModeRoute.action, }, { path: "/welcome/password", element: , action: WelcomeLocalPasswordRoute.action, }, { path: "/welcome", element: , loader: WelcomeRoute.loader, }, { path: "/login-local", element: , action: LoginLocalRoute.action, loader: LoginLocalRoute.loader, }, { path: "/", errorElement: , element: , loader: DeviceRoute.loader, children: [ { path: "other-session", element: , }, { path: "mount", element: , }, { path: "settings", element: , children: [ { index: true, loader: SettingsIndexRoute.loader, }, { path: "general", children: [ { index: true, element: , }, { path: "update", element: , }, ], }, { path: "mouse", element: , }, { path: "advanced", element: , }, { path: "hardware", element: , }, { path: "access", children: [ { index: true, element: , loader: SettingsAccessIndexRoute.loader, }, { path: "local-auth", element: , }, ], }, { path: "video", element: , }, { path: "appearance", element: , }, ], }, ], }, { path: "/adopt", element: , loader: AdoptRoute.loader, errorElement: , }, ]); } else { router = createBrowserRouter([ { errorElement: , children: [ { path: "signup", element: }, { path: "login", element: }, { path: "/", element: , children: [ { index: true, loader: async () => { await checkAuth(); return redirect(`/devices`); }, }, { path: "devices/:id/setup", element: , action: SetupRoute.action, loader: SetupRoute.loader, }, { path: "devices/already-adopted", element: , }, { path: "devices/:id", element: , loader: DeviceRoute.loader, children: [ { path: "other-session", element: , }, { path: "mount", element: , }, { path: "settings", element: , children: [ { index: true, loader: SettingsIndexRoute.loader, }, { path: "general", children: [ { index: true, element: , }, { path: "update", element: , }, ], }, { path: "mouse", element: , }, { path: "advanced", element: , }, { path: "hardware", element: , }, { path: "access", children: [ { index: true, element: , loader: SettingsAccessIndexRoute.loader, }, { path: "local-auth", element: , }, ], }, { path: "video", element: , }, { path: "appearance", element: , }, ], }, ], }, { path: "devices/:id/deregister", element: , loader: DevicesIdDeregister.loader, action: DevicesIdDeregister.action, }, { path: "devices/:id/rename", element: , loader: DeviceIdRename.loader, action: DeviceIdRename.action, }, { path: "devices", element: , loader: DeviceListLoader }, ], }, ], }, ]); } document.addEventListener("DOMContentLoaded", () => { ReactDOM.createRoot(document.getElementById("root")!).render( <> , ); }); // eslint-disable-next-line react-refresh/only-export-components function ErrorBoundary() { const error = useRouteError(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error const errorMessage = error?.data?.error?.message || error?.message; if (isRouteErrorResponse(error)) { if (error.status === 404) return ; } return (
{errorMessage}
) } />
); }