mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-10-31 02:44:50 +01:00 
			
		
		
		
	Move more stuff to Portal (#1309)
This commit is contained in:
		| @@ -162,12 +162,34 @@ class Portal { | ||||
|     this.roomID = null; | ||||
|     this.roomKey = null; | ||||
|   } | ||||
|  | ||||
|   isOpen() { | ||||
|     return this.socketInitialized && this.socket && this.roomID && this.roomKey; | ||||
|   } | ||||
|  | ||||
|   async _broadcastSocketData( | ||||
|     data: SocketUpdateDataSource[keyof SocketUpdateDataSource] & { | ||||
|       _brand: "socketUpdateData"; | ||||
|     }, | ||||
|   ) { | ||||
|     if (this.isOpen()) { | ||||
|       const json = JSON.stringify(data); | ||||
|       const encoded = new TextEncoder().encode(json); | ||||
|       const encrypted = await encryptAESGEM(encoded, this.roomKey!); | ||||
|       this.socket!.emit( | ||||
|         "server-broadcast", | ||||
|         this.roomID, | ||||
|         encrypted.data, | ||||
|         encrypted.iv, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| export class App extends React.Component<any, AppState> { | ||||
|   canvas: HTMLCanvasElement | null = null; | ||||
|   rc: RoughCanvas | null = null; | ||||
|   room: Portal = new Portal(); | ||||
|   portal: Portal = new Portal(); | ||||
|   lastBroadcastedOrReceivedSceneVersion: number = -1; | ||||
|   removeSceneCallback: SceneStateCallbackRemover | null = null; | ||||
|  | ||||
| @@ -444,7 +466,7 @@ export class App extends React.Component<any, AppState> { | ||||
|   }); | ||||
|  | ||||
|   componentDidUpdate() { | ||||
|     if (this.state.isCollaborating && !this.room.socket) { | ||||
|     if (this.state.isCollaborating && !this.portal.socket) { | ||||
|       this.initializeSocketClient({ showLoadingState: true }); | ||||
|     } | ||||
|  | ||||
| @@ -740,17 +762,17 @@ export class App extends React.Component<any, AppState> { | ||||
|       isCollaborating: false, | ||||
|       collaborators: new Map(), | ||||
|     }); | ||||
|     this.room.close(); | ||||
|     this.portal.close(); | ||||
|   }; | ||||
|  | ||||
|   private initializeSocketClient = (opts: { showLoadingState: boolean }) => { | ||||
|     if (this.room.socket) { | ||||
|     if (this.portal.socket) { | ||||
|       return; | ||||
|     } | ||||
|     const roomMatch = getCollaborationLinkData(window.location.href); | ||||
|     if (roomMatch) { | ||||
|       const initialize = () => { | ||||
|         this.room.socketInitialized = true; | ||||
|         this.portal.socketInitialized = true; | ||||
|         clearTimeout(initializationTimer); | ||||
|         if (this.state.isLoading && !this.unmounted) { | ||||
|           this.setState({ isLoading: false }); | ||||
| @@ -856,26 +878,30 @@ export class App extends React.Component<any, AppState> { | ||||
|         // undo, a user makes a change, and then try to redo, your element(s) will be lost. However, | ||||
|         // right now we think this is the right tradeoff. | ||||
|         history.clear(); | ||||
|         if (this.room.socketInitialized === false) { | ||||
|         if (this.portal.socketInitialized === false) { | ||||
|           initialize(); | ||||
|         } | ||||
|       }; | ||||
|  | ||||
|       this.room.open(socketIOClient(SOCKET_SERVER), roomMatch[1], roomMatch[2]); | ||||
|       this.portal.open( | ||||
|         socketIOClient(SOCKET_SERVER), | ||||
|         roomMatch[1], | ||||
|         roomMatch[2], | ||||
|       ); | ||||
|  | ||||
|       this.room.socket!.on("init-room", () => { | ||||
|         this.room.socket && | ||||
|           this.room.socket.emit("join-room", this.room.roomID); | ||||
|       this.portal.socket!.on("init-room", () => { | ||||
|         this.portal.socket && | ||||
|           this.portal.socket.emit("join-room", this.portal.roomID); | ||||
|       }); | ||||
|       this.room.socket!.on( | ||||
|       this.portal.socket!.on( | ||||
|         "client-broadcast", | ||||
|         async (encryptedData: ArrayBuffer, iv: Uint8Array) => { | ||||
|           if (!this.room.roomKey) { | ||||
|           if (!this.portal.roomKey) { | ||||
|             return; | ||||
|           } | ||||
|           const decryptedData = await decryptAESGEM( | ||||
|             encryptedData, | ||||
|             this.room.roomKey, | ||||
|             this.portal.roomKey, | ||||
|             iv, | ||||
|           ); | ||||
|  | ||||
| @@ -883,7 +909,7 @@ export class App extends React.Component<any, AppState> { | ||||
|             case "INVALID_RESPONSE": | ||||
|               return; | ||||
|             case "SCENE_INIT": { | ||||
|               if (!this.room.socketInitialized) { | ||||
|               if (!this.portal.socketInitialized) { | ||||
|                 updateScene(decryptedData, { scrollToContent: true }); | ||||
|               } | ||||
|               break; | ||||
| @@ -916,13 +942,13 @@ export class App extends React.Component<any, AppState> { | ||||
|           } | ||||
|         }, | ||||
|       ); | ||||
|       this.room.socket!.on("first-in-room", () => { | ||||
|         if (this.room.socket) { | ||||
|           this.room.socket.off("first-in-room"); | ||||
|       this.portal.socket!.on("first-in-room", () => { | ||||
|         if (this.portal.socket) { | ||||
|           this.portal.socket.off("first-in-room"); | ||||
|         } | ||||
|         initialize(); | ||||
|       }); | ||||
|       this.room.socket!.on("room-user-change", (clients: string[]) => { | ||||
|       this.portal.socket!.on("room-user-change", (clients: string[]) => { | ||||
|         this.setState((state) => { | ||||
|           const collaborators: typeof state.collaborators = new Map(); | ||||
|           for (const socketID of clients) { | ||||
| @@ -938,7 +964,7 @@ export class App extends React.Component<any, AppState> { | ||||
|           }; | ||||
|         }); | ||||
|       }); | ||||
|       this.room.socket!.on("new-user", async (_socketID: string) => { | ||||
|       this.portal.socket!.on("new-user", async (_socketID: string) => { | ||||
|         this.broadcastScene("SCENE_INIT"); | ||||
|       }); | ||||
|  | ||||
| @@ -953,18 +979,18 @@ export class App extends React.Component<any, AppState> { | ||||
|     pointerCoords: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointerCoords"]; | ||||
|     button: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["button"]; | ||||
|   }) => { | ||||
|     if (this.room.socket?.id) { | ||||
|     if (this.portal.socket?.id) { | ||||
|       const data: SocketUpdateDataSource["MOUSE_LOCATION"] = { | ||||
|         type: "MOUSE_LOCATION", | ||||
|         payload: { | ||||
|           socketID: this.room.socket.id, | ||||
|           socketID: this.portal.socket.id, | ||||
|           pointerCoords: payload.pointerCoords, | ||||
|           button: payload.button || "up", | ||||
|           selectedElementIds: this.state.selectedElementIds, | ||||
|           username: this.state.username, | ||||
|         }, | ||||
|       }; | ||||
|       return this._broadcastSocketData( | ||||
|       return this.portal._broadcastSocketData( | ||||
|         data as typeof data & { _brand: "socketUpdateData" }, | ||||
|       ); | ||||
|     } | ||||
| @@ -983,35 +1009,11 @@ export class App extends React.Component<any, AppState> { | ||||
|       this.lastBroadcastedOrReceivedSceneVersion, | ||||
|       getDrawingVersion(globalSceneState.getElementsIncludingDeleted()), | ||||
|     ); | ||||
|     return this._broadcastSocketData( | ||||
|     return this.portal._broadcastSocketData( | ||||
|       data as typeof data & { _brand: "socketUpdateData" }, | ||||
|     ); | ||||
|   }; | ||||
|  | ||||
|   // Low-level. Use type-specific broadcast* method. | ||||
|   private async _broadcastSocketData( | ||||
|     data: SocketUpdateDataSource[keyof SocketUpdateDataSource] & { | ||||
|       _brand: "socketUpdateData"; | ||||
|     }, | ||||
|   ) { | ||||
|     if ( | ||||
|       this.room.socketInitialized && | ||||
|       this.room.socket && | ||||
|       this.room.roomID && | ||||
|       this.room.roomKey | ||||
|     ) { | ||||
|       const json = JSON.stringify(data); | ||||
|       const encoded = new TextEncoder().encode(json); | ||||
|       const encrypted = await encryptAESGEM(encoded, this.room.roomKey); | ||||
|       this.room.socket.emit( | ||||
|         "server-broadcast", | ||||
|         this.room.roomID, | ||||
|         encrypted.data, | ||||
|         encrypted.iv, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private onSceneUpdated = () => { | ||||
|     this.setState({}); | ||||
|   }; | ||||
| @@ -2500,7 +2502,7 @@ export class App extends React.Component<any, AppState> { | ||||
|       // sometimes the pointer goes off screen | ||||
|       return; | ||||
|     } | ||||
|     this.room.socket && | ||||
|     this.portal.socket && | ||||
|       this.broadcastMouseLocation({ | ||||
|         pointerCoords, | ||||
|         button, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Kent Beck
					Kent Beck