feat: use userId instead of socketId
This commit is contained in:
parent
62df03d78d
commit
2bdf09153c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
12
src/utils.ts
12
src/utils.ts
@ -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;
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user