feat: use userId instead of socketId

This commit is contained in:
Arnošt Pleskot 2023-07-12 16:56:21 +02:00
parent 62df03d78d
commit 2bdf09153c
No known key found for this signature in database
5 changed files with 47 additions and 31 deletions

View File

@ -16,6 +16,7 @@ import { Collaborator, Gesture } from "../../types";
import { import {
preventUnload, preventUnload,
resolvablePromise, resolvablePromise,
upsertMap,
withBatchedUpdates, withBatchedUpdates,
} from "../../utils"; } from "../../utils";
import { import {
@ -74,6 +75,7 @@ import { resetBrowserStateVersions } from "../data/tabSync";
import { LocalData } from "../data/LocalData"; import { LocalData } from "../data/LocalData";
import { atom, useAtom } from "jotai"; import { atom, useAtom } from "jotai";
import { appJotaiStore } from "../app-jotai"; import { appJotaiStore } from "../app-jotai";
import { nanoid } from "nanoid";
export const collabAPIAtom = atom<CollabAPI | null>(null); export const collabAPIAtom = atom<CollabAPI | null>(null);
export const collabDialogShownAtom = atom(false); export const collabDialogShownAtom = atom(false);
@ -85,6 +87,7 @@ interface CollabState {
errorMessage: string; errorMessage: string;
username: string; username: string;
activeRoomLink: string; activeRoomLink: string;
userId: string;
} }
type CollabInstance = InstanceType<typeof Collab>; type CollabInstance = InstanceType<typeof Collab>;
@ -125,6 +128,7 @@ class Collab extends PureComponent<Props, CollabState> {
errorMessage: "", errorMessage: "",
username: importUsernameFromLocalStorage() || "", username: importUsernameFromLocalStorage() || "",
activeRoomLink: "", activeRoomLink: "",
userId: nanoid(),
}; };
this.portal = new Portal(this); this.portal = new Portal(this);
this.fileManager = new FileManager({ this.fileManager = new FileManager({
@ -644,33 +648,36 @@ class Collab extends PureComponent<Props, CollabState> {
); );
break; break;
case "MOUSE_LOCATION": { case "MOUSE_LOCATION": {
const { pointer, button, username, selectedElementIds } = const { pointer, button, username, selectedElementIds, userId } =
decryptedData.payload; decryptedData.payload;
const socketId: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["socketId"] = const collaborators = upsertMap(
decryptedData.payload.socketId || userId,
// @ts-ignore legacy, see #2094 (#2097) {
decryptedData.payload.socketID; username,
pointer,
const collaborators = new Map(this.collaborators); button,
const user = collaborators.get(socketId) || {}!; selectedElementIds,
user.pointer = pointer; },
user.button = button; this.collaborators,
user.selectedElementIds = selectedElementIds; );
user.username = username;
collaborators.set(socketId, user);
this.excalidrawAPI.updateScene({ this.excalidrawAPI.updateScene({
collaborators, collaborators: new Map(collaborators),
}); });
break; break;
} }
case "IDLE_STATUS": { case "IDLE_STATUS": {
const { userState, socketId, username } = decryptedData.payload; const { userState, username, userId } = decryptedData.payload;
const collaborators = new Map(this.collaborators); const collaborators = upsertMap(
const user = collaborators.get(socketId) || {}!; userId,
user.userState = userState; {
user.username = username; username,
userState,
userId,
},
this.collaborators,
);
this.excalidrawAPI.updateScene({ this.excalidrawAPI.updateScene({
collaborators, collaborators: new Map(collaborators),
}); });
break; break;
} }

View File

@ -74,9 +74,6 @@ class Portal {
/* syncAll */ true, /* syncAll */ true,
); );
}); });
this.socket.on("room-user-change", (clients: string[]) => {
this.collab.setCollaborators(clients);
});
} }
isOpen() { isOpen() {
@ -189,13 +186,13 @@ class Portal {
}; };
broadcastIdleChange = (userState: UserIdleState) => { broadcastIdleChange = (userState: UserIdleState) => {
if (this.socket?.id) { if (this.socket) {
const data: SocketUpdateDataSource["IDLE_STATUS"] = { const data: SocketUpdateDataSource["IDLE_STATUS"] = {
type: "IDLE_STATUS", type: "IDLE_STATUS",
payload: { payload: {
socketId: this.socket.id,
userState, userState,
username: this.collab.state.username, username: this.collab.state.username,
userId: this.collab.state.userId,
}, },
}; };
return this._broadcastSocketData( return this._broadcastSocketData(
@ -209,16 +206,16 @@ class Portal {
pointer: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointer"]; pointer: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["pointer"];
button: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["button"]; button: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["button"];
}) => { }) => {
if (this.socket?.id) { if (this.socket) {
const data: SocketUpdateDataSource["MOUSE_LOCATION"] = { const data: SocketUpdateDataSource["MOUSE_LOCATION"] = {
type: "MOUSE_LOCATION", type: "MOUSE_LOCATION",
payload: { payload: {
socketId: this.socket.id,
pointer: payload.pointer, pointer: payload.pointer,
button: payload.button || "up", button: payload.button || "up",
selectedElementIds: selectedElementIds:
this.collab.excalidrawAPI.getAppState().selectedElementIds, this.collab.excalidrawAPI.getAppState().selectedElementIds,
username: this.collab.state.username, username: this.collab.state.username,
userId: this.collab.state.userId,
}, },
}; };
return this._broadcastSocketData( return this._broadcastSocketData(

View File

@ -106,19 +106,19 @@ export type SocketUpdateDataSource = {
MOUSE_LOCATION: { MOUSE_LOCATION: {
type: "MOUSE_LOCATION"; type: "MOUSE_LOCATION";
payload: { payload: {
socketId: string;
pointer: { x: number; y: number }; pointer: { x: number; y: number };
button: "down" | "up"; button: "down" | "up";
selectedElementIds: AppState["selectedElementIds"]; selectedElementIds: AppState["selectedElementIds"];
username: string; username: string;
userId: string;
}; };
}; };
IDLE_STATUS: { IDLE_STATUS: {
type: "IDLE_STATUS"; type: "IDLE_STATUS";
payload: { payload: {
socketId: string;
userState: UserIdleState; userState: UserIdleState;
username: string; username: string;
userId: string;
}; };
}; };
}; };

View File

@ -619,8 +619,8 @@ export const _renderScene = ({
if (renderConfig.remoteSelectedElementIds[element.id]) { if (renderConfig.remoteSelectedElementIds[element.id]) {
selectionColors.push( selectionColors.push(
...renderConfig.remoteSelectedElementIds[element.id].map( ...renderConfig.remoteSelectedElementIds[element.id].map(
(socketId) => { (userId) => {
const background = getClientColor(socketId); const background = getClientColor(userId);
return background; return background;
}, },
), ),

View File

@ -20,6 +20,7 @@ import { unstable_batchedUpdates } from "react-dom";
import { SHAPES } from "./shapes"; import { SHAPES } from "./shapes";
import { isEraserActive, isHandToolActive } from "./appState"; import { isEraserActive, isHandToolActive } from "./appState";
import { ResolutionType } from "./utility-types"; import { ResolutionType } from "./utility-types";
import { reconcileElements } from "./excalidraw-app/collab/reconciliation";
let mockDateTime: string | null = null; let mockDateTime: string | null = null;
@ -907,3 +908,14 @@ export const isOnlyExportingSingleFrame = (
) )
); );
}; };
export const upsertMap = <T>(key: T, value: object, map: Map<T, object>) => {
if (!map.has(key)) {
map.set(key, value);
} else {
const old = map.get(key);
map.set(key, { ...old, ...value });
}
return map;
};