fix(vcs): remember the diff window's size between openings (#2328) (#2353)

The modal-commit diff dialog always reopened at its default 1100x720.
Pass the persisted size as the dialog's initialSize and save it when a
resize ends, like the Find in Files popup already does.
Цей коміт міститься в:
arookieofc authored and GitHub committed 2026-11-09 20:14:28 +08:00
1 джерело 039ec09122
коміт bb8c9fa0b4
2 files changed
+53 -2

No files matched your search

+23 -1
Переглянути файл
@@ -23,7 +23,7 @@ import { ChangesTree, nodeMenu } from "../CommitView";
import type { ChangeNode } from "../changes";
import { VcsDialogHost } from "../dialogs";
import { useVcs } from "../store";
import { openDiffDialog } from "../diffDialog";
import { loadDiffDialogSize, openDiffDialog } from "../diffDialog";
const modified = (path: string) => ({
path,
@@ -116,6 +116,28 @@ describe("Commit dialog diff window (#1863)", () => {
await screen.findByRole("dialog", { name: "b.ts (HEAD ↔ Your version)" });
});
it("remembers the resized size for the next opening (#2328)", async () => {
render(<VcsDialogHost />);
let close: () => void = () => {};
act(() => {
close = openDiffDialog({ path: "/p/a.ts", left: { type: "rev", rev: "HEAD" }, right: { type: "worktree" } });
});
await diffDialogs();
// Drag the corner grip; jsdom reports a zero rect so the dialog clamps to its
// minimums — what matters is that the resize end is persisted.
fireEvent.pointerDown(screen.getByRole("separator", { name: "Resize" }), { button: 0, clientX: 0, clientY: 0 });
fireEvent.pointerMove(window, { buttons: 1, clientX: 100, clientY: 80 });
fireEvent.pointerUp(window);
expect(loadDiffDialogSize()).toEqual({ w: 480, h: 280 });
act(() => close());
// A fresh open starts at the remembered size rather than the default.
act(() => {
close = openDiffDialog({ path: "/p/a.ts", left: { type: "rev", rev: "HEAD" }, right: { type: "worktree" } });
});
const reopened = await diffDialogs();
expect([reopened.style.width, reopened.style.height]).toEqual(["480px", "280px"]);
});
it("closes on Jump to Source so the editor it opens is not hidden behind it", async () => {
render(
<>
+30 -1
Переглянути файл
@@ -15,6 +15,26 @@ import { diffInput, diffTitle, type DiffData } from "./diffInput";
import { openDialog } from "./dialogs";
import { GitMergeDiff } from "./GitMergeDiff";
const SIZE_KEY = "openidea.vcs.diffDialogSize";
/** The diff window's last size (#2328); null on first run, clamped to the window by Dialog. */
export function loadDiffDialogSize(): { w: number; h: number } | null {
try {
const v = JSON.parse(localStorage.getItem(SIZE_KEY) ?? "null") as { w?: unknown; h?: unknown } | null;
return typeof v?.w === "number" && typeof v.h === "number" ? { w: v.w, h: v.h } : null;
} catch {
return null;
}
}
export function saveDiffDialogSize(size: { w: number; h: number }) {
try {
localStorage.setItem(SIZE_KEY, JSON.stringify(size));
} catch {
// Private mode etc. — the size just isn't remembered.
}
}
/** The open diff dialog's close function (one diff window at a time, as in IDEA). */
let shown: (() => void) | null = null;
@@ -52,6 +72,14 @@ export function openMergeDiffDialog(input: EditorInput): () => void {
function FrontWindow({ title, onClose, children }: { title: string; onClose: () => void; children: ReactNode }) {
const body = useRef<HTMLDivElement>(null);
// The size the user last resized the diff window to (#2328), else the usual default.
const [initialSize] = useState(
() =>
loadDiffDialogSize() ?? {
w: Math.min(1100, globalThis.innerWidth - 64),
h: Math.min(720, globalThis.innerHeight - 64),
},
);
useEffect(
() =>
registerKeyClaim((e, stroke) => {
@@ -74,7 +102,8 @@ function FrontWindow({ title, onClose, children }: { title: string; onClose: ()
resizable="both"
minWidth={480}
minHeight={280}
initialSize={{ w: Math.min(1100, globalThis.innerWidth - 64), h: Math.min(720, globalThis.innerHeight - 64) }}
initialSize={initialSize}
onResized={saveDiffDialogSize}
buttons={[{ label: "Close", role: "cancel" }]}
>
<div