137 lines · 4.5 KB · TypeScript
RawDownload
import { RotateCcwIcon } from "lucide-react";import {  Outlet,  createFileRoute,  redirect,  useCanGoBack,  useLocation,  useNavigate,} from "@tanstack/react-router";import { useCallback, useEffect, useState } from "react"; import { useSettingsRestore } from "../components/settings/SettingsPanels";import { SettingsBreadcrumb } from "../components/settings/SettingsBreadcrumb";import { Button } from "../components/ui/button";import { SidebarInset } from "../components/ui/sidebar";import { isElectron } from "../env";import { cn } from "~/lib/utils";import { COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS } from "~/workspaceTitlebar"; function RestoreDefaultsButton({ onRestored }: { onRestored: () => void }) {  const { changedSettingLabels, restoreDefaults } = useSettingsRestore(onRestored);   return (    <Button      size="xs"      variant="ghost"      disabled={changedSettingLabels.length === 0}      onClick={() => void restoreDefaults()}    >      <RotateCcwIcon className="mx-1 size-3.5" />      Restore defaults    </Button>  );} function SettingsContentLayout() {  const location = useLocation();  const navigate = useNavigate();  const canGoBack = useCanGoBack();  const [restoreSignal, setRestoreSignal] = useState(0);  const showRestoreDefaults = location.pathname === "/settings/general";  const handleRestored = () => setRestoreSignal((value) => value + 1);  const navigateBackWithinApp = useCallback(() => {    if (canGoBack) {      window.history.back();      return;    }    void navigate({ to: "/" });  }, [canGoBack, navigate]);   useEffect(() => {    const onKeyDown = (event: KeyboardEvent) => {      if (event.defaultPrevented) return;      if (event.key === "Escape") {        event.preventDefault();         const activeElement = document.activeElement;        if (activeElement instanceof HTMLElement) {          activeElement.blur();        }         navigateBackWithinApp();      }    };     window.addEventListener("keydown", onKeyDown);    return () => {      window.removeEventListener("keydown", onKeyDown);    };  }, [navigateBackWithinApp]);   return (    <SidebarInset className="h-dvh min-h-0 overflow-hidden overscroll-y-none bg-background text-foreground isolate">      <div className="flex min-h-0 min-w-0 flex-1 flex-col bg-background text-foreground">        {!isElectron && (          <header            className={cn(              "flex h-[var(--workspace-topbar-height)] min-h-[var(--workspace-topbar-height)] shrink-0 items-center px-3 transition-[padding-left] duration-200 ease-linear motion-reduce:transition-none sm:px-5",              COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS,            )}          >            <div className="flex w-full items-center gap-2">              <SettingsBreadcrumb pathname={location.pathname} />              {showRestoreDefaults ? (                <div className="ms-auto flex items-center gap-2">                  <RestoreDefaultsButton onRestored={handleRestored} />                </div>              ) : null}            </div>          </header>        )}         {isElectron && (          <div            className={cn(              "drag-region flex h-[52px] shrink-0 items-center px-5 transition-[padding-left] duration-200 ease-linear motion-reduce:transition-none wco:h-[env(titlebar-area-height)] wco:pr-[calc(100vw-env(titlebar-area-width)-env(titlebar-area-x)+1em)]",              COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS,            )}          >            <div className="flex w-full items-center gap-2">              <SettingsBreadcrumb pathname={location.pathname} />              {showRestoreDefaults ? (                <div className="ms-auto flex items-center gap-2">                  <RestoreDefaultsButton onRestored={handleRestored} />                </div>              ) : null}            </div>          </div>        )}         <div key={restoreSignal} className="min-h-0 flex flex-1 flex-col">          <Outlet />        </div>      </div>    </SidebarInset>  );} function SettingsRouteLayout() {  return <SettingsContentLayout />;} export const Route = createFileRoute("/settings")({  beforeLoad: async ({ context, location }) => {    if (      context.authGateState.status !== "authenticated" &&      context.authGateState.status !== "hosted-static"    ) {      throw redirect({ to: "/pair", replace: true });    }     if (location.pathname === "/settings") {      throw redirect({ to: "/settings/general", replace: true });    }  },  component: SettingsRouteLayout,});