perf(history): batch transform drag undo
This commit is contained in:
@@ -5,8 +5,9 @@ import { documentAddArtboardCommand } from "./document";
|
||||
import { historyCommands } from "./history";
|
||||
import { commandIds } from "./ids";
|
||||
import { createCommandRegistry } from "./registry";
|
||||
import { transformCommands } from "./transform";
|
||||
|
||||
const registry = createCommandRegistry([documentAddArtboardCommand, ...historyCommands]);
|
||||
const registry = createCommandRegistry([documentAddArtboardCommand, ...historyCommands, ...transformCommands]);
|
||||
|
||||
describe("history commands", () => {
|
||||
test("records document changes and undoes/redoes them", () => {
|
||||
@@ -26,4 +27,81 @@ describe("history commands", () => {
|
||||
|
||||
expect(store.getState().document.artboards.map((artboard) => artboard.id)).toEqual(["a1"]);
|
||||
});
|
||||
|
||||
test("records one history entry for a transform drag", () => {
|
||||
const store = createAppStore(artboardState(), registry);
|
||||
|
||||
store.dispatch(commandIds.transformBegin, {
|
||||
target: { type: "artboard", id: "a1" },
|
||||
handle: "body",
|
||||
point: { x: 0, y: 0 },
|
||||
initialBounds: { x: 0, y: 0, w: 100, h: 80 },
|
||||
});
|
||||
store.dispatch(commandIds.transformUpdate, { point: { x: 5, y: 10 } });
|
||||
store.dispatch(commandIds.transformUpdate, { point: { x: 10, y: 20 } });
|
||||
store.dispatch(commandIds.transformUpdate, { point: { x: 15, y: 25 } });
|
||||
|
||||
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 15, y: 25, w: 100, h: 80 });
|
||||
expect(store.getState().history.past).toHaveLength(0);
|
||||
|
||||
store.dispatch(commandIds.transformEnd, undefined);
|
||||
|
||||
expect(store.getState().editor.transformSession).toBeUndefined();
|
||||
expect(store.getState().history.past).toHaveLength(1);
|
||||
expect(store.getState().history.past[0]?.document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
||||
expect(store.getState().history.past[0]?.editor.transformSession).toBeUndefined();
|
||||
|
||||
store.dispatch(commandIds.historyUndo, undefined);
|
||||
|
||||
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
||||
expect(store.getState().editor.transformSession).toBeUndefined();
|
||||
expect(store.getState().history.future).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("keeps direct transform bounds edits normally undoable", () => {
|
||||
const store = createAppStore(artboardState(), registry);
|
||||
|
||||
store.dispatch(commandIds.transformSetBounds, { target: { type: "artboard", id: "a1" }, bounds: { x: 12, y: 24, w: 120, h: 90 } });
|
||||
|
||||
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 12, y: 24, w: 120, h: 90 });
|
||||
expect(store.getState().history.past).toHaveLength(1);
|
||||
|
||||
store.dispatch(commandIds.historyUndo, undefined);
|
||||
|
||||
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
||||
});
|
||||
|
||||
test("does not record history for transform update or end without a session", () => {
|
||||
const store = createAppStore(artboardState(), registry);
|
||||
|
||||
store.dispatch(commandIds.transformUpdate, { point: { x: 10, y: 20 } });
|
||||
store.dispatch(commandIds.transformEnd, undefined);
|
||||
|
||||
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
||||
expect(store.getState().history.past).toHaveLength(0);
|
||||
expect(store.getState().history.future).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("does not record history for a transform session with no document update", () => {
|
||||
const store = createAppStore(artboardState(), registry);
|
||||
|
||||
store.dispatch(commandIds.transformBegin, {
|
||||
target: { type: "artboard", id: "a1" },
|
||||
handle: "body",
|
||||
point: { x: 0, y: 0 },
|
||||
initialBounds: { x: 0, y: 0, w: 100, h: 80 },
|
||||
});
|
||||
store.dispatch(commandIds.transformEnd, undefined);
|
||||
|
||||
expect(store.getState().editor.transformSession).toBeUndefined();
|
||||
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
||||
expect(store.getState().history.past).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
function artboardState() {
|
||||
return documentAddArtboardCommand.execute(
|
||||
{ state: createInitialAppState("Test") },
|
||||
{ id: "a1", name: "Artboard", bounds: { x: 0, y: 0, w: 100, h: 80 } },
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user