100 lines · 3.1 KB · TypeScript
RawDownload
import { Outlet, createFileRoute } from "@tanstack/react-router";import { useEffect } from "react"; import { useHandleNewThread } from "../hooks/useHandleNewThread";import { isTerminalFocused } from "../lib/terminalFocus";import { resolveShortcutCommand } from "../keybindings";import { selectThreadTerminalState, useTerminalStateStore } from "../terminalStateStore";import { useThreadSelectionStore } from "../threadSelectionStore";import { resolveSidebarNewThreadEnvMode } from "~/components/Sidebar.logic";import { useSettings } from "~/hooks/useSettings";import { useServerKeybindings } from "~/rpc/serverState"; function ChatRouteGlobalShortcuts() {  const clearSelection = useThreadSelectionStore((state) => state.clearSelection);  const selectedThreadIdsSize = useThreadSelectionStore((state) => state.selectedThreadIds.size);  const { activeDraftThread, activeThread, defaultProjectId, handleNewThread, routeThreadId } =    useHandleNewThread();  const keybindings = useServerKeybindings();  const terminalOpen = useTerminalStateStore((state) =>    routeThreadId      ? selectThreadTerminalState(state.terminalStateByThreadId, routeThreadId).terminalOpen      : false,  );  const appSettings = useSettings();   useEffect(() => {    const onWindowKeyDown = (event: KeyboardEvent) => {      if (event.defaultPrevented) return;       if (event.key === "Escape" && selectedThreadIdsSize > 0) {        event.preventDefault();        clearSelection();        return;      }       const projectId = activeThread?.projectId ?? activeDraftThread?.projectId ?? defaultProjectId;      if (!projectId) return;       const command = resolveShortcutCommand(event, keybindings, {        context: {          terminalFocus: isTerminalFocused(),          terminalOpen,        },      });       if (command === "chat.newLocal") {        event.preventDefault();        event.stopPropagation();        void handleNewThread(projectId, {          envMode: resolveSidebarNewThreadEnvMode({            defaultEnvMode: appSettings.defaultThreadEnvMode,          }),        });        return;      }       if (command === "chat.new") {        event.preventDefault();        event.stopPropagation();        void handleNewThread(projectId, {          branch: activeThread?.branch ?? activeDraftThread?.branch ?? null,          worktreePath: activeThread?.worktreePath ?? activeDraftThread?.worktreePath ?? null,          envMode:            activeDraftThread?.envMode ?? (activeThread?.worktreePath ? "worktree" : "local"),        });        return;      }    };     window.addEventListener("keydown", onWindowKeyDown);    return () => {      window.removeEventListener("keydown", onWindowKeyDown);    };  }, [    activeDraftThread,    activeThread,    clearSelection,    handleNewThread,    keybindings,    defaultProjectId,    selectedThreadIdsSize,    terminalOpen,    appSettings.defaultThreadEnvMode,  ]);   return null;} function ChatRouteLayout() {  return (    <>      <ChatRouteGlobalShortcuts />      <Outlet />    </>  );} export const Route = createFileRoute("/_chat")({  component: ChatRouteLayout,});