transmit awareness
This commit is contained in:
parent
5fbc189884
commit
8bcc16f790
7 changed files with 143 additions and 14 deletions
15
package-lock.json
generated
15
package-lock.json
generated
|
@ -30,6 +30,7 @@
|
|||
"nodemailer": "^6.10.0",
|
||||
"pg": "^8.13.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"randomcolor": "^0.6.2",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rss-parser": "^3.13.0",
|
||||
"socket.io": "^4.8.1",
|
||||
|
@ -53,6 +54,7 @@
|
|||
"@types/node-schedule": "^2.1.6",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/qrcode": "~1.5.5",
|
||||
"@types/randomcolor": "^0.5.9",
|
||||
"@types/speakeasy": "^2.0.10",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"ts-node": "10.7.0",
|
||||
|
@ -480,6 +482,13 @@
|
|||
"integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/randomcolor": {
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/randomcolor/-/randomcolor-0.5.9.tgz",
|
||||
"integrity": "sha512-k58cfpkK15AKn1m+oRd9nh5BnuiowhbyvBBdAzcddtARMr3xRzP0VlFaAKovSG6N6Knx08EicjPlOMzDejerrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/range-parser": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||
|
@ -3471,6 +3480,12 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/randomcolor": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/randomcolor/-/randomcolor-0.6.2.tgz",
|
||||
"integrity": "sha512-Mn6TbyYpFgwFuQ8KJKqf3bqqY9O1y37/0jgSK/61PUxV4QfIMv0+K2ioq8DfOjkBslcjwSzRfIDEXfzA9aCx7A==",
|
||||
"license": "CC0"
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
"nodemailer": "^6.10.0",
|
||||
"pg": "^8.13.1",
|
||||
"qrcode": "^1.5.4",
|
||||
"randomcolor": "^0.6.2",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rss-parser": "^3.13.0",
|
||||
"socket.io": "^4.8.1",
|
||||
|
@ -68,6 +69,7 @@
|
|||
"@types/node-schedule": "^2.1.6",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/qrcode": "~1.5.5",
|
||||
"@types/randomcolor": "^0.5.9",
|
||||
"@types/speakeasy": "^2.0.10",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"ts-node": "10.7.0",
|
||||
|
|
|
@ -19,9 +19,13 @@ export default abstract class MissionDocHelper {
|
|||
// const ytext = ydoc.getText('meinText');
|
||||
// ytext.insert(0, 'Hier ist ein initialer Text');
|
||||
|
||||
const awareness = 0; // TODO Awareness
|
||||
|
||||
MissionMap.write(missionId, { missionId, doc, awareness, timestamp: 0 });
|
||||
MissionMap.write(missionId, {
|
||||
missionId,
|
||||
doc,
|
||||
editors: new Map(),
|
||||
editorStates: new Map(),
|
||||
timestamp: 0,
|
||||
});
|
||||
console.log(`created local doc ${missionId}`);
|
||||
}
|
||||
|
||||
|
@ -40,6 +44,16 @@ export default abstract class MissionDocHelper {
|
|||
return mission.timestamp;
|
||||
}
|
||||
|
||||
public static getAwarenessState(missionId: string) {
|
||||
const mission = MissionMap.read(missionId);
|
||||
return Array.from(mission.editorStates.entries());
|
||||
}
|
||||
|
||||
public static getAwarenessEditors(missionId: string) {
|
||||
const mission = MissionMap.read(missionId);
|
||||
return Array.from(mission.editors.entries());
|
||||
}
|
||||
|
||||
public static async saveDoc(missionId: string, update: Uint8Array) {
|
||||
MissionMap.updateState(missionId, update);
|
||||
const mission = MissionMap.read(missionId);
|
||||
|
|
|
@ -4,10 +4,24 @@ import ms from "ms";
|
|||
export interface missionStoreModel {
|
||||
missionId: string;
|
||||
doc: Y.Doc;
|
||||
awareness: any;
|
||||
editors: Map<string, Editor>;
|
||||
editorStates: Map<string, EditorState>;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export interface Editor {
|
||||
username: string;
|
||||
firstname: string;
|
||||
lastname: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
export interface EditorState {
|
||||
field: string;
|
||||
cursor: any;
|
||||
range: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description store credentials to socket to prevent auth data change while connected
|
||||
*/
|
||||
|
@ -32,12 +46,30 @@ export abstract class MissionMap {
|
|||
this.write(identifier, mission, true);
|
||||
}
|
||||
|
||||
public static updateAwareness(identifier: string, data: any): void {
|
||||
public static updateAwareness(
|
||||
identifier: string,
|
||||
data: { action: "update" | "remove"; socketId: string } & (
|
||||
| { store: "editors"; update: Editor }
|
||||
| { store: "state"; update: EditorState }
|
||||
)
|
||||
): void {
|
||||
this.monitorAccess(identifier);
|
||||
|
||||
let mission = this.read(identifier);
|
||||
|
||||
// TODO save awareness
|
||||
if (data.store == "editors") {
|
||||
if (data.action == "update") {
|
||||
mission.editors.set(data.socketId, data.update);
|
||||
} else {
|
||||
mission.editors.delete(data.socketId);
|
||||
}
|
||||
} else {
|
||||
if (data.action == "update") {
|
||||
mission.editorStates.set(data.socketId, data.update);
|
||||
} else {
|
||||
mission.editorStates.delete(data.socketId);
|
||||
}
|
||||
}
|
||||
|
||||
this.write(identifier, mission, true);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ export interface socketStoreModel {
|
|||
socketId: string;
|
||||
userId: string;
|
||||
username: string;
|
||||
firstname: string;
|
||||
lastname: string;
|
||||
isOwner: string;
|
||||
permissions: PermissionObject;
|
||||
isWebApiRequest: boolean;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { Server, Socket } from "socket.io";
|
||||
import { handleEvent } from "../handleEvent";
|
||||
import { MissionMap, missionStoreModel } from "../../storage/missionMap";
|
||||
import { EditorState, MissionMap, missionStoreModel } from "../../storage/missionMap";
|
||||
import * as Y from "yjs";
|
||||
import MissionDocHelper from "../../helpers/missionDocHelper";
|
||||
import randomColor from "randomcolor";
|
||||
import { SocketMap } from "../../storage/socketMap";
|
||||
|
||||
export default (io: Server, socket: Socket) => {
|
||||
socket.on(
|
||||
|
@ -45,9 +47,36 @@ export default (io: Server, socket: Socket) => {
|
|||
});
|
||||
}
|
||||
|
||||
socket.emit("package-sync-awareness", {
|
||||
update: [], // do awareness self
|
||||
source: "server",
|
||||
console.log(MissionDocHelper.getAwarenessEditors(missionId));
|
||||
socket.emit("package-init-awareness", {
|
||||
update: MissionDocHelper.getAwarenessEditors(missionId),
|
||||
type: "editors",
|
||||
});
|
||||
socket.emit("package-init-awareness", {
|
||||
update: MissionDocHelper.getAwarenessState(missionId),
|
||||
type: "state",
|
||||
});
|
||||
|
||||
let newEditor = {
|
||||
socketId: socket.id,
|
||||
data: {
|
||||
username: SocketMap.read(socket.id).username,
|
||||
firstname: SocketMap.read(socket.id).firstname,
|
||||
lastname: SocketMap.read(socket.id).lastname,
|
||||
color: randomColor({ format: "hex" }),
|
||||
},
|
||||
};
|
||||
MissionMap.updateAwareness(missionId, {
|
||||
action: "update",
|
||||
socketId: newEditor.socketId,
|
||||
store: "editors",
|
||||
update: newEditor.data,
|
||||
});
|
||||
socket.to(missionId).emit("package-sync-awareness", {
|
||||
update: newEditor.data,
|
||||
socketId: socket.id,
|
||||
action: "update",
|
||||
type: "editors",
|
||||
});
|
||||
|
||||
return {
|
||||
|
@ -124,16 +153,23 @@ export default (io: Server, socket: Socket) => {
|
|||
"mission:sync-client-awareness",
|
||||
handleEvent(
|
||||
{ type: "create", section: "operation", module: "mission" },
|
||||
async (data: { update: Array<number>; timestamp: number }) => {
|
||||
async (data: EditorState) => {
|
||||
const socketRooms = Array.from(socket.rooms).filter((room) => room !== socket.id && room !== "home");
|
||||
try {
|
||||
MissionMap.updateAwareness(socketRooms[0], new Uint8Array(data.update));
|
||||
MissionMap.updateAwareness(socketRooms[0], {
|
||||
action: "update",
|
||||
store: "state",
|
||||
update: data,
|
||||
socketId: socket.id,
|
||||
});
|
||||
|
||||
return {
|
||||
type: "package-sync-awareness",
|
||||
answer: {
|
||||
update: data.update,
|
||||
source: socket.id,
|
||||
type: "state",
|
||||
action: "update",
|
||||
update: data,
|
||||
socketId: socket.id,
|
||||
},
|
||||
room: socketRooms[0],
|
||||
};
|
||||
|
@ -163,6 +199,32 @@ export default (io: Server, socket: Socket) => {
|
|||
MissionMap.delete(socketRooms[0]);
|
||||
}
|
||||
|
||||
MissionMap.updateAwareness(socketRooms[0], {
|
||||
action: "remove",
|
||||
store: "editors",
|
||||
update: undefined,
|
||||
socketId: socket.id,
|
||||
});
|
||||
io.to(socketRooms[0]).emit("package-sync-awareness", {
|
||||
type: "editors",
|
||||
update: undefined,
|
||||
action: "remove",
|
||||
socketId: socket.id,
|
||||
});
|
||||
|
||||
MissionMap.updateAwareness(socketRooms[0], {
|
||||
action: "remove",
|
||||
store: "state",
|
||||
update: undefined,
|
||||
socketId: socket.id,
|
||||
});
|
||||
io.to(socketRooms[0]).emit("package-sync-awareness", {
|
||||
type: "state",
|
||||
update: undefined,
|
||||
action: "remove",
|
||||
socketId: socket.id,
|
||||
});
|
||||
|
||||
return {
|
||||
type: "deleted",
|
||||
answer: "leave instance",
|
||||
|
|
|
@ -39,6 +39,8 @@ export default async function authenticateSocket(socket: Socket, next: Function)
|
|||
socketId: socket.id,
|
||||
userId: decoded.userId,
|
||||
username: decoded.username,
|
||||
firstname: decoded.firstname,
|
||||
lastname: decoded.lastname,
|
||||
isOwner: decoded.isOwner,
|
||||
permissions: decoded.permissions,
|
||||
isWebApiRequest: decoded?.sub == "webapi_access_token",
|
||||
|
|
Loading…
Add table
Reference in a new issue