diff --git a/src/excalidraw-app/app_constants.ts b/src/excalidraw-app/app_constants.ts index 47ae8e634..3997f7216 100644 --- a/src/excalidraw-app/app_constants.ts +++ b/src/excalidraw-app/app_constants.ts @@ -8,6 +8,7 @@ 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 RECONNECT_TOAST_DURATION = 2000; 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 4e72399db..d60241b26 100644 --- a/src/excalidraw-app/index.tsx +++ b/src/excalidraw-app/index.tsx @@ -44,6 +44,7 @@ import { import { FIREBASE_STORAGE_PREFIXES, HIDDEN_DISCONNECT_TIMEOUT, + RECONNECT_TOAST_DURATION, STORAGE_KEYS, SYNC_BROWSER_TABS_TIMEOUT, } from "./app_constants"; @@ -84,6 +85,7 @@ import { Provider, useAtom } from "jotai"; import { jotaiStore, useAtomWithInitialValue } from "../jotai"; import { reconcileElements } from "./collab/reconciliation"; import { parseLibraryTokensFromUrl, useHandleLibrary } from "../data/library"; +import { Toast } from "../components/Toast"; polyfill(); window.EXCALIDRAW_THROTTLE_RENDER = true; @@ -250,6 +252,8 @@ const PlusAppLinkJSX = ( const ExcalidrawWrapper = () => { const [errorMessage, setErrorMessage] = useState(""); + const [toast, setToast] = useState(null); + const disconnectRef = useRef(false); let currentLangCode = languageDetector.detect() || defaultLang.code; if (Array.isArray(currentLangCode)) { currentLangCode = currentLangCode[0]; @@ -470,6 +474,7 @@ const ExcalidrawWrapper = () => { () => collabAPI.stopCollaboration(false), HIDDEN_DISCONNECT_TIMEOUT, ); + disconnectRef.current = true; }; const cancelPrevDisconnect = () => clearTimeout(disconnectTimeout); @@ -479,14 +484,26 @@ const ExcalidrawWrapper = () => { } else { cancelPrevDisconnect(); disconnect(); + setToast(null); } } else { cancelPrevDisconnect(); if (!collabAPI.isCollaborating()) { - initializeScene({ collabAPI, excalidrawAPI }).then(async (data) => { - loadImages(data, /* isInitialLoad */ true); - initialStatePromiseRef.current.promise.resolve(data.scene); - }); + if (!toast && disconnectRef.current) { + setToast({ + message: t("toast.reconnectRoomServer"), + duration: RECONNECT_TOAST_DURATION, + closable: true, + }); + } + disconnectRef.current && + initializeScene({ collabAPI, excalidrawAPI }).then( + async (data) => { + loadImages(data, /* isInitialLoad */ true); + initialStatePromiseRef.current.promise.resolve(data.scene); + }, + ); + disconnectRef.current = false; } } } @@ -509,7 +526,7 @@ const ExcalidrawWrapper = () => { ); clearTimeout(titleTimeout); }; - }, [collabAPI, excalidrawAPI]); + }, [collabAPI, excalidrawAPI, toast]); useEffect(() => { const unloadHandler = (event: BeforeUnloadEvent) => { @@ -719,7 +736,7 @@ const ExcalidrawWrapper = () => { return (
@@ -769,6 +786,14 @@ const ExcalidrawWrapper = () => { onClose={() => setErrorMessage("")} /> )} + {toast && ( + setToast(null)} + /> + )}
); }; diff --git a/src/locales/en.json b/src/locales/en.json index 36dd36fc9..f07cec76a 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -387,7 +387,8 @@ "fileSaved": "File saved.", "fileSavedToFilename": "Saved to {filename}", "canvas": "canvas", - "selection": "selection" + "selection": "selection", + "reconnectRoomServer": "Reconnecting to server" }, "colors": { "ffffff": "White",