Browse Source

Add app state to history (#309)

* Add app state to history.

* Pick missing state keys.

* Fix bug.

* Remove force update.
Enzo Ferey 5 years ago
parent
commit
dfb7c2b744
2 changed files with 34 additions and 9 deletions
  1. 9 4
      src/history.ts
  2. 25 5
      src/index.tsx

+ 9 - 4
src/history.ts

@@ -1,3 +1,4 @@
+import { AppState } from "./types";
 import { ExcalidrawElement } from "./element/types";
 
 class SceneHistory {
@@ -5,13 +6,17 @@ class SceneHistory {
   private stateHistory: string[] = [];
   private redoStack: string[] = [];
 
-  generateCurrentEntry(elements: readonly ExcalidrawElement[]) {
-    return JSON.stringify(
-      elements.map(({ shape, ...element }) => ({
+  generateCurrentEntry(
+    appState: Partial<AppState>,
+    elements: readonly ExcalidrawElement[]
+  ) {
+    return JSON.stringify({
+      appState,
+      elements: elements.map(({ shape, ...element }) => ({
         ...element,
         isSelected: false
       }))
-    );
+    });
   }
 
   pushEntry(newEntry: string) {

+ 25 - 5
src/index.tsx

@@ -115,6 +115,19 @@ export function viewportCoordsToSceneCoords(
   return { x, y };
 }
 
+function pickAppStatePropertiesForHistory(
+  appState: AppState
+): Partial<AppState> {
+  return {
+    exportBackground: appState.exportBackground,
+    currentItemStrokeColor: appState.currentItemStrokeColor,
+    currentItemBackgroundColor: appState.currentItemBackgroundColor,
+    currentItemFont: appState.currentItemFont,
+    viewBackgroundColor: appState.viewBackgroundColor,
+    name: appState.name
+  };
+}
+
 export class App extends React.Component<any, AppState> {
   canvas: HTMLCanvasElement | null = null;
   rc: RoughCanvas | null = null;
@@ -312,21 +325,23 @@ export class App extends React.Component<any, AppState> {
       }
       this.setState({ elementType: shape });
     } else if (event[KEYS.META] && event.code === "KeyZ") {
+      event.preventDefault();
+
       if (event.shiftKey) {
         // Redo action
         const data = history.redoOnce();
         if (data !== null) {
-          elements = data;
+          elements = data.elements;
+          this.setState(data.appState);
         }
       } else {
         // undo action
         const data = history.undoOnce();
         if (data !== null) {
-          elements = data;
+          elements = data.elements;
+          this.setState(data.appState);
         }
       }
-      this.forceUpdate();
-      event.preventDefault();
     }
   };
 
@@ -1387,7 +1402,12 @@ export class App extends React.Component<any, AppState> {
     });
     this.saveDebounced();
     if (history.isRecording()) {
-      history.pushEntry(history.generateCurrentEntry(elements));
+      history.pushEntry(
+        history.generateCurrentEntry(
+          pickAppStatePropertiesForHistory(this.state),
+          elements
+        )
+      );
     }
   }
 }