mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-10-31 10:54:33 +01:00 
			
		
		
		
	Add SCENE_INIT broadcast type for new user (#1095)
				
					
				
			This commit is contained in:
		| @@ -502,7 +502,7 @@ export class App extends React.Component<any, AppState> { | ||||
|       getDrawingVersion(globalSceneState.getAllElements()) > | ||||
|       this.lastBroadcastedOrReceivedSceneVersion | ||||
|     ) { | ||||
|       this.broadcastSceneUpdate(); | ||||
|       this.broadcastScene("SCENE_UPDATE"); | ||||
|     } | ||||
|  | ||||
|     history.record(this.state, globalSceneState.getAllElements()); | ||||
| @@ -708,28 +708,9 @@ export class App extends React.Component<any, AppState> { | ||||
|       //  initial SCENE_UPDATE message | ||||
|       const initializationTimer = setTimeout(initialize, 5000); | ||||
|  | ||||
|       this.socket = socketIOClient(SOCKET_SERVER); | ||||
|       this.roomID = roomMatch[1]; | ||||
|       this.roomKey = roomMatch[2]; | ||||
|       this.socket.on("init-room", () => { | ||||
|         this.socket && this.socket.emit("join-room", this.roomID); | ||||
|       }); | ||||
|       this.socket.on( | ||||
|         "client-broadcast", | ||||
|         async (encryptedData: ArrayBuffer, iv: Uint8Array) => { | ||||
|           if (!this.roomKey) { | ||||
|             return; | ||||
|           } | ||||
|           const decryptedData = await decryptAESGEM( | ||||
|             encryptedData, | ||||
|             this.roomKey, | ||||
|             iv, | ||||
|           ); | ||||
|  | ||||
|           switch (decryptedData.type) { | ||||
|             case "INVALID_RESPONSE": | ||||
|               return; | ||||
|             case "SCENE_UPDATE": { | ||||
|       const updateScene = ( | ||||
|         decryptedData: SocketUpdateDataSource["SCENE_INIT" | "SCENE_UPDATE"], | ||||
|       ) => { | ||||
|         const { elements: remoteElements } = decryptedData.payload; | ||||
|         const restoredState = restore(remoteElements || [], null, { | ||||
|           scrollToContent: true, | ||||
| @@ -772,8 +753,7 @@ export class App extends React.Component<any, AppState> { | ||||
|                   delete localElementMap[element.id]; | ||||
|                 } else if ( | ||||
|                   localElementMap.hasOwnProperty(element.id) && | ||||
|                         localElementMap[element.id].version === | ||||
|                           element.version && | ||||
|                   localElementMap[element.id].version === element.version && | ||||
|                   localElementMap[element.id].versionNonce !== | ||||
|                     element.versionNonce | ||||
|                 ) { | ||||
| @@ -803,6 +783,7 @@ export class App extends React.Component<any, AppState> { | ||||
|         this.lastBroadcastedOrReceivedSceneVersion = getDrawingVersion( | ||||
|           globalSceneState.getAllElements(), | ||||
|         ); | ||||
|  | ||||
|         // We haven't yet implemented multiplayer undo functionality, so we clear the undo stack | ||||
|         // when we receive any messages from another peer. This UX can be pretty rough -- if you | ||||
|         // undo, a user makes a change, and then try to redo, your element(s) will be lost. However, | ||||
| @@ -811,8 +792,38 @@ export class App extends React.Component<any, AppState> { | ||||
|         if (this.socketInitialized === false) { | ||||
|           initialize(); | ||||
|         } | ||||
|       }; | ||||
|  | ||||
|       this.socket = socketIOClient(SOCKET_SERVER); | ||||
|       this.roomID = roomMatch[1]; | ||||
|       this.roomKey = roomMatch[2]; | ||||
|       this.socket.on("init-room", () => { | ||||
|         this.socket && this.socket.emit("join-room", this.roomID); | ||||
|       }); | ||||
|       this.socket.on( | ||||
|         "client-broadcast", | ||||
|         async (encryptedData: ArrayBuffer, iv: Uint8Array) => { | ||||
|           if (!this.roomKey) { | ||||
|             return; | ||||
|           } | ||||
|           const decryptedData = await decryptAESGEM( | ||||
|             encryptedData, | ||||
|             this.roomKey, | ||||
|             iv, | ||||
|           ); | ||||
|  | ||||
|           switch (decryptedData.type) { | ||||
|             case "INVALID_RESPONSE": | ||||
|               return; | ||||
|             case "SCENE_INIT": { | ||||
|               if (!this.socketInitialized) { | ||||
|                 updateScene(decryptedData); | ||||
|               } | ||||
|               break; | ||||
|             } | ||||
|             case "SCENE_UPDATE": | ||||
|               updateScene(decryptedData); | ||||
|               break; | ||||
|             case "MOUSE_LOCATION": { | ||||
|               const { socketID, pointerCoords } = decryptedData.payload; | ||||
|               this.setState((state) => { | ||||
| @@ -852,7 +863,7 @@ export class App extends React.Component<any, AppState> { | ||||
|         }); | ||||
|       }); | ||||
|       this.socket.on("new-user", async (socketID: string) => { | ||||
|         this.broadcastSceneUpdate(); | ||||
|         this.broadcastScene("SCENE_INIT"); | ||||
|       }); | ||||
|  | ||||
|       this.setState({ | ||||
| @@ -879,9 +890,9 @@ export class App extends React.Component<any, AppState> { | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   private broadcastSceneUpdate = () => { | ||||
|     const data: SocketUpdateDataSource["SCENE_UPDATE"] = { | ||||
|       type: "SCENE_UPDATE", | ||||
|   private broadcastScene = (sceneType: "SCENE_INIT" | "SCENE_UPDATE") => { | ||||
|     const data: SocketUpdateDataSource[typeof sceneType] = { | ||||
|       type: sceneType, | ||||
|       payload: { | ||||
|         elements: getSyncableElements(globalSceneState.getAllElements()), | ||||
|       }, | ||||
|   | ||||
| @@ -32,6 +32,12 @@ export type EncryptedData = { | ||||
| }; | ||||
|  | ||||
| export type SocketUpdateDataSource = { | ||||
|   SCENE_INIT: { | ||||
|     type: "SCENE_INIT"; | ||||
|     payload: { | ||||
|       elements: readonly ExcalidrawElement[]; | ||||
|     }; | ||||
|   }; | ||||
|   SCENE_UPDATE: { | ||||
|     type: "SCENE_UPDATE"; | ||||
|     payload: { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sanghyeon Lee
					Sanghyeon Lee