bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/whiteboard/cursors/service.js

109 lines
3.1 KiB
JavaScript
Raw Normal View History

import Auth from '/imports/ui/services/auth';
2022-04-05 22:49:13 +08:00
import Users from '/imports/api/users';
import { throttle } from 'lodash';
import logger from '/imports/startup/client/logger';
const { cursorInterval: CURSOR_INTERVAL } = Meteor.settings.public.whiteboard;
const Cursor = new Mongo.Collection(null);
let cursorStreamListener = null;
export const clearCursors = () => {
Cursor.remove({});
};
const updateCursor = (userId, payload) => {
const selector = {
userId,
whiteboardId: payload.whiteboardId,
};
const modifier = {
$set: {
userId,
...payload,
},
};
return Cursor.upsert(selector, modifier);
};
const publishCursorUpdate = throttle((payload) => {
if (cursorStreamListener) {
cursorStreamListener.emit.bind(cursorStreamListener)('publish', payload);
}
return updateCursor(Auth.userID, payload);
}, CURSOR_INTERVAL);
export const initCursorStreamListener = () => {
logger.info({
logCode: 'init_cursor_stream_listener',
extraInfo: { meetingId: Auth.meetingID, userId: Auth.userID },
}, 'initCursorStreamListener called');
/**
* We create a promise to add the handlers after a ddp subscription stop.
* The problem was caused because we add handlers to stream before the onStop event happens,
* which set the handlers to undefined.
*/
cursorStreamListener = new Meteor.Streamer(`cursor-${Auth.meetingID}`, { retransmit: false });
const startStreamHandlersPromise = new Promise((resolve) => {
const checkStreamHandlersInterval = setInterval(() => {
const streamHandlersSize = Object.values(Meteor.StreamerCentral.instances[`cursor-${Auth.meetingID}`].handlers)
.filter((el) => el !== undefined)
.length;
if (!streamHandlersSize) {
resolve(clearInterval(checkStreamHandlersInterval));
}
}, 250);
});
startStreamHandlersPromise.then(() => {
logger.debug({ logCode: 'cursor_stream_handler_attach' }, 'Attaching handlers for cursor stream');
cursorStreamListener.on('message', ({ cursors }) => {
Object.keys(cursors).forEach((cursorId) => {
const cursor = cursors[cursorId];
const { userId } = cursor;
delete cursor.userId;
if (Auth.userID === userId) return;
updateCursor(userId, cursor);
});
});
});
};
2022-04-05 22:49:13 +08:00
2022-05-07 00:37:43 +08:00
const getCurrentCursors = (whiteboardId) => {
const selector = { whiteboardId };
const filter = {};
const cursors = Cursor.find(selector, filter).fetch();
return cursors.reduce((result, cursor) => {
2022-04-05 22:49:13 +08:00
const { userId } = cursor;
const user = Users.findOne(
{ userId },
{
fields: {
name: 1, presenter: 1, userId: 1, role: 1,
},
},
);
2022-04-05 22:49:13 +08:00
if (user) {
const newCursor = cursor;
newCursor.userName = user.name;
newCursor.userId = user.userId;
newCursor.role = user.role;
newCursor.presenter = user.presenter;
result.push(newCursor);
2022-04-05 22:49:13 +08:00
}
return result;
}, []);
2022-04-05 22:49:13 +08:00
};
export default {
2022-05-07 00:37:43 +08:00
getCurrentCursors,
publishCursorUpdate,
};