diff --git a/src/components/RightSidebar.tsx b/src/components/RightSidebar.tsx index 0f4bc829a..9be4770b4 100644 --- a/src/components/RightSidebar.tsx +++ b/src/components/RightSidebar.tsx @@ -179,6 +179,9 @@ const RightSidebarComponent: React.FC = ({ // Global tab preference (not per-workspace) const [selectedTab, setSelectedTab] = usePersistedState("right-sidebar-tab", "costs"); + // Trigger for focusing Review panel (preserves hunk selection) + const [focusTrigger, setFocusTrigger] = React.useState(0); + // Notify parent (AIView) of tab changes so it can enable/disable resize functionality React.useEffect(() => { onTabChange?.(selectedTab); @@ -192,13 +195,18 @@ const RightSidebarComponent: React.FC = ({ setSelectedTab("costs"); } else if (matchesKeybind(e, KEYBINDS.REVIEW_TAB)) { e.preventDefault(); - setSelectedTab("review"); + // If already on Review tab, focus the panel + if (selectedTab === "review") { + setFocusTrigger((prev) => prev + 1); + } else { + setSelectedTab("review"); + } } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); - }, [setSelectedTab]); + }, [setSelectedTab, selectedTab]); const usage = useWorkspaceUsage(workspaceId); const [use1M] = use1MContext(); @@ -337,6 +345,7 @@ const RightSidebarComponent: React.FC = ({ workspaceId={workspaceId} workspacePath={workspacePath} onReviewNote={onReviewNote} + focusTrigger={focusTrigger} /> )} diff --git a/src/components/RightSidebar/CodeReview/ReviewPanel.tsx b/src/components/RightSidebar/CodeReview/ReviewPanel.tsx index 01c62a578..88db02985 100644 --- a/src/components/RightSidebar/CodeReview/ReviewPanel.tsx +++ b/src/components/RightSidebar/CodeReview/ReviewPanel.tsx @@ -25,6 +25,8 @@ interface ReviewPanelProps { workspaceId: string; workspacePath: string; onReviewNote?: (note: string) => void; + /** Trigger to focus panel (increment to trigger) */ + focusTrigger?: number; } const PanelContainer = styled.div` @@ -274,7 +276,9 @@ export const ReviewPanel: React.FC = ({ workspaceId, workspacePath, onReviewNote, + focusTrigger, }) => { + const panelRef = useRef(null); const [hunks, setHunks] = useState([]); const [selectedHunkId, setSelectedHunkId] = useState(null); const [isLoadingHunks, setIsLoadingHunks] = useState(true); @@ -322,6 +326,13 @@ export const ReviewPanel: React.FC = ({ includeUncommitted: includeUncommitted, }); + // Focus panel when focusTrigger changes (preserves current hunk selection) + useEffect(() => { + if (focusTrigger && focusTrigger > 0) { + panelRef.current?.focus(); + } + }, [focusTrigger]); + // Load file tree - when workspace, diffBase, or refreshTrigger changes useEffect(() => { let cancelled = false; @@ -633,6 +644,7 @@ export const ReviewPanel: React.FC = ({ return ( setIsPanelFocused(true)} onBlur={() => setIsPanelFocused(false)}