From f8c9f63650f8664a1df4aad1fd3d542dbe88dc7d Mon Sep 17 00:00:00 2001 From: Ryan Di Date: Fri, 26 Aug 2022 19:58:54 +0800 Subject: [PATCH] fix: disconnect from and reconnect to socket server when visibilitychange --- src/excalidraw-app/app_constants.ts | 1 + src/excalidraw-app/index.tsx | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/excalidraw-app/app_constants.ts b/src/excalidraw-app/app_constants.ts index cbead7683..47ae8e634 100644 --- a/src/excalidraw-app/app_constants.ts +++ b/src/excalidraw-app/app_constants.ts @@ -7,6 +7,7 @@ export const SYNC_FULL_SCENE_INTERVAL_MS = 20000; export const SYNC_BROWSER_TABS_TIMEOUT = 50; export const CURSOR_SYNC_TIMEOUT = 33; // ~30fps export const DELETED_ELEMENT_TIMEOUT = 24 * 60 * 60 * 1000; // 1 day +export const HIDDEN_DISCONNECT_TIMEOUT = 30000; export const FILE_UPLOAD_MAX_BYTES = 3 * 1024 * 1024; // 3 MiB // 1 year (https://stackoverflow.com/a/25201898/927631) diff --git a/src/excalidraw-app/index.tsx b/src/excalidraw-app/index.tsx index 896c96d98..4e72399db 100644 --- a/src/excalidraw-app/index.tsx +++ b/src/excalidraw-app/index.tsx @@ -43,6 +43,7 @@ import { } from "../utils"; import { FIREBASE_STORAGE_PREFIXES, + HIDDEN_DISCONNECT_TIMEOUT, STORAGE_KEYS, SYNC_BROWSER_TABS_TIMEOUT, } from "./app_constants"; @@ -452,6 +453,8 @@ const ExcalidrawWrapper = () => { LocalData.flushSave(); }; + let disconnectTimeout: ReturnType; + const visibilityChange = (event: FocusEvent | Event) => { if (event.type === EVENT.BLUR || document.hidden) { LocalData.flushSave(); @@ -461,6 +464,31 @@ const ExcalidrawWrapper = () => { event.type === EVENT.FOCUS ) { syncData(); + + const disconnect = () => { + disconnectTimeout = setTimeout( + () => collabAPI.stopCollaboration(false), + HIDDEN_DISCONNECT_TIMEOUT, + ); + }; + const cancelPrevDisconnect = () => clearTimeout(disconnectTimeout); + + if (document.hidden && collabAPI.isCollaborating()) { + if (!disconnectTimeout) { + disconnect(); + } else { + cancelPrevDisconnect(); + disconnect(); + } + } else { + cancelPrevDisconnect(); + if (!collabAPI.isCollaborating()) { + initializeScene({ collabAPI, excalidrawAPI }).then(async (data) => { + loadImages(data, /* isInitialLoad */ true); + initialStatePromiseRef.current.promise.resolve(data.scene); + }); + } + } } };