Browse Source

Restore input value and fix history

Signed-off-by: Mark Tolmacs <[email protected]>
Mark Tolmacs 4 months ago
parent
commit
3d40221dc1

+ 20 - 6
packages/excalidraw/components/Stats/Angle.tsx

@@ -117,6 +117,7 @@ const handleFinished: DragFinishedCallbackType<AngleProps["property"]> = ({
   scene,
   accumulatedChange,
   setAppState,
+  setInputValue,
 }) => {
   const elementsMap = scene.getNonDeletedElementsMap();
   const origElement = originalElements[0];
@@ -125,19 +126,32 @@ const handleFinished: DragFinishedCallbackType<AngleProps["property"]> = ({
     const latestElement = elementsMap.get(origElement.id);
 
     if (latestElement) {
-      updateBindings(latestElement, elementsMap, originalAppState.zoom, () => {
+      setAppState({
+        suggestedBindings: [],
+      });
+
+      const success = updateBindings(
+        latestElement,
+        elementsMap,
+        originalAppState.zoom,
+      );
+
+      if (!success) {
         const change = degreesToRadians(accumulatedChange as Degrees);
+        const angle = (latestElement.angle - change) as Radians;
 
         mutateElement(latestElement, {
-          angle: (latestElement.angle - change) as Radians,
+          angle,
         });
-      });
 
-      setAppState({
-        suggestedBindings: [],
-      });
+        setInputValue(angle);
+
+        return false;
+      }
     }
   }
+
+  return true;
 };
 
 const Angle = ({ element, scene, appState, property }: AngleProps) => {

+ 26 - 17
packages/excalidraw/components/Stats/DragInput.tsx

@@ -48,7 +48,8 @@ export type DragFinishedCallbackType<
   originalAppState: AppState;
   accumulatedChange: number;
   setAppState: React.Component<any, AppState>["setState"];
-}) => void;
+  setInputValue: (value: number) => void;
+}) => boolean;
 
 interface StatsDragInputProps<
   T extends StatsInputProperty,
@@ -155,7 +156,7 @@ const StatsDragInput = <
         setInputValue: (value) => setInputValue(String(value)),
         setAppState,
       });
-      dragFinishedCallback?.({
+      const commit = dragFinishedCallback?.({
         originalElements: elements,
         originalElementsMap,
         scene,
@@ -163,10 +164,13 @@ const StatsDragInput = <
         accumulatedChange: rounded,
         property,
         setAppState,
+        setInputValue: (value) => setInputValue(String(value)),
       });
-      app.syncActionResult({
-        captureUpdate: CaptureUpdateAction.IMMEDIATELY,
-      });
+      if (commit) {
+        app.syncActionResult({
+          captureUpdate: CaptureUpdateAction.IMMEDIATELY,
+        });
+      }
     }
   };
 
@@ -311,21 +315,26 @@ const StatsDragInput = <
                 false,
               );
 
+              let commit = true;
               if (originalElements !== null && originalElementsMap !== null) {
-                dragFinishedCallback?.({
-                  originalElements,
-                  originalElementsMap,
-                  scene,
-                  originalAppState,
-                  property,
-                  accumulatedChange,
-                  setAppState,
-                });
+                commit =
+                  dragFinishedCallback?.({
+                    originalElements,
+                    originalElementsMap,
+                    scene,
+                    originalAppState,
+                    property,
+                    accumulatedChange,
+                    setAppState,
+                    setInputValue: (value) => setInputValue(String(value)),
+                  }) ?? true;
               }
 
-              app.syncActionResult({
-                captureUpdate: CaptureUpdateAction.IMMEDIATELY,
-              });
+              if (commit) {
+                app.syncActionResult({
+                  captureUpdate: CaptureUpdateAction.IMMEDIATELY,
+                });
+              }
 
               lastPointer = null;
               accumulatedChange = 0;

+ 19 - 6
packages/excalidraw/components/Stats/Position.tsx

@@ -204,7 +204,8 @@ const handleFinished: DragFinishedCallbackType<"x" | "y"> = ({
   accumulatedChange,
   property,
   setAppState,
-}) => {
+  setInputValue,
+}): boolean => {
   const elementsMap = scene.getNonDeletedElementsMap();
   const origElement = originalElements[0];
 
@@ -212,17 +213,29 @@ const handleFinished: DragFinishedCallbackType<"x" | "y"> = ({
     const latestElement = elementsMap.get(origElement.id);
 
     if (latestElement) {
-      updateBindings(latestElement, elementsMap, originalAppState.zoom, () => {
+      setAppState({
+        suggestedBindings: [],
+      });
+
+      const success = updateBindings(
+        latestElement,
+        elementsMap,
+        originalAppState.zoom,
+      );
+
+      if (!success) {
         mutateElement(latestElement, {
           [property]: latestElement[property] - accumulatedChange,
         });
-      });
 
-      setAppState({
-        suggestedBindings: [],
-      });
+        setInputValue(latestElement[property] - accumulatedChange);
+      }
+
+      return false;
     }
   }
+
+  return true;
 };
 
 const Position = ({ property, element, scene, appState }: PositionProps) => {

+ 12 - 11
packages/excalidraw/components/Stats/utils.ts

@@ -204,8 +204,7 @@ export const updateBindings = (
   latestElement: ExcalidrawElement,
   elementsMap: NonDeletedSceneElementsMap,
   zoom?: AppState["zoom"],
-  bindingElementKeptOriginalBinding?: () => void,
-) => {
+): boolean => {
   if (isBindingElement(latestElement)) {
     const [start, end] = getOriginalBindingsIfStillCloseToArrowEnds(
       latestElement,
@@ -217,15 +216,17 @@ export const updateBindings = (
       (latestElement.startBinding && start) ||
       (latestElement.endBinding && end)
     ) {
-      bindingElementKeptOriginalBinding?.();
-    } else {
-      if (latestElement.startBinding && !start) {
-        unbindLinearElement(latestElement, "start");
-      }
-
-      if (latestElement.endBinding && !end) {
-        unbindLinearElement(latestElement, "end");
-      }
+      return false;
+    }
+
+    if (latestElement.startBinding && !start) {
+      unbindLinearElement(latestElement, "start");
+    }
+
+    if (latestElement.endBinding && !end) {
+      unbindLinearElement(latestElement, "end");
     }
   }
+
+  return true;
 };