Skip to content

Commit cfb38ed

Browse files
committed
fix(web): make the panel maximize shortcut work
1 parent 9bd1d80 commit cfb38ed

5 files changed

Lines changed: 64 additions & 1 deletion

File tree

‎apps/web/src/components/ChatView.tsx‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ import { addBrowserSurface } from "./preview/addBrowserSurface";
260260
import { closePreviewSession } from "./preview/closePreviewSession";
261261
import { ThreadPreviewMiniPlayer } from "./preview/ThreadPreviewMiniPlayer";
262262
import { subscribePreviewAction } from "./preview/previewActionBus";
263+
import { onToggleRightPanelMaximized } from "../rightPanelActionBus";
263264
import { getConfiguredPreviewUrls } from "./preview/previewEmptyStateLogic";
264265

265266
import {
@@ -5821,6 +5822,10 @@ export default function ChatView(props: ChatViewProps) {
58215822
threadKey === routeThreadKey ? null : routeThreadKey,
58225823
);
58235824
}, [canMaximizeRightPanel, routeThreadKey]);
5825+
useEffect(
5826+
() => onToggleRightPanelMaximized(toggleRightPanelMaximized),
5827+
[toggleRightPanelMaximized],
5828+
);
58245829
const cleanupRightPanelSurfaces = useCallback(
58255830
(surfaces: readonly RightPanelSurface[]) => {
58265831
if (!activeThreadRef) return;
@@ -7824,6 +7829,13 @@ export default function ChatView(props: ChatViewProps) {
78247829
return;
78257830
}
78267831

7832+
if (command === "rightPanel.toggleMaximized") {
7833+
event.preventDefault();
7834+
event.stopPropagation();
7835+
if (!event.repeat) toggleRightPanelMaximized();
7836+
return;
7837+
}
7838+
78277839
if (command === "rightPanel.close") {
78287840
// Nothing open: leave the event alone so the shortcut keeps its
78297841
// native meaning (close window on desktop, close tab in a browser).
@@ -8015,6 +8027,7 @@ export default function ChatView(props: ChatViewProps) {
80158027
copyActiveThreadReference,
80168028
getShortcutContext,
80178029
toggleRightPanel,
8030+
toggleRightPanelMaximized,
80188031
toggleThreadPanel,
80198032
toggleTerminalVisibility,
80208033
composerRef,
@@ -10863,6 +10876,7 @@ export default function ChatView(props: ChatViewProps) {
1086310876
>
1086410877
<RightPanelMaximizeControl
1086510878
maximized={rightPanelMaximized}
10879+
shortcutLabel={shortcutLabelForCommand(keybindings, "rightPanel.toggleMaximized")}
1086610880
onToggle={toggleRightPanelMaximized}
1086710881
/>
1086810882
</span>

‎apps/web/src/components/CommandPalette.tsx‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
FolderPlusIcon,
5656
MessageSquareDashedIcon,
5757
LinkIcon,
58+
Maximize2Icon,
5859
MessageSquareIcon,
5960
MonitorIcon,
6061
MoonIcon,
@@ -125,11 +126,15 @@ import {
125126
resolveProjectPathForDispatch,
126127
} from "../lib/projectPaths";
127128
import { onOpenCommandPalette } from "../commandPaletteBus";
129+
import { useMediaQuery } from "../hooks/useMediaQuery";
130+
import { RIGHT_PANEL_INLINE_LAYOUT_MEDIA_QUERY } from "../rightPanelLayout";
131+
import { dispatchToggleRightPanelMaximized } from "../rightPanelActionBus";
128132
import { isPreviewFocused } from "../lib/previewFocus";
129133
import { isTerminalFocused } from "../lib/terminalFocus";
130134
import {
131135
PULL_REQUESTS_PANEL_REF,
132136
selectActiveRightPanel,
137+
selectThreadRightPanelState,
133138
useRightPanelStore,
134139
} from "../rightPanelStore";
135140
import { getLatestThreadForProject, sortThreads } from "../lib/threadSort";
@@ -739,6 +744,15 @@ function OpenCommandPaletteDialog(props: {
739744
const availableSettingsSearchItems = useAvailableSettingsSearchItems();
740745
const { activeDraftThread, activeThread, defaultProjectRef, handleNewThread } =
741746
useHandleNewThread();
747+
const panelThreadRef = activeThread
748+
? scopeThreadRef(activeThread.environmentId, activeThread.id)
749+
: activeDraftThread
750+
? scopeThreadRef(activeDraftThread.environmentId, activeDraftThread.threadId)
751+
: null;
752+
const rightPanelOpen = useRightPanelStore(
753+
(state) => selectThreadRightPanelState(state.byThreadKey, panelThreadRef).isOpen,
754+
);
755+
const rightPanelUsesSheet = useMediaQuery(RIGHT_PANEL_INLINE_LAYOUT_MEDIA_QUERY);
742756
const projects = useProjects();
743757
const referenceThreadRef =
744758
pathname === "/pull-requests"
@@ -1880,6 +1894,20 @@ function OpenCommandPaletteDialog(props: {
18801894

18811895
const actionItems: Array<CommandPaletteActionItem | CommandPaletteSubmenuItem> = [];
18821896

1897+
if (panelThreadRef !== null && rightPanelOpen && !rightPanelUsesSheet) {
1898+
actionItems.push({
1899+
kind: "action",
1900+
value: "action:toggle-right-panel-maximized",
1901+
searchTerms: ["maximize", "restore", "panel", "size", "expand"],
1902+
title: "Toggle right panel maximized",
1903+
icon: <Maximize2Icon className={ITEM_ICON_CLASS} />,
1904+
shortcutCommand: "rightPanel.toggleMaximized",
1905+
run: async () => {
1906+
dispatchToggleRightPanelMaximized();
1907+
},
1908+
});
1909+
}
1910+
18831911
if (projects.length > 0) {
18841912
const activeProjectTitle =
18851913
projectPickerEntries.find((entry) => entry.isPreferred)?.group.displayName ??

‎apps/web/src/components/chat/PanelLayoutControls.tsx‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,11 @@ export const PanelLayoutControls = memo(function PanelLayoutControls({
141141

142142
export const RightPanelMaximizeControl = memo(function RightPanelMaximizeControl({
143143
maximized,
144+
shortcutLabel,
144145
onToggle,
145146
}: {
146147
maximized: boolean;
148+
shortcutLabel: string | null;
147149
onToggle: () => void;
148150
}) {
149151
const label = maximized ? "Restore panel size" : "Maximize panel";
@@ -163,7 +165,10 @@ export const RightPanelMaximizeControl = memo(function RightPanelMaximizeControl
163165
</Toggle>
164166
}
165167
/>
166-
<TooltipPopup side="bottom">{label}</TooltipPopup>
168+
<TooltipPopup side="bottom">
169+
{label}
170+
{shortcutLabel ? ` (${shortcutLabel})` : ""}
171+
</TooltipPopup>
167172
</Tooltip>
168173
);
169174
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/** Lets the command palette reach the chat view's panel layout handler. */
2+
const TOGGLE_MAXIMIZED_EVENT = "t3code:toggle-right-panel-maximized";
3+
4+
export function dispatchToggleRightPanelMaximized(): void {
5+
window.dispatchEvent(new Event(TOGGLE_MAXIMIZED_EVENT));
6+
}
7+
8+
export function onToggleRightPanelMaximized(listener: () => void): () => void {
9+
window.addEventListener(TOGGLE_MAXIMIZED_EVENT, listener);
10+
return () => window.removeEventListener(TOGGLE_MAXIMIZED_EVENT, listener);
11+
}

‎docs/user/keybindings.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ a shortcut.
120120

121121
## Commands with special behavior
122122

123+
Assign `rightPanel.toggleMaximized` in **Settings → Keybindings** to maximize or
124+
restore the open right panel. It has no default shortcut and is also available
125+
in the command palette. It does nothing when the panel is closed or displayed
126+
as a sheet on a narrow screen.
127+
123128
`thread.stop` interrupts the running turn in the focused thread. It has no default
124129
shortcut; assign one in **Settings → Keybindings**.
125130

0 commit comments

Comments
 (0)