Skip to content
Merged
14 changes: 14 additions & 0 deletions apps/mobile/src/features/files/fileTree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,17 @@ describe("mobile file tree helpers", () => {
expect([...defaultExpandedTreePaths(tree)]).toEqual(["src"]);
});
});

it("flattens a wide expanded directory without exceeding argument limits", () => {
const children = Array.from({ length: 200_000 }, (_, index) => ({
path: `root/file-${index}`,
name: `file-${index}`,
kind: "file" as const,
children: [],
}));
const nodes = [{ path: "root", name: "root", kind: "directory" as const, children }];
const rows = flattenFileTree({ nodes, expanded: new Set(["root"]) });
expect(rows).toHaveLength(children.length + 1);
expect(rows[0]).toEqual({ node: nodes[0], depth: 0 });
expect(rows.at(-1)).toEqual({ node: children.at(-1), depth: 1 });
});
8 changes: 4 additions & 4 deletions apps/mobile/src/features/files/fileTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,23 @@ function flattenNode(
const isSearching = searchResultPaths !== null;
const matches = searchResultPaths?.has(node.path) ?? false;
let descendantMatches = false;
const childOutput: VisibleFileTreeNode[] = [];
const start = output.length;
output.push({ node, depth });

if (node.kind === "directory" && (expanded.has(node.path) || isSearching)) {
for (const child of node.children) {
if (flattenNode(childOutput, child, depth + 1, expanded, searchResultPaths)) {
if (flattenNode(output, child, depth + 1, expanded, searchResultPaths)) {
descendantMatches = true;
}
}
}

const visible = !isSearching || matches || descendantMatches;
if (!visible) {
output.length = start;
return false;
}

output.push({ node, depth });
output.push(...childOutput);
return matches || descendantMatches;
}

Expand Down
Loading