1
0
mirror of https://github.com/excalidraw/excalidraw.git synced 2024-11-10 11:35:52 +01:00

fix: collab room initialization (#4882)

This commit is contained in:
David Luzar 2022-03-06 15:59:56 +01:00 committed by GitHub
parent b26e4fcf99
commit 9392ec276d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 31 deletions

@ -353,32 +353,17 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
this.isCollaborating = true;
const { default: socketIOClient }: any = await import(
const { default: socketIOClient } = await import(
/* webpackChunkName: "socketIoClient" */ "socket.io-client"
);
this.portal.open(socketIOClient(SOCKET_SERVER), roomId, roomKey);
this.portal.socket = this.portal.open(
socketIOClient(SOCKET_SERVER),
roomId,
roomKey,
);
if (existingRoomLinkData) {
this.excalidrawAPI.resetScene();
try {
const elements = await loadFromFirebase(
roomId,
roomKey,
this.portal.socket,
);
if (elements) {
scenePromise.resolve({
elements,
scrollToContent: true,
});
}
} catch (error: any) {
// log the error and move on. other peers will sync us the scene.
console.error(error);
}
} else {
if (!existingRoomLinkData) {
const elements = this.excalidrawAPI.getSceneElements().map((element) => {
if (isImageElement(element) && element.status === "saved") {
return newElementWith(element, { status: "pending" });
@ -402,14 +387,17 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
}
// fallback in case you're not alone in the room but still don't receive
// initial SCENE_UPDATE message
// initial SCENE_INIT message
this.socketInitializationTimer = window.setTimeout(() => {
this.initializeSocket();
this.initializeRoom({
roomLinkData: existingRoomLinkData,
fetchScene: true,
});
scenePromise.resolve(null);
}, INITIAL_SCENE_UPDATE_TIMEOUT);
// All socket listeners are moving to Portal
this.portal.socket!.on(
this.portal.socket.on(
"client-broadcast",
async (encryptedData: ArrayBuffer, iv: Uint8Array) => {
if (!this.portal.roomKey) {
@ -427,7 +415,7 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
return;
case SCENE.INIT: {
if (!this.portal.socketInitialized) {
this.initializeSocket();
this.initializeRoom({ fetchScene: false });
const remoteElements = decryptedData.payload.elements;
const reconciledElements = this.reconcileElements(remoteElements);
this.handleRemoteSceneUpdate(reconciledElements, {
@ -481,12 +469,15 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
},
);
this.portal.socket!.on("first-in-room", () => {
this.portal.socket.on("first-in-room", async () => {
if (this.portal.socket) {
this.portal.socket.off("first-in-room");
}
this.initializeSocket();
scenePromise.resolve(null);
const sceneData = await this.initializeRoom({
fetchScene: true,
roomLinkData: existingRoomLinkData,
});
scenePromise.resolve(sceneData);
});
this.initializeIdleDetector();
@ -498,9 +489,45 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
return scenePromise;
};
private initializeSocket = () => {
this.portal.socketInitialized = true;
private initializeRoom = async ({
fetchScene,
roomLinkData,
}:
| {
fetchScene: true;
roomLinkData: { roomId: string; roomKey: string } | null;
}
| { fetchScene: false; roomLinkData?: null }) => {
clearTimeout(this.socketInitializationTimer!);
if (fetchScene && roomLinkData && this.portal.socket) {
this.excalidrawAPI.resetScene();
try {
const elements = await loadFromFirebase(
roomLinkData.roomId,
roomLinkData.roomKey,
this.portal.socket,
);
if (elements) {
this.setLastBroadcastedOrReceivedSceneVersion(
getSceneVersion(elements),
);
return {
elements,
scrollToContent: true,
};
}
} catch (error: any) {
// log the error and move on. other peers will sync us the scene.
console.error(error);
} finally {
this.portal.socketInitialized = true;
}
} else {
this.portal.socketInitialized = true;
}
return null;
};
private reconcileElements = (

@ -45,6 +45,8 @@ class Portal {
this.socket.on("room-user-change", (clients: string[]) => {
this.collab.setCollaborators(clients);
});
return socket;
}
close() {