From ccb886730bbea02f1d2012e361e71c4b956773c5 Mon Sep 17 00:00:00 2001 From: Gasim Gasimzada Date: Thu, 9 Jan 2020 12:51:36 +0400 Subject: [PATCH] Make history actions immutable --- src/history.ts | 21 +++++++++++++-------- src/index.tsx | 10 ++++++++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/history.ts b/src/history.ts index 5847c0f0f..6b93e92ac 100644 --- a/src/history.ts +++ b/src/history.ts @@ -22,14 +22,15 @@ class SceneHistory { this.stateHistory.push(newEntry); } - restoreEntry(elements: ExcalidrawElement[], entry: string) { - const newElements = JSON.parse(entry); - elements.splice(0, elements.length); - newElements.forEach((newElement: ExcalidrawElement) => { - elements.push(newElement); - }); + restoreEntry(entry: string) { // When restoring, we shouldn't add an history entry otherwise we'll be stuck with it and can't go back this.skipRecording(); + + try { + return JSON.parse(entry); + } catch { + return null; + } } clearRedoStack() { @@ -40,9 +41,11 @@ class SceneHistory { const currentEntry = this.generateCurrentEntry(elements); const entryToRestore = this.redoStack.pop(); if (entryToRestore !== undefined) { - this.restoreEntry(elements, entryToRestore); this.stateHistory.push(currentEntry); + return this.restoreEntry(entryToRestore); } + + return null; } undoOnce(elements: ExcalidrawElement[]) { @@ -54,9 +57,11 @@ class SceneHistory { entryToRestore = this.stateHistory.pop(); } if (entryToRestore !== undefined) { - this.restoreEntry(elements, entryToRestore); this.redoStack.push(currentEntry); + return this.restoreEntry(entryToRestore); } + + return null; } isRecording() { diff --git a/src/index.tsx b/src/index.tsx index d6295d9c7..dbeb56a6f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -214,10 +214,16 @@ export class App extends React.Component<{}, AppState> { } else if (event[META_KEY] && event.code === "KeyZ") { if (event.shiftKey) { // Redo action - history.redoOnce(elements); + const data = history.redoOnce(elements); + if (data !== null) { + elements = data; + } } else { // undo action - history.undoOnce(elements); + const data = history.undoOnce(elements); + if (data !== null) { + elements = data; + } } this.forceUpdate(); event.preventDefault();