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

View File

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

View File

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

View File

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

View File

@ -20,6 +20,7 @@ import { unstable_batchedUpdates } from "react-dom";
import { SHAPES } from "./shapes";
import { isEraserActive, isHandToolActive } from "./appState";
import { ResolutionType } from "./utility-types";
import { reconcileElements } from "./excalidraw-app/collab/reconciliation";
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;
};