Przeglądaj źródła

refactor: move getSyncableElements to CollabWrapper & expose isInvisiblySmallElement helper (#3471)

Co-authored-by: Aakansha Doshi <aakansha1216@gmail.com>
David Luzar 4 lat temu
rodzic
commit
3a0b6fb41b

+ 0 - 7
src/element/index.ts

@@ -58,13 +58,6 @@ export {
 } from "./sizeHelpers";
 } from "./sizeHelpers";
 export { showSelectedShapeActions } from "./showSelectedShapeActions";
 export { showSelectedShapeActions } from "./showSelectedShapeActions";
 
 
-export const getSyncableElements = (
-  elements: readonly ExcalidrawElement[], // There are places in Excalidraw where synthetic invisibly small elements are added and removed.
-) =>
-  // It's probably best to keep those local otherwise there might be a race condition that
-  // gets the app into an invalid state. I've never seen it happen but I'm worried about it :)
-  elements.filter((el) => el.isDeleted || !isInvisiblySmallElement(el));
-
 export const getElementMap = (elements: readonly ExcalidrawElement[]) =>
 export const getElementMap = (elements: readonly ExcalidrawElement[]) =>
   elements.reduce(
   elements.reduce(
     (acc: { [key: string]: ExcalidrawElement }, element: ExcalidrawElement) => {
     (acc: { [key: string]: ExcalidrawElement }, element: ExcalidrawElement) => {

+ 8 - 5
src/excalidraw-app/collab/CollabWrapper.tsx

@@ -8,7 +8,6 @@ import { ExcalidrawElement } from "../../element/types";
 import {
 import {
   getElementMap,
   getElementMap,
   getSceneVersion,
   getSceneVersion,
-  getSyncableElements,
 } from "../../packages/excalidraw/index";
 } from "../../packages/excalidraw/index";
 import { Collaborator, Gesture } from "../../types";
 import { Collaborator, Gesture } from "../../types";
 import { resolvablePromise, withBatchedUpdates } from "../../utils";
 import { resolvablePromise, withBatchedUpdates } from "../../utils";
@@ -41,6 +40,7 @@ import { t } from "../../i18n";
 import { UserIdleState } from "../../types";
 import { UserIdleState } from "../../types";
 import { IDLE_THRESHOLD, ACTIVE_THRESHOLD } from "../../constants";
 import { IDLE_THRESHOLD, ACTIVE_THRESHOLD } from "../../constants";
 import { trackEvent } from "../../analytics";
 import { trackEvent } from "../../analytics";
+import { isInvisiblySmallElement } from "../../element";
 
 
 interface CollabState {
 interface CollabState {
   modalIsShown: boolean;
   modalIsShown: boolean;
@@ -146,7 +146,7 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
   };
   };
 
 
   private beforeUnload = withBatchedUpdates((event: BeforeUnloadEvent) => {
   private beforeUnload = withBatchedUpdates((event: BeforeUnloadEvent) => {
-    const syncableElements = getSyncableElements(
+    const syncableElements = this.getSyncableElements(
       this.getSceneElementsIncludingDeleted(),
       this.getSceneElementsIncludingDeleted(),
     );
     );
 
 
@@ -177,7 +177,7 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
   });
   });
 
 
   saveCollabRoomToFirebase = async (
   saveCollabRoomToFirebase = async (
-    syncableElements: ExcalidrawElement[] = getSyncableElements(
+    syncableElements: ExcalidrawElement[] = this.getSyncableElements(
       this.excalidrawAPI.getSceneElementsIncludingDeleted(),
       this.excalidrawAPI.getSceneElementsIncludingDeleted(),
     ),
     ),
   ) => {
   ) => {
@@ -565,7 +565,7 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
     ) {
     ) {
       this.portal.broadcastScene(
       this.portal.broadcastScene(
         SCENE.UPDATE,
         SCENE.UPDATE,
-        getSyncableElements(elements),
+        this.getSyncableElements(elements),
         false,
         false,
       );
       );
       this.lastBroadcastedOrReceivedSceneVersion = getSceneVersion(elements);
       this.lastBroadcastedOrReceivedSceneVersion = getSceneVersion(elements);
@@ -576,7 +576,7 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
   queueBroadcastAllElements = throttle(() => {
   queueBroadcastAllElements = throttle(() => {
     this.portal.broadcastScene(
     this.portal.broadcastScene(
       SCENE.UPDATE,
       SCENE.UPDATE,
-      getSyncableElements(
+      this.getSyncableElements(
         this.excalidrawAPI.getSceneElementsIncludingDeleted(),
         this.excalidrawAPI.getSceneElementsIncludingDeleted(),
       ),
       ),
       true,
       true,
@@ -604,6 +604,9 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
     });
     });
   };
   };
 
 
+  getSyncableElements = (elements: readonly ExcalidrawElement[]) =>
+    elements.filter((el) => el.isDeleted || !isInvisiblySmallElement(el));
+
   /** PRIVATE. Use `this.getContextValue()` instead. */
   /** PRIVATE. Use `this.getContextValue()` instead. */
   private contextValue: CollabAPI | null = null;
   private contextValue: CollabAPI | null = null;
 
 

+ 3 - 2
src/excalidraw-app/collab/Portal.tsx

@@ -6,7 +6,6 @@ import {
 
 
 import CollabWrapper from "./CollabWrapper";
 import CollabWrapper from "./CollabWrapper";
 
 
-import { getSyncableElements } from "../../packages/excalidraw/index";
 import { ExcalidrawElement } from "../../element/types";
 import { ExcalidrawElement } from "../../element/types";
 import { BROADCAST, SCENE } from "../app_constants";
 import { BROADCAST, SCENE } from "../app_constants";
 import { UserIdleState } from "../../types";
 import { UserIdleState } from "../../types";
@@ -39,7 +38,9 @@ class Portal {
     this.socket.on("new-user", async (_socketId: string) => {
     this.socket.on("new-user", async (_socketId: string) => {
       this.broadcastScene(
       this.broadcastScene(
         SCENE.INIT,
         SCENE.INIT,
-        getSyncableElements(this.collab.getSceneElementsIncludingDeleted()),
+        this.collab.getSyncableElements(
+          this.collab.getSceneElementsIncludingDeleted(),
+        ),
         /* syncAll */ true,
         /* syncAll */ true,
       );
       );
     });
     });

+ 11 - 0
src/packages/excalidraw/CHANGELOG.md

@@ -40,6 +40,17 @@ Please add the latest change on the top under the correct section.
 
 
 - When switching theme, apply it only to the active Excalidraw component. This fixes a case where the theme was getting applied to the first Excalidraw component if you had multiple Excalidraw components on the same page [#3446](https://github.com/excalidraw/excalidraw/pull/3446)
 - When switching theme, apply it only to the active Excalidraw component. This fixes a case where the theme was getting applied to the first Excalidraw component if you had multiple Excalidraw components on the same page [#3446](https://github.com/excalidraw/excalidraw/pull/3446)
 
 
+### Refactor
+
+- #### BREAKING CHANGE
+
+  - Removed exposing `getSyncableElements` helper which was specific to excalidraw app collab implementation [#3471](https://github.com/excalidraw/excalidraw/pull/3471). If you happened to use it, you can easily reimplement it yourself using the newly exposed [isInvisiblySmallElement](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#isInvisiblySmallElement) helper:
+
+    ```ts
+    const getSyncableElements = (elements: readonly ExcalidrawElement[]) =>
+      elements.filter((el) => el.isDeleted || !isInvisiblySmallElement(el));
+    ```
+
 ## Types
 ## Types
 
 
 - Renamed the following types in case you depend on them (via [#3427](https://github.com/excalidraw/excalidraw/pull/3427)):
 - Renamed the following types in case you depend on them (via [#3427](https://github.com/excalidraw/excalidraw/pull/3427)):

+ 4 - 4
src/packages/excalidraw/README_NEXT.md

@@ -629,21 +629,21 @@ getSceneVersion(elements:  <a href="https://github.com/excalidraw/excalidraw/blo
 
 
 This function returns the current scene version.
 This function returns the current scene version.
 
 
-#### `getSyncableElements`
+#### `isInvisiblySmallElement`
 
 
 **_Signature_**
 **_Signature_**
 
 
 <pre>
 <pre>
-getSyncableElements(elements:  <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>):<a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement[]</a>
+isInvisiblySmallElement(element:  <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L78">ExcalidrawElement</a>): boolean
 </pre>
 </pre>
 
 
 **How to use**
 **How to use**
 
 
 ```js
 ```js
-import { getSyncableElements } from "@excalidraw/excalidraw";
+import { isInvisiblySmallElement } from "@excalidraw/excalidraw";
 ```
 ```
 
 
-Returns all elements including deleted ones, excluding elements which are are invisibly small (e.g. width & height are zero). Useful when you want to sync elements during collaboration.
+Returns `true` if element is invisibly small (e.g. width & height are zero).
 
 
 #### `getElementMap`
 #### `getElementMap`
 
 

+ 1 - 1
src/packages/excalidraw/index.tsx

@@ -115,8 +115,8 @@ const forwardedRefComp = forwardRef<
 export default React.memo(forwardedRefComp, areEqual);
 export default React.memo(forwardedRefComp, areEqual);
 export {
 export {
   getSceneVersion,
   getSceneVersion,
-  getSyncableElements,
   getElementMap,
   getElementMap,
+  isInvisiblySmallElement,
 } from "../../element";
 } from "../../element";
 export { defaultLang, languages } from "../../i18n";
 export { defaultLang, languages } from "../../i18n";
 export { restore, restoreAppState, restoreElements } from "../../data/restore";
 export { restore, restoreAppState, restoreElements } from "../../data/restore";