import { type EnvironmentId, type EditorId, type ProjectScript, type ResolvedKeybindingsConfig, type ThreadId, } from "@t3tools/contracts"; import { scopeThreadRef } from "@t3tools/client-runtime"; import { memo } from "react"; import GitActionsControl from "../GitActionsControl"; import { type DraftId } from "~/composerDraftStore"; import { DiffIcon, TerminalSquareIcon } from "lucide-react"; import { Badge } from "../ui/badge"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; import ProjectScriptsControl, { type NewProjectScriptInput } from "../ProjectScriptsControl"; import { Toggle } from "../ui/toggle"; import { SidebarTrigger } from "../ui/sidebar"; import { OpenInPicker } from "./OpenInPicker"; import { usePrimaryEnvironmentId } from "../../environments/primary"; interface ChatHeaderProps { activeThreadEnvironmentId: EnvironmentId; activeThreadId: ThreadId; draftId?: DraftId; activeThreadTitle: string; activeProjectName: string | undefined; isGitRepo: boolean; openInCwd: string | null; activeProjectScripts: ProjectScript[] | undefined; preferredScriptId: string | null; keybindings: ResolvedKeybindingsConfig; availableEditors: ReadonlyArray; terminalAvailable: boolean; terminalOpen: boolean; terminalToggleShortcutLabel: string | null; diffToggleShortcutLabel: string | null; gitCwd: string | null; diffOpen: boolean; onRunProjectScript: (script: ProjectScript) => void; onAddProjectScript: (input: NewProjectScriptInput) => Promise; onUpdateProjectScript: (scriptId: string, input: NewProjectScriptInput) => Promise; onDeleteProjectScript: (scriptId: string) => Promise; onToggleTerminal: () => void; onToggleDiff: () => void; } export function shouldShowOpenInPicker(input: { readonly activeProjectName: string | undefined; readonly activeThreadEnvironmentId: EnvironmentId; readonly primaryEnvironmentId: EnvironmentId | null; }): boolean { return ( Boolean(input.activeProjectName) && input.primaryEnvironmentId !== null && input.activeThreadEnvironmentId === input.primaryEnvironmentId ); } export const ChatHeader = memo(function ChatHeader({ activeThreadEnvironmentId, activeThreadId, draftId, activeThreadTitle, activeProjectName, isGitRepo, openInCwd, activeProjectScripts, preferredScriptId, keybindings, availableEditors, terminalAvailable, terminalOpen, terminalToggleShortcutLabel, diffToggleShortcutLabel, gitCwd, diffOpen, onRunProjectScript, onAddProjectScript, onUpdateProjectScript, onDeleteProjectScript, onToggleTerminal, onToggleDiff, }: ChatHeaderProps) { const primaryEnvironmentId = usePrimaryEnvironmentId(); const showOpenInPicker = shouldShowOpenInPicker({ activeProjectName, activeThreadEnvironmentId, primaryEnvironmentId, }); return (

{activeThreadTitle}

{activeProjectName && ( {activeProjectName} )} {activeProjectName && !isGitRepo && ( No Git )}
{activeProjectScripts && ( )} {showOpenInPicker && ( )} {activeProjectName && ( )} } /> {!terminalAvailable ? "Terminal is unavailable until this thread has an active project." : terminalToggleShortcutLabel ? `Toggle terminal drawer (${terminalToggleShortcutLabel})` : "Toggle terminal drawer"} } /> {!isGitRepo && !diffOpen ? "Diff panel is unavailable because this project is not a git repository." : diffToggleShortcutLabel ? `Toggle diff panel (${diffToggleShortcutLabel})` : "Toggle diff panel"}
); });