refactor(app): implement canvas-based diff rendering

This commit is contained in:
Mohamed Boudra
2026-08-17 21:14:37 +02:00
parent 75adf53893
commit d03cf14703
66 changed files with 6147 additions and 3210 deletions
@@ -84,6 +84,7 @@ export interface PanelState {
// by full uncompressed dir path, so folders default to expanded and new
// folders stay expanded as the diff changes.
diffCollapsedFoldersByWorkspace: Record<string, string[]>;
collapsedFilePathsByWorkspace: Record<string, string[]>;
sidebarWidth: number;
explorerWidth: number;
explorerSortOption: SortOption;
@@ -111,6 +112,7 @@ export interface PanelState {
setExplorerTabForCheckout: (params: ExplorerCheckoutContext & { tab: ExplorerTab }) => void;
setExpandedPathsForWorkspace: (workspaceKey: string, paths: ExpandedPathsUpdate) => void;
setDiffCollapsedFoldersForWorkspace: (workspaceKey: string, dirPaths: string[]) => void;
setCollapsedFilePathsForWorkspace: (workspaceKey: string, paths: string[]) => void;
activateExplorerTabForCheckout: (checkout: ExplorerCheckoutContext) => void;
setSidebarWidth: (width: number) => void;
setExplorerWidth: (width: number) => void;
@@ -147,6 +149,7 @@ export const usePanelStore = create<PanelState>()(
explorerTabByCheckout: {},
expandedPathsByWorkspace: {},
diffCollapsedFoldersByWorkspace: {},
collapsedFilePathsByWorkspace: {},
sidebarWidth: DEFAULT_SIDEBAR_WIDTH,
explorerWidth: DEFAULT_EXPLORER_SIDEBAR_WIDTH,
explorerSortOption: "name",
@@ -280,6 +283,13 @@ export const usePanelStore = create<PanelState>()(
[workspaceKey]: dirPaths,
},
})),
setCollapsedFilePathsForWorkspace: (workspaceKey, paths) =>
set((state) => ({
collapsedFilePathsByWorkspace: {
...state.collapsedFilePathsByWorkspace,
[workspaceKey]: paths,
},
})),
activateExplorerTabForCheckout: (checkout) =>
set((state) => ({
explorerTab: resolveExplorerTabForCheckout({
@@ -307,6 +317,7 @@ export const usePanelStore = create<PanelState>()(
explorerTabByCheckout: state.explorerTabByCheckout,
expandedPathsByWorkspace: state.expandedPathsByWorkspace,
diffCollapsedFoldersByWorkspace: state.diffCollapsedFoldersByWorkspace,
collapsedFilePathsByWorkspace: state.collapsedFilePathsByWorkspace,
sidebarWidth: state.sidebarWidth,
explorerWidth: state.explorerWidth,
explorerSortOption: state.explorerSortOption,
@@ -120,6 +120,15 @@ describe("panel-store migration", () => {
expect(state.diffCollapsedFoldersByWorkspace).toEqual({ ws: ["src/app"] });
});
it("initializes and preserves collapsed diff file paths by workspace", () => {
expect(migratePanelState({}, 14, { isWeb: false }).collapsedFilePathsByWorkspace).toEqual({});
expect(
migratePanelState({ collapsedFilePathsByWorkspace: { ws: ["src/app.ts"] } }, 14, {
isWeb: false,
}).collapsedFilePathsByWorkspace,
).toEqual({ ws: ["src/app.ts"] });
});
it("drops the retired per-file diff expansion state", () => {
const state = migratePanelState({ diffExpandedPathsByWorkspace: { ws: ["src/app.ts"] } }, 13, {
isWeb: false,
@@ -186,6 +186,7 @@ export const PanelPersistedStateSchema = z.strictObject({
// Accepted only so migration can discard the former per-file diff expansion state.
diffExpandedPathsByWorkspace: z.record(z.string(), z.array(z.string())).optional(),
diffCollapsedFoldersByWorkspace: z.record(z.string(), z.array(z.string())).optional(),
collapsedFilePathsByWorkspace: z.record(z.string(), z.array(z.string())).optional(),
sidebarWidth: z.number().optional(),
explorerWidth: z.number().optional(),
explorerSortOption: z.enum(["name", "modified", "size"]).optional(),
@@ -299,6 +300,12 @@ export function migratePanelState(
) {
state.diffCollapsedFoldersByWorkspace = {};
}
if (
typeof state.collapsedFilePathsByWorkspace !== "object" ||
!state.collapsedFilePathsByWorkspace
) {
state.collapsedFilePathsByWorkspace = {};
}
if (typeof state.explorerShowHiddenFiles !== "boolean") {
state.explorerShowHiddenFiles = true;
}