authorgravatar for encriptandost@gmail.comLeonel Rivas <encriptandost@gmail.com> 2026-08-08 14:02:51-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-08 17:02:51-04:00
log89ee692bf0436505d008c1d70215e70836eba4e2
tree4cdc065aa2725df741f2ff3dc7954193cd9b45a7
parenta20923ce463335e89e92f5983d98a180536e8e7d
signature Signed by PGP key B5690EEEBB952194

fix(web): persist diff view mode (#5731)


3 files changed, 36 insertions(+), 3 deletions(-)

apps/web/src/components/DiffPanel.tsx+2-2
......@@ -76,7 +76,6 @@ import { reviewEnvironment } from "../state/review";
7676import { vcsEnvironment } from "../state/vcs";
7777import { buildBaseRefChoices, filterBaseRefChoices } from "../lib/baseRefChoices";
7878
79type DiffRenderMode = "stacked" | "split";
8079type DiffThemeType = "light" | "dark";
8180const AUTOMATIC_BASE_REF = "__automatic_base_ref__";
8281
......@@ -312,7 +311,8 @@ export default function DiffPanel({
312311 const { resolvedTheme } = useTheme();
313312 const settings = useClientSettings();
314313 const [initialGitScope] = useState(initialGitScopeProp);
315 const [diffRenderMode, setDiffRenderMode] = useState<DiffRenderMode>("stacked");
314 const diffRenderMode = useDiffPanelStore((state) => state.diffRenderMode);
315 const setDiffRenderMode = useDiffPanelStore((state) => state.setDiffRenderMode);
316316 const [wordWrap, setWordWrap] = useState(settings.wordWrap);
317317 const [diffIgnoreWhitespace, setDiffIgnoreWhitespace] = useState(settings.diffIgnoreWhitespace);
318318 const [baseRefQuery, setBaseRefQuery] = useState("");
apps/web/src/diffPanelStore.test.ts+27-1
......@@ -7,7 +7,33 @@ import { selectThreadDiffPanelSelection, useDiffPanelStore } from "./diffPanelSt
77const THREAD_REF = scopeThreadRef(EnvironmentId.make("environment-1"), ThreadId.make("thread-1"));
88
99describe("diffPanelStore", () => {
10 beforeEach(() => useDiffPanelStore.setState({ byThreadKey: {}, branchBaseRefByThreadKey: {} }));
10 beforeEach(() =>
11 useDiffPanelStore.setState({
12 byThreadKey: {},
13 branchBaseRefByThreadKey: {},
14 diffRenderMode: "stacked",
15 }),
16 );
17
18 it("keeps the selected render mode in panel and persisted state", async () => {
19 useDiffPanelStore.getState().setDiffRenderMode("split");
20
21 expect(useDiffPanelStore.getState().diffRenderMode).toBe("split");
22 expect(
23 useDiffPanelStore.persist.getOptions().partialize?.(useDiffPanelStore.getState()),
24 ).toMatchObject({ diffRenderMode: "split" });
25
26 const { name, storage } = useDiffPanelStore.persist.getOptions();
27 if (!name) throw new Error("Expected diff panel persistence to have a storage name");
28 const persisted = await storage?.getItem(name);
29 expect(persisted?.state).toMatchObject({ diffRenderMode: "split" });
30
31 useDiffPanelStore.setState({ diffRenderMode: "stacked" });
32 if (persisted) await storage?.setItem(name, persisted);
33 await useDiffPanelStore.persist.rehydrate();
34
35 expect(useDiffPanelStore.getState().diffRenderMode).toBe("split");
36 });
1137
1238 it("defaults each thread to branch changes when the working tree is clean", () => {
1339 expect(
apps/web/src/diffPanelStore.ts+7
......@@ -10,12 +10,16 @@ export type DiffPanelSelection =
1010 | { kind: "unstaged" }
1111 | { kind: "turn"; turnId: TurnId; filePath: string | null; revealRequestId: number };
1212
13export type DiffRenderMode = "stacked" | "split";
14
1315const DEFAULT_SELECTION: DiffPanelSelection = { kind: "branch", baseRef: null };
1416const DEFAULT_WORKING_TREE_SELECTION: DiffPanelSelection = { kind: "unstaged" };
1517
1618interface DiffPanelStoreState {
1719 byThreadKey: Record<string, DiffPanelSelection>;
1820 branchBaseRefByThreadKey: Record<string, string | null>;
21 diffRenderMode: DiffRenderMode;
22 setDiffRenderMode: (mode: DiffRenderMode) => void;
1923 selectGitScope: (ref: ScopedThreadRef, scope: "branch" | "unstaged") => void;
2024 selectBranchBaseRef: (ref: ScopedThreadRef, baseRef: string | null) => void;
2125 selectTurn: (ref: ScopedThreadRef, turnId: TurnId, filePath?: string) => void;
......@@ -33,6 +37,8 @@ export const useDiffPanelStore = create<DiffPanelStoreState>()(
3337 (set) => ({
3438 byThreadKey: {},
3539 branchBaseRefByThreadKey: {},
40 diffRenderMode: "stacked",
41 setDiffRenderMode: (diffRenderMode) => set({ diffRenderMode }),
3642 selectGitScope: (ref, scope) =>
3743 set((state) => {
3844 const threadKey = scopedThreadKey(ref);
......@@ -126,6 +132,7 @@ export const useDiffPanelStore = create<DiffPanelStoreState>()(
126132 partialize: (state) => ({
127133 byThreadKey: state.byThreadKey,
128134 branchBaseRefByThreadKey: state.branchBaseRefByThreadKey,
135 diffRenderMode: state.diffRenderMode,
129136 }),
130137 },
131138 ),