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
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export function DiffPane({ context, workspaceId, onOpenFile }: DiffPaneProps) {
() => new Set(data.collapsedFiles ?? []),
[data.collapsedFiles],
);
const expandedSet = useMemo(
() => new Set(data.expandedFiles ?? []),
[data.expandedFiles],
);

// Stable callback via refs — identity does not churn as collapsedFiles
// updates, so memo'd children can skip re-renders on unrelated toggles.
Expand All @@ -80,6 +84,19 @@ export function DiffPane({ context, workspaceId, onOpenFile }: DiffPaneProps) {
},
[updateData],
);
const setExpanded = useCallback(
(path: string, value: boolean) => {
const current = dataRef.current;
const expanded = current.expandedFiles ?? [];
const has = expanded.includes(path);
if (value === has) return;
const next = value
? [...expanded, path]
: expanded.filter((p) => p !== path);
updateData({ ...current, expandedFiles: next } as PaneViewerData);
},
[updateData],
Comment on lines +87 to +98
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 expandedFiles grows without bound

setExpanded is only ever called with value = true (from handleShowFullDiff), so paths are appended to expandedFiles but never removed. Over a long session with many file navigations, the persisted array accumulates every file the user has ever clicked or expanded. Unlike collapsedFiles, which shrinks when a file is uncollapsed, expandedFiles has no equivalent trim path. The Array.includes check in setExpanded is also O(n) on each call.

Consider pruning stale entries when the changeset changes (e.g., keep only paths that are still in the current files list), or simply mirror the collapsedFiles pattern and allow callers to set value = false to remove entries.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/DiffPane.tsx
Line: 87-98

Comment:
**`expandedFiles` grows without bound**

`setExpanded` is only ever called with `value = true` (from `handleShowFullDiff`), so paths are appended to `expandedFiles` but never removed. Over a long session with many file navigations, the persisted array accumulates every file the user has ever clicked or expanded. Unlike `collapsedFiles`, which shrinks when a file is uncollapsed, `expandedFiles` has no equivalent trim path. The `Array.includes` check in `setExpanded` is also O(n) on each call.

Consider pruning stale entries when the changeset changes (e.g., keep only paths that are still in the current `files` list), or simply mirror the `collapsedFiles` pattern and allow callers to set `value = false` to remove entries.

How can I resolve this? If you propose a fix, please make it concise.

);

if (!isLoading && files.length === 0) {
return (
Expand All @@ -103,6 +120,8 @@ export function DiffPane({ context, workspaceId, onOpenFile }: DiffPaneProps) {
diffStyle={diffStyle}
collapsed={collapsedSet.has(file.path)}
onSetCollapsed={setCollapsed}
expanded={expandedSet.has(file.path)}
onSetExpanded={setExpanded}
viewed={viewedSet.has(file.path)}
onSetViewed={setViewed}
onOpenFile={onOpenFile}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ interface DiffFileEntryProps {
diffStyle: "split" | "unified";
collapsed: boolean;
onSetCollapsed: (path: string, value: boolean) => void;
expanded: boolean;
onSetExpanded: (path: string, value: boolean) => void;
viewed: boolean;
onSetViewed: (path: string, next: boolean) => void;
onOpenFile: (path: string, openInNewTab?: boolean) => void;
Expand All @@ -45,6 +47,8 @@ export const DiffFileEntry = memo(function DiffFileEntry({
diffStyle,
collapsed,
onSetCollapsed,
expanded,
onSetExpanded,
viewed,
onSetViewed,
onOpenFile,
Expand All @@ -55,9 +59,9 @@ export const DiffFileEntry = memo(function DiffFileEntry({
const hasBeenNearRef = useRef(false);
if (isNear) hasBeenNearRef.current = true;

const [showFullDiff, setShowFullDiff] = useState(false);
const [expandUnchanged, setExpandUnchanged] = useState(false);
const reason = deferReason(file);
const showFullDiff = expanded;

const handleToggleCollapsed = useCallback(
() => onSetCollapsed(file.path, !collapsed),
Expand Down Expand Up @@ -90,7 +94,10 @@ export const DiffFileEntry = memo(function DiffFileEntry({
}
onOpenInExternalEditor(file.path);
}, [file.status, file.path, onOpenInExternalEditor, showDeletedFileToast]);
const handleShowFullDiff = useCallback(() => setShowFullDiff(true), []);
const handleShowFullDiff = useCallback(
() => onSetExpanded(file.path, true),
[onSetExpanded, file.path],
);
const handleToggleExpandUnchanged = useCallback(
() => setExpandUnchanged((prev) => !prev),
[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function useWorkspacePaneOpeners({
data: {
path: filePath,
collapsedFiles: [],
expandedFiles: [filePath],
} as DiffPaneData,
},
],
Expand All @@ -42,11 +43,18 @@ export function useWorkspacePaneOpeners({
for (const pane of Object.values(tab.panes)) {
if (pane.kind !== "diff") continue;
const prev = pane.data as DiffPaneData;
const prevExpanded = prev.expandedFiles ?? [];
state.setPaneData({
paneId: pane.id,
data: {
...prev,
path: filePath,
collapsedFiles: (prev.collapsedFiles ?? []).filter(
(p) => p !== filePath,
),
expandedFiles: prevExpanded.includes(filePath)
? prevExpanded
: [...prevExpanded, filePath],
} as PaneViewerData,
});
state.setActiveTab(tab.id);
Expand All @@ -60,6 +68,7 @@ export function useWorkspacePaneOpeners({
data: {
path: filePath,
collapsedFiles: [],
expandedFiles: [filePath],
} as DiffPaneData,
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface DevtoolsPaneData {
export interface DiffPaneData {
path: string;
collapsedFiles: string[];
expandedFiles?: string[];
}

export interface CommentPaneData {
Expand Down
Loading