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:
parent
b26e4fcf99
commit
9392ec276d
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user