Prevent restored file trees from crashing desktop startup (#2595)

* fix(explorer): prevent persisted trees from crashing startup

Persisted expansion restored every directory and recursively flattened the resulting tree during render. Limit automatic restoration to five rendered directory levels and flatten iteratively so deep or broad workspaces cannot exhaust the JavaScript stack.

* fix(explorer): preserve expansion changes during restore

Reconcile completed restoration against the current expansion set atomically so folder interactions made while directory requests are in flight are not overwritten.

* fix(explorer): show hidden files before restoration

* fix(explorer): apply directory toggles atomically
This commit is contained in:
Mohamed Boudra
2026-07-29 22:10:51 +08:00
committed by GitHub
parent b897c59e9c
commit 68a215d40c
6 changed files with 536 additions and 160 deletions
+13 -4
View File
@@ -63,6 +63,8 @@ export {
selectPanelVisibility,
};
export type ExpandedPathsUpdate = string[] | ((currentPaths: string[]) => string[]);
export interface PanelState {
// Mobile: React's durable target plus the generation that owns it.
mobilePanel: MobilePanelSelection;
@@ -104,7 +106,7 @@ export interface PanelState {
// File explorer settings actions
setExplorerTab: (tab: ExplorerTab) => void;
setExplorerTabForCheckout: (params: ExplorerCheckoutContext & { tab: ExplorerTab }) => void;
setExpandedPathsForWorkspace: (workspaceKey: string, paths: string[]) => void;
setExpandedPathsForWorkspace: (workspaceKey: string, paths: ExpandedPathsUpdate) => void;
setDiffExpandedPathsForWorkspace: (workspaceKey: string, paths: string[]) => void;
setDiffCollapsedFoldersForWorkspace: (workspaceKey: string, dirPaths: string[]) => void;
activateExplorerTabForCheckout: (checkout: ExplorerCheckoutContext) => void;
@@ -253,9 +255,16 @@ export const usePanelStore = create<PanelState>()(
return nextState;
}),
setExpandedPathsForWorkspace: (workspaceKey, paths) =>
set((state) => ({
expandedPathsByWorkspace: { ...state.expandedPathsByWorkspace, [workspaceKey]: paths },
})),
set((state) => {
const currentPaths = state.expandedPathsByWorkspace[workspaceKey] ?? ["."];
const nextPaths = typeof paths === "function" ? paths(currentPaths) : paths;
return {
expandedPathsByWorkspace: {
...state.expandedPathsByWorkspace,
[workspaceKey]: nextPaths,
},
};
}),
setDiffExpandedPathsForWorkspace: (workspaceKey, paths) =>
set((state) => ({
diffExpandedPathsByWorkspace: {
+1 -1
View File
@@ -285,7 +285,7 @@ export interface ExplorerFile {
modifiedAt: string;
}
interface ExplorerDirectory {
export interface ExplorerDirectory {
path: string;
entries: ExplorerEntry[];
}