Browse Source

fix: scene not initialized properly when tab not focused (#2677)

Co-authored-by: Lipis <lipiridis@gmail.com>
David Luzar 4 years ago
parent
commit
aef3644c93
3 changed files with 20 additions and 16 deletions
  1. 10 1
      src/components/App.tsx
  2. 9 15
      src/excalidraw-app/index.tsx
  3. 1 0
      src/packages/excalidraw/CHANGELOG.md

+ 10 - 1
src/components/App.tsx

@@ -861,7 +861,16 @@ class App extends React.Component<ExcalidrawProps, AppState> {
 
     history.record(this.state, this.scene.getElementsIncludingDeleted());
 
-    this.props.onChange?.(this.scene.getElementsIncludingDeleted(), this.state);
+    // Do not notify consumers if we're still loading the scene. Among other
+    // potential issues, this fixes a case where the tab isn't focused during
+    // init, which would trigger onChange with empty elements, which would then
+    // override whatever is in localStorage currently.
+    if (!this.state.isLoading) {
+      this.props.onChange?.(
+        this.scene.getElementsIncludingDeleted(),
+        this.state,
+      );
+    }
   }
 
   // Copy/paste

+ 9 - 15
src/excalidraw-app/index.tsx

@@ -93,7 +93,6 @@ type Scene = ImportedDataState & { commitToHistory: boolean };
 const initializeScene = async (opts: {
   resetScene: ExcalidrawImperativeAPI["resetScene"];
   initializeSocketClient: CollabAPI["initializeSocketClient"];
-  onLateInitialization?: (scene: Scene) => void;
 }): Promise<Scene | null> => {
   const searchParams = new URLSearchParams(window.location.search);
   const id = searchParams.get("id");
@@ -124,17 +123,15 @@ const initializeScene = async (opts: {
     } else {
       // https://github.com/excalidraw/excalidraw/issues/1919
       if (document.hidden) {
-        window.addEventListener(
-          "focus",
-          () =>
-            initializeScene(opts).then((_scene) => {
-              opts?.onLateInitialization?.(_scene || scene);
-            }),
-          {
-            once: true,
-          },
-        );
-        return null;
+        return new Promise((resolve, reject) => {
+          window.addEventListener(
+            "focus",
+            () => initializeScene(opts).then(resolve).catch(reject),
+            {
+              once: true,
+            },
+          );
+        });
       }
 
       isCollabScene = false;
@@ -222,9 +219,6 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
       initializeScene({
         resetScene: excalidrawApi.resetScene,
         initializeSocketClient: collab.initializeSocketClient,
-        onLateInitialization: (scene) => {
-          initialStatePromiseRef.current.promise.resolve(scene);
-        },
       }).then((scene) => {
         initialStatePromiseRef.current.promise.resolve(scene);
       });

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

@@ -27,6 +27,7 @@ Please add the latest change on the top under the correct section.
 
 ### Fixes
 
+- Fix initialization when browser tab not focused [#2677](https://github.com/excalidraw/excalidraw/pull/2677)
 - Consistent case for export locale strings [#2622](https://github.com/excalidraw/excalidraw/pull/2622)
 - Remove unnecessary console.error as it was polluting Sentry [#2637](https://github.com/excalidraw/excalidraw/pull/2637)
 - Fix scroll-to-center on init for non-zero canvas offsets [#2445](https://github.com/excalidraw/excalidraw/pull/2445)