Skip to content

Commit

Permalink
Move more stuff to Portal (excalidraw#1309)
Browse files Browse the repository at this point in the history
  • Loading branch information
KentBeck authored Apr 8, 2020
1 parent df0613d commit fdebb38
Showing 1 changed file with 50 additions and 48 deletions.
98 changes: 50 additions & 48 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 });
}

Expand Down Expand Up @@ -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 });
Expand Down Expand Up @@ -856,34 +878,38 @@ 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,
);

switch (decryptedData.type) {
case "INVALID_RESPONSE":
return;
case "SCENE_INIT": {
if (!this.room.socketInitialized) {
if (!this.portal.socketInitialized) {
updateScene(decryptedData, { scrollToContent: true });
}
break;
Expand Down Expand Up @@ -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) {
Expand All @@ -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");
});

Expand All @@ -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" },
);
}
Expand All @@ -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({});
};
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit fdebb38

Please sign in to comment.