From 4624ec2bd6ac9275b65fa158f0b019177ca6e283 Mon Sep 17 00:00:00 2001
From: Aakansha Doshi <aakansha1216@gmail.com>
Date: Fri, 29 Jan 2021 23:38:37 +0530
Subject: [PATCH] fix: apply initialData appState for zenmode and grid stats
 and refactor check param for actions (#2871)

* fix: pass default value for grid mode / zen mode so it sets the value from initialData appState

fixes #2870

* change checked from boolean to be a function which recieves appState and returns boolean

* fix

* use clsx

Co-authored-by: dwelle <luzar.david@gmail.com>
---
 src/actions/actionToggleGridMode.tsx |  7 +++----
 src/actions/actionToggleStats.tsx    |  5 ++---
 src/actions/actionToggleZenMode.tsx  |  9 ++++-----
 src/actions/types.ts                 |  2 +-
 src/components/App.tsx               |  3 ++-
 src/components/ContextMenu.tsx       | 13 +++++++++----
 6 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/src/actions/actionToggleGridMode.tsx b/src/actions/actionToggleGridMode.tsx
index 22e8e558..e99e3a01 100644
--- a/src/actions/actionToggleGridMode.tsx
+++ b/src/actions/actionToggleGridMode.tsx
@@ -1,21 +1,20 @@
 import { CODES, KEYS } from "../keys";
 import { register } from "./register";
 import { GRID_SIZE } from "../constants";
+import { AppState } from "../types";
 
 export const actionToggleGridMode = register({
   name: "gridMode",
   perform(elements, appState) {
-    this.checked = !this.checked;
     return {
       appState: {
         ...appState,
-        gridSize: this.checked ? GRID_SIZE : null,
+        gridSize: this.checked!(appState) ? null : GRID_SIZE,
       },
       commitToHistory: false,
     };
   },
-  checked: false,
+  checked: (appState: AppState) => appState.gridSize !== null,
   contextItemLabel: "labels.gridMode",
-  // Wrong event code
   keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.code === CODES.QUOTE,
 });
diff --git a/src/actions/actionToggleStats.tsx b/src/actions/actionToggleStats.tsx
index 1d75caf8..3c03b80c 100644
--- a/src/actions/actionToggleStats.tsx
+++ b/src/actions/actionToggleStats.tsx
@@ -3,15 +3,14 @@ import { register } from "./register";
 export const actionToggleStats = register({
   name: "stats",
   perform(elements, appState) {
-    this.checked = !this.checked;
     return {
       appState: {
         ...appState,
-        showStats: !appState.showStats,
+        showStats: !this.checked!(appState),
       },
       commitToHistory: false,
     };
   },
-  checked: false,
+  checked: (appState) => appState.showStats,
   contextItemLabel: "stats.title",
 });
diff --git a/src/actions/actionToggleZenMode.tsx b/src/actions/actionToggleZenMode.tsx
index 32ddd6fe..38da9cde 100644
--- a/src/actions/actionToggleZenMode.tsx
+++ b/src/actions/actionToggleZenMode.tsx
@@ -4,17 +4,16 @@ import { register } from "./register";
 export const actionToggleZenMode = register({
   name: "zenMode",
   perform(elements, appState) {
-    this.checked = !this.checked;
     return {
       appState: {
         ...appState,
-        zenModeEnabled: this.checked,
+        zenModeEnabled: !this.checked!(appState),
       },
       commitToHistory: false,
     };
   },
-  checked: false,
+  checked: (appState) => appState.zenModeEnabled,
   contextItemLabel: "buttons.zenMode",
-  // Wrong event code
-  keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.code === CODES.QUOTE,
+  keyTest: (event) =>
+    !event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === CODES.Z,
 });
diff --git a/src/actions/types.ts b/src/actions/types.ts
index 6d373faa..66f8dece 100644
--- a/src/actions/types.ts
+++ b/src/actions/types.ts
@@ -106,7 +106,7 @@ export interface Action {
     elements: readonly ExcalidrawElement[],
     appState: AppState,
   ) => boolean;
-  checked?: boolean;
+  checked?: (appState: Readonly<AppState>) => boolean;
 }
 
 export interface ActionsManagerInterface {
diff --git a/src/components/App.tsx b/src/components/App.tsx
index c8e321be..795d2def 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -1254,7 +1254,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
     if (!event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === CODES.Z) {
       this.toggleZenMode();
     }
-
     if (event[KEYS.CTRL_OR_CMD] && event.code === CODES.QUOTE) {
       this.toggleGridMode();
     }
@@ -3663,6 +3662,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
         top: clientY,
         left: clientX,
         actionManager: this.actionManager,
+        appState: this.state,
       });
       return;
     }
@@ -3709,6 +3709,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
       top: clientY,
       left: clientX,
       actionManager: this.actionManager,
+      appState: this.state,
     });
   };
 
diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx
index 567d9dd4..17556665 100644
--- a/src/components/ContextMenu.tsx
+++ b/src/components/ContextMenu.tsx
@@ -11,6 +11,7 @@ import {
 } from "../actions/shortcuts";
 import { Action } from "../actions/types";
 import { ActionManager } from "../actions/manager";
+import { AppState } from "../types";
 
 type ContextMenuOption = "separator" | Action;
 
@@ -20,6 +21,7 @@ type ContextMenuProps = {
   top: number;
   left: number;
   actionManager: ActionManager;
+  appState: Readonly<AppState>;
 };
 
 const ContextMenu = ({
@@ -28,11 +30,11 @@ const ContextMenu = ({
   top,
   left,
   actionManager,
+  appState,
 }: ContextMenuProps) => {
   const isDarkTheme = !!document
     .querySelector(".excalidraw")
     ?.classList.contains("Appearance_dark");
-
   return (
     <div
       className={clsx("excalidraw", {
@@ -61,9 +63,10 @@ const ContextMenu = ({
             return (
               <li key={idx} data-testid={actionName} onClick={onCloseRequest}>
                 <button
-                  className={`context-menu-option
-                  ${actionName === "deleteSelectedElements" ? "dangerous" : ""}
-                  ${option.checked ? "checkmark" : ""}`}
+                  className={clsx("context-menu-option", {
+                    dangerous: actionName === "deleteSelectedElements",
+                    checkmark: option.checked?.(appState),
+                  })}
                   onClick={() => actionManager.executeAction(option)}
                 >
                   <div className="context-menu-option__label">{label}</div>
@@ -97,6 +100,7 @@ type ContextMenuParams = {
   top: ContextMenuProps["top"];
   left: ContextMenuProps["left"];
   actionManager: ContextMenuProps["actionManager"];
+  appState: Readonly<AppState>;
 };
 
 const handleClose = () => {
@@ -119,6 +123,7 @@ export default {
           options={options}
           onCloseRequest={handleClose}
           actionManager={params.actionManager}
+          appState={params.appState}
         />,
         getContextMenuNode(),
       );