diff --git a/packages/app/src/components/file-explorer-pane.tsx b/packages/app/src/components/file-explorer-pane.tsx index 24167c63d..3b5ee22ba 100644 --- a/packages/app/src/components/file-explorer-pane.tsx +++ b/packages/app/src/components/file-explorer-pane.tsx @@ -42,6 +42,7 @@ import { flattenExplorerTree, reconcileRestoredExpandedPaths, restoreExpandedDirectories, + showHiddenFilesAndRestoreExpandedDirectories, type ExplorerTreeRow, } from "@/file-explorer/tree"; import { useWorkspaceFileDragSource } from "@/attachments/use-workspace-file-drag-source"; @@ -375,10 +376,10 @@ export function FileExplorerPane({ toggleExplorerShowHiddenFiles(); return; } - void restoreExpandedDirectories({ + void showHiddenFilesAndRestoreExpandedDirectories({ rootDirectory, persistedExpandedPaths: expandedPaths, - showHiddenFiles: true, + showHiddenFiles: toggleExplorerShowHiddenFiles, requestDirectoryListing: (path) => requestDirectoryListing(path, { recordHistory: false, @@ -392,7 +393,6 @@ export function FileExplorerPane({ restoredExpandedPaths: restoredPaths, }), ); - toggleExplorerShowHiddenFiles(); return null; }); }, [ diff --git a/packages/app/src/file-explorer/tree.test.ts b/packages/app/src/file-explorer/tree.test.ts index 552f687c4..cb8a0b4b0 100644 --- a/packages/app/src/file-explorer/tree.test.ts +++ b/packages/app/src/file-explorer/tree.test.ts @@ -5,6 +5,7 @@ import { flattenExplorerTree, reconcileRestoredExpandedPaths, restoreExpandedDirectories, + showHiddenFilesAndRestoreExpandedDirectories, } from "./tree"; function makeDirectoryEntry(name: string, path: string): ExplorerEntry { @@ -151,4 +152,29 @@ describe("file explorer tree", () => { expect(paths).toEqual([".", "manual"]); }); + + it("shows hidden files before waiting for expanded directories to restore", async () => { + const rootDirectory = { + path: ".", + entries: [makeDirectoryEntry(".hidden", ".hidden")], + }; + let resolveDirectory!: (directory: { path: string; entries: ExplorerEntry[] }) => void; + const directoryListing = new Promise<{ path: string; entries: ExplorerEntry[] }>((resolve) => { + resolveDirectory = resolve; + }); + let hiddenFilesAreShown = false; + + const restoration = showHiddenFilesAndRestoreExpandedDirectories({ + rootDirectory, + persistedExpandedPaths: new Set([".hidden"]), + showHiddenFiles: () => { + hiddenFilesAreShown = true; + }, + requestDirectoryListing: () => directoryListing, + }); + + expect(hiddenFilesAreShown).toBe(true); + resolveDirectory({ path: ".hidden", entries: [] }); + await expect(restoration).resolves.toEqual([".", ".hidden"]); + }); }); diff --git a/packages/app/src/file-explorer/tree.ts b/packages/app/src/file-explorer/tree.ts index b358f981b..8f39a52c6 100644 --- a/packages/app/src/file-explorer/tree.ts +++ b/packages/app/src/file-explorer/tree.ts @@ -23,6 +23,13 @@ interface RestoreExpandedDirectoriesInput { requestDirectoryListing: (path: string) => Promise; } +interface ShowHiddenFilesAndRestoreExpandedDirectoriesInput extends Omit< + RestoreExpandedDirectoriesInput, + "showHiddenFiles" +> { + showHiddenFiles: () => void; +} + interface ReconcileRestoredExpandedPathsInput { persistedExpandedPaths: ReadonlySet; currentExpandedPaths: ReadonlySet; @@ -110,6 +117,21 @@ export async function restoreExpandedDirectories({ return restoredPaths; } +export function showHiddenFilesAndRestoreExpandedDirectories({ + rootDirectory, + persistedExpandedPaths, + showHiddenFiles, + requestDirectoryListing, +}: ShowHiddenFilesAndRestoreExpandedDirectoriesInput): Promise { + showHiddenFiles(); + return restoreExpandedDirectories({ + rootDirectory, + persistedExpandedPaths, + showHiddenFiles: true, + requestDirectoryListing, + }); +} + export function reconcileRestoredExpandedPaths({ persistedExpandedPaths, currentExpandedPaths,