Skip to content

Commit ed0066f

Browse files
committed
fix: make Expand All truly recursive
Previously only collected directories from already-loaded entries. Now recursively fetches each directory level before expanding children, ensuring all nested directories are expanded.
1 parent 95f99bd commit ed0066f

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

src/browser/components/RightSidebar/ExplorerTab.tsx

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ export const ExplorerTab: React.FC<ExplorerTabProps> = (props) => {
5252
// Track if we've done initial load
5353
const initialLoadRef = React.useRef(false);
5454

55-
// Fetch a directory's contents
55+
// Fetch a directory's contents and return the entries (for recursive expand)
5656
const fetchDirectory = React.useCallback(
57-
async (relativePath: string) => {
57+
async (relativePath: string): Promise<FileTreeNode[] | null> => {
5858
const key = relativePath || "__root__";
5959

6060
setState((prev) => ({
@@ -64,7 +64,7 @@ export const ExplorerTab: React.FC<ExplorerTabProps> = (props) => {
6464
}));
6565

6666
try {
67-
if (!api) return;
67+
if (!api) return null;
6868
const result = await api.general.listWorkspaceDirectory({
6969
workspacePath: props.workspacePath,
7070
relativePath: relativePath || undefined,
@@ -76,7 +76,7 @@ export const ExplorerTab: React.FC<ExplorerTabProps> = (props) => {
7676
loading: new Set([...prev.loading].filter((k) => k !== key)),
7777
error: result.error,
7878
}));
79-
return;
79+
return null;
8080
}
8181

8282
setState((prev) => {
@@ -88,12 +88,15 @@ export const ExplorerTab: React.FC<ExplorerTabProps> = (props) => {
8888
loading: new Set([...prev.loading].filter((k) => k !== key)),
8989
};
9090
});
91+
92+
return result.data;
9193
} catch (err) {
9294
setState((prev) => ({
9395
...prev,
9496
loading: new Set([...prev.loading].filter((k) => k !== key)),
9597
error: err instanceof Error ? err.message : String(err),
9698
}));
99+
return null;
97100
}
98101
},
99102
[api, props.workspacePath]
@@ -166,29 +169,38 @@ export const ExplorerTab: React.FC<ExplorerTabProps> = (props) => {
166169
};
167170

168171
// Expand all recursively (skip gitignored directories)
169-
const handleExpandAll = () => {
170-
// Collect all known non-ignored directories from loaded entries
172+
const handleExpandAll = async () => {
171173
const allDirs: string[] = [];
174+
const entriesCache = new Map(state.entries);
175+
176+
// Recursively fetch and collect all non-ignored directories
177+
const expandRecursively = async (parentKey: string): Promise<void> => {
178+
let entries = entriesCache.get(parentKey);
179+
180+
// Fetch if not in cache
181+
if (!entries) {
182+
const fetched = await fetchDirectory(parentKey === "__root__" ? "" : parentKey);
183+
if (fetched) {
184+
entries = fetched;
185+
entriesCache.set(parentKey, entries);
186+
}
187+
}
172188

173-
const collectDirs = (parentKey: string) => {
174-
const entries = state.entries.get(parentKey);
175189
if (!entries) return;
190+
191+
// Process children in parallel
192+
const childPromises: Array<Promise<void>> = [];
176193
for (const entry of entries) {
177194
if (entry.isDirectory && !entry.ignored) {
178195
allDirs.push(entry.path);
179-
collectDirs(entry.path);
196+
childPromises.push(expandRecursively(entry.path));
180197
}
181198
}
182-
};
183199

184-
collectDirs("__root__");
200+
await Promise.all(childPromises);
201+
};
185202

186-
// Fetch any directories not yet loaded
187-
for (const dir of allDirs) {
188-
if (!state.entries.has(dir)) {
189-
void fetchDirectory(dir);
190-
}
191-
}
203+
await expandRecursively("__root__");
192204

193205
setState((prev) => ({
194206
...prev,

0 commit comments

Comments
 (0)