Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
219 changes: 149 additions & 70 deletions apps/web/src/components/chat/ChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import {
} from "@t3tools/contracts";
import { memo } from "react";
import GitActionsControl from "../GitActionsControl";
import { DiffIcon, TerminalSquareIcon } from "lucide-react";
import { DiffIcon, EllipsisIcon, 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 { useIsMobile } from "~/hooks/useMediaQuery";
import { Button } from "../ui/button";
import { Popover, PopoverPopup, PopoverTrigger } from "../ui/popover";

interface ChatHeaderProps {
activeThreadId: ThreadId;
Expand Down Expand Up @@ -61,6 +64,8 @@ export const ChatHeader = memo(function ChatHeader({
onToggleTerminal,
onToggleDiff,
}: ChatHeaderProps) {
const isMobile = useIsMobile();

return (
<div className="@container/header-actions flex min-w-0 flex-1 items-center gap-2">
<div className="flex min-w-0 flex-1 items-center gap-2 overflow-hidden sm:gap-3">
Expand All @@ -82,75 +87,149 @@ export const ChatHeader = memo(function ChatHeader({
</Badge>
)}
</div>
<div className="flex shrink-0 items-center justify-end gap-2 @3xl/header-actions:gap-3">
{activeProjectScripts && (
<ProjectScriptsControl
scripts={activeProjectScripts}
keybindings={keybindings}
preferredScriptId={preferredScriptId}
onRunScript={onRunProjectScript}
onAddScript={onAddProjectScript}
onUpdateScript={onUpdateProjectScript}
onDeleteScript={onDeleteProjectScript}
/>
)}
{activeProjectName && (
<OpenInPicker
keybindings={keybindings}
availableEditors={availableEditors}
openInCwd={openInCwd}
/>
)}
{activeProjectName && <GitActionsControl gitCwd={gitCwd} activeThreadId={activeThreadId} />}
<Tooltip>
<TooltipTrigger
render={
<Toggle
className="shrink-0"
pressed={terminalOpen}
onPressedChange={onToggleTerminal}
aria-label="Toggle terminal drawer"
variant="outline"
size="xs"
disabled={!terminalAvailable}
>
<TerminalSquareIcon className="size-3" />
</Toggle>
}
/>
<TooltipPopup side="bottom">
{!terminalAvailable
? "Terminal is unavailable until this thread has an active project."
: terminalToggleShortcutLabel
? `Toggle terminal drawer (${terminalToggleShortcutLabel})`
: "Toggle terminal drawer"}
</TooltipPopup>
</Tooltip>
<Tooltip>
<TooltipTrigger
render={
<Toggle
className="shrink-0"
pressed={diffOpen}
onPressedChange={onToggleDiff}
aria-label="Toggle diff panel"
variant="outline"
size="xs"
disabled={!isGitRepo}
>
<DiffIcon className="size-3" />
</Toggle>
}
/>
<TooltipPopup side="bottom">
{!isGitRepo
? "Diff panel is unavailable because this project is not a git repository."
: diffToggleShortcutLabel
? `Toggle diff panel (${diffToggleShortcutLabel})`
: "Toggle diff panel"}
</TooltipPopup>
</Tooltip>
</div>
{isMobile ? (
<Popover>
<PopoverTrigger
render={<Button size="icon-xs" variant="outline" aria-label="More actions" />}
>
<EllipsisIcon aria-hidden="true" className="size-4" />
</PopoverTrigger>
<PopoverPopup side="bottom" align="end" sideOffset={4} className="w-auto">
<div className="flex flex-col gap-3">
<div className="flex items-center justify-between gap-4">
<span className="text-sm text-foreground">Terminal</span>
<Toggle
className="shrink-0"
pressed={terminalOpen}
onPressedChange={onToggleTerminal}
aria-label="Toggle terminal drawer"
variant="outline"
size="xs"
disabled={!terminalAvailable}
>
<TerminalSquareIcon className="size-3" />
</Toggle>
</div>
<div className="flex items-center justify-between gap-4">
<span className="text-sm text-foreground">Diff</span>
<Toggle
className="shrink-0"
pressed={diffOpen}
onPressedChange={onToggleDiff}
aria-label="Toggle diff panel"
variant="outline"
size="xs"
disabled={!isGitRepo}
>
<DiffIcon className="size-3" />
</Toggle>
</div>
{activeProjectName && (
<>
<div className="h-px bg-border" />
<div className="flex items-center gap-2">
<OpenInPicker
keybindings={keybindings}
availableEditors={availableEditors}
openInCwd={openInCwd}
/>
</div>
</>
)}
{activeProjectName && (
<div className="flex items-center gap-2">
<GitActionsControl gitCwd={gitCwd} activeThreadId={activeThreadId} />
</div>
)}
{activeProjectScripts && (
<div className="flex items-center gap-2">
<ProjectScriptsControl
scripts={activeProjectScripts}
keybindings={keybindings}
preferredScriptId={preferredScriptId}
onRunScript={onRunProjectScript}
onAddScript={onAddProjectScript}
onUpdateScript={onUpdateProjectScript}
onDeleteScript={onDeleteProjectScript}
/>
</div>
)}
</div>
</PopoverPopup>
</Popover>
) : (
<div className="flex shrink-0 items-center justify-end gap-2 @3xl/header-actions:gap-3">
{activeProjectScripts && (
<ProjectScriptsControl
scripts={activeProjectScripts}
keybindings={keybindings}
preferredScriptId={preferredScriptId}
onRunScript={onRunProjectScript}
onAddScript={onAddProjectScript}
onUpdateScript={onUpdateProjectScript}
onDeleteScript={onDeleteProjectScript}
/>
)}
{activeProjectName && (
<OpenInPicker
keybindings={keybindings}
availableEditors={availableEditors}
openInCwd={openInCwd}
/>
)}
{activeProjectName && (
<GitActionsControl gitCwd={gitCwd} activeThreadId={activeThreadId} />
)}
<Tooltip>
<TooltipTrigger
render={
<Toggle
className="shrink-0"
pressed={terminalOpen}
onPressedChange={onToggleTerminal}
aria-label="Toggle terminal drawer"
variant="outline"
size="xs"
disabled={!terminalAvailable}
>
<TerminalSquareIcon className="size-3" />
</Toggle>
}
/>
<TooltipPopup side="bottom">
{!terminalAvailable
? "Terminal is unavailable until this thread has an active project."
: terminalToggleShortcutLabel
? `Toggle terminal drawer (${terminalToggleShortcutLabel})`
: "Toggle terminal drawer"}
</TooltipPopup>
</Tooltip>
<Tooltip>
<TooltipTrigger
render={
<Toggle
className="shrink-0"
pressed={diffOpen}
onPressedChange={onToggleDiff}
aria-label="Toggle diff panel"
variant="outline"
size="xs"
disabled={!isGitRepo}
>
<DiffIcon className="size-3" />
</Toggle>
}
/>
<TooltipPopup side="bottom">
{!isGitRepo
? "Diff panel is unavailable because this project is not a git repository."
: diffToggleShortcutLabel
? `Toggle diff panel (${diffToggleShortcutLabel})`
: "Toggle diff panel"}
</TooltipPopup>
</Tooltip>
</div>
)}
</div>
);
});
Loading