Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 0 additions & 1 deletion apps/web/src/components/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4623,7 +4623,6 @@ export default function ChatView({ threadId }: ChatViewProps) {
onToggleDiff={onToggleDiff}
onTogglePreview={() => togglePreviewOpen()}
onTogglePreviewLayout={() => togglePreviewLayout(activeThread.id)}
onToggleCodeViewer={toggleCodeViewer}
/>
</header>

Expand Down
13 changes: 0 additions & 13 deletions apps/web/src/components/chat/ChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Badge } from "../ui/badge";
import ProjectScriptsControl, { type NewProjectScriptInput } from "../ProjectScriptsControl";
import { SidebarTrigger } from "../ui/sidebar";
import { useThreadTitleEditor } from "~/hooks/useThreadTitleEditor";
import { useCodeViewerStore } from "~/codeViewerStore";
import { useProjectColor } from "~/projectColors";
import { useTheme } from "~/hooks/useTheme";
import type { ClientMode } from "~/lib/clientMode";
Expand Down Expand Up @@ -51,7 +50,6 @@ interface ChatHeaderProps {
onToggleDiff: () => void;
onTogglePreview: () => void;
onTogglePreviewLayout: () => void;
onToggleCodeViewer: () => void;
}

export const ChatHeader = memo(function ChatHeader({
Expand Down Expand Up @@ -86,11 +84,8 @@ export const ChatHeader = memo(function ChatHeader({
onToggleDiff,
onTogglePreview,
onTogglePreviewLayout: _onTogglePreviewLayout,
onToggleCodeViewer,
}: ChatHeaderProps) {
const isMobileCompanion = clientMode === "mobile";
const codeViewerOpen = useCodeViewerStore((state) => state.isOpen);
const hasCodeViewerTabs = useCodeViewerStore((state) => state.tabs.length > 0);
const projectColor = useProjectColor(activeProjectId);
const { resolvedTheme } = useTheme();
const isDark = resolvedTheme === "dark";
Expand Down Expand Up @@ -186,13 +181,9 @@ export const ChatHeader = memo(function ChatHeader({
diffOpen={diffOpen}
diffToggleShortcutLabel={diffToggleShortcutLabel}
isGitRepo={isGitRepo}
codeViewerOpen={codeViewerOpen}
hasCodeViewerTabs={hasCodeViewerTabs}
hasProject={activeProjectName !== undefined}
onToggleTerminal={onToggleTerminal}
onTogglePreview={onTogglePreview}
onToggleDiff={onToggleDiff}
onToggleCodeViewer={onToggleCodeViewer}
/>
)}
{/* Mobile: only diff toggle */}
Expand All @@ -206,13 +197,9 @@ export const ChatHeader = memo(function ChatHeader({
diffOpen={diffOpen}
diffToggleShortcutLabel={diffToggleShortcutLabel}
isGitRepo={isGitRepo}
codeViewerOpen={false}
hasCodeViewerTabs={false}
hasProject={false}
onToggleTerminal={() => {}}
onTogglePreview={() => {}}
onToggleDiff={onToggleDiff}
onToggleCodeViewer={() => {}}
/>
)}
</div>
Expand Down
143 changes: 62 additions & 81 deletions apps/web/src/components/chat/HeaderPanelsMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { memo } from "react";
import { memo, useMemo } from "react";
import {
DiffIcon,
EllipsisIcon,
FileCodeIcon,
MonitorIcon,
TerminalSquareIcon,
} from "lucide-react";
import { Button } from "../ui/button";
import { Menu, MenuCheckboxItem, MenuPopup, MenuSeparator, MenuTrigger } from "../ui/menu";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { ToggleGroup, Toggle, ToggleGroupSeparator } from "../ui/toggle-group";

interface HeaderPanelsMenuProps {
terminalAvailable: boolean;
Expand All @@ -19,13 +16,9 @@ interface HeaderPanelsMenuProps {
diffOpen: boolean;
diffToggleShortcutLabel: string | null;
isGitRepo: boolean;
codeViewerOpen: boolean;
hasCodeViewerTabs: boolean;
hasProject: boolean;
onToggleTerminal: () => void;
onTogglePreview: () => void;
onToggleDiff: () => void;
onToggleCodeViewer: () => void;
}

export const HeaderPanelsMenu = memo(function HeaderPanelsMenu({
Expand All @@ -37,88 +30,76 @@ export const HeaderPanelsMenu = memo(function HeaderPanelsMenu({
diffOpen,
diffToggleShortcutLabel,
isGitRepo,
codeViewerOpen,
hasCodeViewerTabs,
hasProject,
onToggleTerminal,
onTogglePreview,
onToggleDiff,
onToggleCodeViewer,
}: HeaderPanelsMenuProps) {
const value = useMemo(() => {
const v: string[] = [];
if (terminalOpen) v.push("terminal");
if (previewOpen) v.push("preview");
if (diffOpen) v.push("diff");
return v;
}, [terminalOpen, previewOpen, diffOpen]);

return (
<Menu>
<ToggleGroup
value={value}
variant="outline"
size="xs"
className="shrink-0"
>
<Tooltip>
<TooltipTrigger
render={
<Toggle
value="terminal"
disabled={!terminalAvailable}
onClick={onToggleTerminal}
aria-label="Toggle terminal"
>
<TerminalSquareIcon className="size-3.5" />
</Toggle>
}
/>
<TooltipPopup side="bottom">
Terminal{terminalToggleShortcutLabel ? ` ${terminalToggleShortcutLabel}` : ""}
</TooltipPopup>
</Tooltip>
<ToggleGroupSeparator />
<Tooltip>
<TooltipTrigger
render={
<Toggle
value="preview"
disabled={!previewAvailable}
onClick={onTogglePreview}
aria-label="Toggle preview"
>
<MonitorIcon className="size-3.5" />
</Toggle>
}
/>
<TooltipPopup side="bottom">Preview</TooltipPopup>
</Tooltip>
<ToggleGroupSeparator />
<Tooltip>
<TooltipTrigger
render={
<MenuTrigger
render={
<Button variant="outline" size="xs" className="shrink-0" aria-label="Toggle panels">
<EllipsisIcon className="size-3.5" />
</Button>
}
/>
<Toggle
value="diff"
disabled={!isGitRepo}
onClick={onToggleDiff}
aria-label="Toggle diff"
>
<DiffIcon className="size-3.5" />
</Toggle>
}
/>
<TooltipPopup side="bottom">Panels</TooltipPopup>
<TooltipPopup side="bottom">
Diff{diffToggleShortcutLabel ? ` ${diffToggleShortcutLabel}` : ""}
</TooltipPopup>
</Tooltip>
<MenuPopup side="bottom" align="end" sideOffset={6}>
<MenuCheckboxItem
checked={terminalOpen}
onCheckedChange={onToggleTerminal}
disabled={!terminalAvailable}
variant="switch"
>
<span className="inline-flex items-center gap-2">
<TerminalSquareIcon className="size-3.5 opacity-80" />
Terminal
{terminalToggleShortcutLabel ? (
<kbd className="ml-auto text-[10px] text-muted-foreground">
{terminalToggleShortcutLabel}
</kbd>
) : null}
</span>
</MenuCheckboxItem>
<MenuCheckboxItem
checked={previewOpen}
onCheckedChange={onTogglePreview}
disabled={!previewAvailable}
variant="switch"
>
<span className="inline-flex items-center gap-2">
<MonitorIcon className="size-3.5 opacity-80" />
Preview
</span>
</MenuCheckboxItem>
<MenuSeparator />
<MenuCheckboxItem
checked={diffOpen}
onCheckedChange={onToggleDiff}
disabled={!isGitRepo}
variant="switch"
>
<span className="inline-flex items-center gap-2">
<DiffIcon className="size-3.5 opacity-80" />
Diff
{diffToggleShortcutLabel ? (
<kbd className="ml-auto text-[10px] text-muted-foreground">
{diffToggleShortcutLabel}
</kbd>
) : null}
</span>
</MenuCheckboxItem>
{hasProject && hasCodeViewerTabs ? (
<MenuCheckboxItem
checked={codeViewerOpen}
onCheckedChange={onToggleCodeViewer}
variant="switch"
>
<span className="inline-flex items-center gap-2">
<FileCodeIcon className="size-3.5 opacity-80" />
Code viewer
</span>
</MenuCheckboxItem>
) : null}
</MenuPopup>
</Menu>
</ToggleGroup>
);
});
Loading