Merge branch 'bbb-2x-mconf' of github.com:bigbluebutton/bigbluebutton into pods_vol1
This commit is contained in:
commit
5a08c0cfca
@ -256,6 +256,14 @@ package org.bigbluebutton.modules.layout.managers
|
||||
var newLayout:LayoutDefinition = _layoutModel.getLayout(name);
|
||||
if (newLayout == null) return;
|
||||
|
||||
var logData:Object = UsersUtil.initLogData();
|
||||
logData.reason = "Layout changed.";
|
||||
logData.tags = ["layout"];
|
||||
logData.message = "The layout was changed.";
|
||||
logData.oldLayout = _currentLayout.name;
|
||||
logData.newLayout = newLayout.name;
|
||||
LOGGER.info(JSON.stringify(logData));
|
||||
|
||||
//trace(LOG + " applying layout [" + newLayout.name + "] to windows.");
|
||||
applyLayout(newLayout);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@
|
||||
content: "\e91e";
|
||||
}
|
||||
.icon-bbb-rectangle_tool:before {
|
||||
content: "\e92f";
|
||||
content: "\e91f";
|
||||
}
|
||||
.icon-bbb-text_tool:before {
|
||||
content: "\e920";
|
||||
|
0
bigbluebutton-html5/imports/api/1.1/chat/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/chat/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/chat/server/methods/sendChat.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/chat/server/methods/sendChat.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/chat/server/modifiers/addChat.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/chat/server/modifiers/addChat.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/chat/server/modifiers/clearChats.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/chat/server/modifiers/clearChats.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/index.js
Executable file → Normal file
@ -0,0 +1,43 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
// import { isAllowedTo } from '/imports/startup/server/userPermissions';
|
||||
import Presentations from '/imports/api/1.1/presentations';
|
||||
|
||||
export default function publishCursorUpdate(credentials, coordinates) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toBBBApps.presentation;
|
||||
const EVENT_NAME = 'send_cursor_update';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(coordinates, {
|
||||
xPercent: Number,
|
||||
yPercent: Number,
|
||||
});
|
||||
|
||||
// if (!isAllowedTo('moveCursor', credentials)) {
|
||||
// throw new Meteor.Error('not-allowed', `You are not allowed to move the Cursor`);
|
||||
// }
|
||||
|
||||
const Presentation = Presentations.findOne({
|
||||
meetingId,
|
||||
'presentation.current': true,
|
||||
});
|
||||
|
||||
if (!Presentation) {
|
||||
throw new Meteor.Error(
|
||||
'presentation-not-found', 'You need a presentation to be able to move the cursor');
|
||||
}
|
||||
|
||||
const payload = {
|
||||
x_percent: coordinates.xPercent,
|
||||
meeting_id: meetingId,
|
||||
y_percent: coordinates.yPercent,
|
||||
};
|
||||
|
||||
return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
|
||||
}
|
0
bigbluebutton-html5/imports/api/1.1/cursor/server/modifiers/clearCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/server/modifiers/clearCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/server/modifiers/initializeCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/server/modifiers/initializeCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/server/modifiers/updateCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/server/modifiers/updateCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/cursor/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/eventHandlers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/eventHandlers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/handlers/incomingDeskshareEvent.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/handlers/incomingDeskshareEvent.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/modifiers/clearDeskshareCollection.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/modifiers/clearDeskshareCollection.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/modifiers/modifyDeskshareStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/modifiers/modifyDeskshareStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/deskshare/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/server/modifiers/addMeeting.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/server/modifiers/addMeeting.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/server/modifiers/clearMeetings.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/server/modifiers/clearMeetings.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/server/modifiers/removeMeeting.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/meetings/server/modifiers/removeMeeting.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/server/modifiers/addPresentation.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/server/modifiers/addPresentation.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/server/modifiers/clearPresentations.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/server/modifiers/clearPresentations.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/presentations/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/shapes/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/shapes/index.js
Executable file → Normal file
@ -1,4 +1,3 @@
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
import clearShapesWhiteboard from '../modifiers/clearShapesWhiteboard';
|
||||
|
@ -1,4 +1,3 @@
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { check } from 'meteor/check';
|
||||
import { inReplyToHTML5Client } from '/imports/api/common/server/helpers';
|
||||
import Shapes from './../../';
|
||||
@ -30,6 +29,4 @@ export default function handleWhiteboardGetReply({ payload }) {
|
||||
const whiteboardId = shape.wb_id;
|
||||
shapesAdded.push(addShape(meetingId, whiteboardId, shape));
|
||||
});
|
||||
|
||||
return shapesAdded;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
import addShape from '../modifiers/addShape';
|
||||
|
@ -1,4 +1,3 @@
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
import removeShape from '../modifiers/removeShape';
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import sendAnnotation from './methods/sendAnnotation';
|
||||
|
||||
Meteor.methods({
|
||||
sendAnnotation,
|
||||
});
|
||||
|
@ -0,0 +1,24 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
export default function clearWhiteboard(credentials, whiteboardId) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toBBBApps.whiteboard;
|
||||
const EVENT_NAME = 'clear_whiteboard_request';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(whiteboardId, String);
|
||||
|
||||
const payload = {
|
||||
requester_id: requesterUserId,
|
||||
meeting_id: meetingId,
|
||||
whiteboard_id: whiteboardId,
|
||||
};
|
||||
|
||||
return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
|
||||
export default function sendAnnotation(credentials, payload) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toBBBApps.whiteboard;
|
||||
const EVENT_NAME = 'send_whiteboard_annotation_request';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(payload, Object);
|
||||
|
||||
payload.annotation.id = `${requesterUserId}-${payload.annotation.id}`;
|
||||
payload.requester_id = requesterUserId;
|
||||
payload.meeting_id = meetingId;
|
||||
|
||||
return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
import RedisPubSub from '/imports/startup/server/redis';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
export default function undoAnnotation(credentials, whiteboardId) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toBBBApps.whiteboard;
|
||||
const EVENT_NAME = 'undo_whiteboard_request';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(whiteboardId, String);
|
||||
|
||||
const payload = {
|
||||
requester_id: requesterUserId,
|
||||
meeting_id: meetingId,
|
||||
whiteboard_id: whiteboardId,
|
||||
};
|
||||
|
||||
return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { check } from 'meteor/check';
|
||||
import Shapes from './../../';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Shapes from './../../';
|
||||
|
||||
|
||||
const SHAPE_TYPE_TEXT = 'text';
|
||||
const SHAPE_TYPE_POLL_RESULT = 'poll_result';
|
||||
@ -26,6 +27,7 @@ export default function addShape(meetingId, whiteboardId, shape) {
|
||||
'shape.shape.type': shape.shape.type,
|
||||
'shape.shape.status': shape.shape.status,
|
||||
},
|
||||
$inc: { 'shape.shape.version': 1 },
|
||||
};
|
||||
|
||||
const shapeType = shape.shape_type;
|
||||
@ -49,6 +51,7 @@ export default function addShape(meetingId, whiteboardId, shape) {
|
||||
|
||||
case SHAPE_TYPE_POLL_RESULT:
|
||||
shape.shape.result = JSON.parse(shape.shape.result);
|
||||
break;
|
||||
|
||||
default:
|
||||
modifier.$set = Object.assign(modifier.$set, {
|
||||
|
2
bigbluebutton-html5/imports/api/1.1/shapes/server/modifiers/clearShapes.js
Executable file → Normal file
2
bigbluebutton-html5/imports/api/1.1/shapes/server/modifiers/clearShapes.js
Executable file → Normal file
@ -1,5 +1,5 @@
|
||||
import Shapes from './../../';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Shapes from './../../';
|
||||
|
||||
export default function clearShapes(meetingId) {
|
||||
if (meetingId) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Shapes from './../../';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Shapes from './../../';
|
||||
|
||||
export default function clearShapesWhiteboard(meetingId, whiteboardId) {
|
||||
check(meetingId, String);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { check } from 'meteor/check';
|
||||
import Shapes from './../../';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Shapes from './../../';
|
||||
|
||||
export default function removeShape(meetingId, whiteboardId, shapeId) {
|
||||
check(meetingId, String);
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Shapes from './../';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import mapToAcl from '/imports/startup/mapToAcl';
|
||||
import Shapes from './../';
|
||||
|
||||
function shapes(credentials) {
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
0
bigbluebutton-html5/imports/api/1.1/slides/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/index.js
Executable file → Normal file
@ -1,3 +1,4 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
|
||||
Meteor.methods();
|
||||
Meteor.methods({
|
||||
});
|
||||
|
0
bigbluebutton-html5/imports/api/1.1/slides/server/methods/switchSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/methods/switchSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/addSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/addSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/changeCurrentSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/changeCurrentSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/clearSlides.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/clearSlides.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/resizeSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/slides/server/modifiers/resizeSlide.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/handlers/emojiStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/handlers/emojiStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/handlers/lockedStatusChange.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/handlers/lockedStatusChange.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/handlers/validateAuthToken.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/handlers/validateAuthToken.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/assignPresenter.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/assignPresenter.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/kickUser.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/kickUser.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/listenOnlyToggle.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/listenOnlyToggle.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/muteToggle.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/muteToggle.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/setEmojiStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/setEmojiStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/userLeaving.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/userLeaving.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/userLogout.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/userLogout.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/validateAuthToken.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/methods/validateAuthToken.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/clearUsers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/clearUsers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/createDummyUser.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/createDummyUser.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/lockAllViewersMic.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/lockAllViewersMic.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/setConnectionStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/setConnectionStatus.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/updateVoiceUser.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/modifiers/updateVoiceUser.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/1.1/users/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/annotations/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/annotations/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/annotations/server/eventHandlers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/annotations/server/eventHandlers.js
Executable file → Normal file
14
bigbluebutton-html5/imports/api/2.0/annotations/server/handlers/whiteboardAnnotations.js
Executable file → Normal file
14
bigbluebutton-html5/imports/api/2.0/annotations/server/handlers/whiteboardAnnotations.js
Executable file → Normal file
@ -1,24 +1,16 @@
|
||||
import _ from 'lodash';
|
||||
import { check } from 'meteor/check';
|
||||
import Annotations from '/imports/api/2.0/annotations';
|
||||
import clearAnnotations from '../modifiers/clearAnnotations';
|
||||
import addAnnotation from '../modifiers/addAnnotation';
|
||||
import removeAnnotation from '../modifiers/removeAnnotation';
|
||||
|
||||
export default function handleWhiteboardAnnotations({ body }, meetingId) {
|
||||
check(meetingId, String);
|
||||
check(body, Object);
|
||||
|
||||
const { annotations, whiteboardId } = body;
|
||||
const annotationIds = annotations.map(a => a.id);
|
||||
const annotationsToRemove = Annotations.find({
|
||||
meetingId,
|
||||
wbId: whiteboardId,
|
||||
'annotationInfo.id': { $nin: annotationIds },
|
||||
}).fetch();
|
||||
|
||||
_.each(annotationsToRemove, (annotation) => {
|
||||
removeAnnotation(meetingId, annotation.whiteboardId, annotation.annotationInfo.id);
|
||||
});
|
||||
check(whiteboardId, String);
|
||||
clearAnnotations(meetingId, whiteboardId);
|
||||
|
||||
const annotationsAdded = [];
|
||||
_.each(annotations, (annotation) => {
|
||||
|
@ -3,9 +3,17 @@ import { check } from 'meteor/check';
|
||||
import clearAnnotations from '../modifiers/clearAnnotations';
|
||||
|
||||
export default function handleWhiteboardCleared({ body }, meetingId) {
|
||||
const whiteboardId = body.whiteboardId;
|
||||
check(body, {
|
||||
userId: String,
|
||||
whiteboardId: String,
|
||||
fullClear: Boolean,
|
||||
});
|
||||
|
||||
check(whiteboardId, String);
|
||||
const { whiteboardId, fullClear, userId } = body;
|
||||
|
||||
if (fullClear) {
|
||||
return clearAnnotations(meetingId, whiteboardId);
|
||||
}
|
||||
|
||||
return clearAnnotations(meetingId, whiteboardId, userId);
|
||||
}
|
||||
|
@ -1,4 +1,10 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import mapToAcl from '/imports/startup/mapToAcl';
|
||||
import undoAnnotation from './methods/undoAnnotation';
|
||||
import clearWhiteboard from './methods/clearWhiteboard';
|
||||
import sendAnnotation from './methods/sendAnnotation';
|
||||
|
||||
Meteor.methods();
|
||||
Meteor.methods({
|
||||
undoAnnotation,
|
||||
clearWhiteboard,
|
||||
sendAnnotation,
|
||||
});
|
||||
|
@ -0,0 +1,31 @@
|
||||
import Acl from '/imports/startup/acl';
|
||||
import { getMultiUserStatus } from '/imports/api/common/server/helpers';
|
||||
import RedisPubSub from '/imports/startup/server/redis2x';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
export default function clearWhiteboard(credentials, whiteboardId) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||
const EVENT_NAME = 'ClearWhiteboardPubMsg';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(whiteboardId, String);
|
||||
|
||||
const allowed = Acl.can('methods.clearWhiteboard', credentials) || getMultiUserStatus(meetingId);
|
||||
if (!allowed) {
|
||||
throw new Meteor.Error(
|
||||
'not-allowed', `User ${requesterUserId} is not allowed to clear the whiteboard`,
|
||||
);
|
||||
}
|
||||
|
||||
const payload = {
|
||||
whiteboardId,
|
||||
};
|
||||
|
||||
return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
import Acl from '/imports/startup/acl';
|
||||
import { getMultiUserStatus } from '/imports/api/common/server/helpers';
|
||||
import RedisPubSub from '/imports/startup/server/redis2x';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
import Annotations from '/imports/api/2.0/annotations';
|
||||
|
||||
function isLastMessage(annotation, userId) {
|
||||
if (annotation.status === 'DRAW_END') {
|
||||
const selector = {
|
||||
id: annotation.id,
|
||||
userId,
|
||||
};
|
||||
|
||||
const _annotation = Annotations.findOne(selector);
|
||||
return _annotation !== null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export default function sendAnnotation(credentials, annotation) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||
const EVENT_NAME = 'SendWhiteboardAnnotationPubMsg';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(annotation, Object);
|
||||
|
||||
// We allow messages to pass through in 3 cases:
|
||||
// 1. When it's a standard message in presenter mode (Acl check)
|
||||
// 2. When it's a standard message in multi-user mode (getMultUserStatus check)
|
||||
// 3. When it's the last message, happens when the user is currently drawing
|
||||
// and then slide/presentation changes, the user lost presenter rights,
|
||||
// or multi-user whiteboard gets turned off
|
||||
// So we allow the last "DRAW_END" message to pass through, to finish the shape.
|
||||
const allowed = Acl.can('methods.sendAnnotation', credentials) ||
|
||||
getMultiUserStatus(meetingId) ||
|
||||
isLastMessage(annotation, requesterUserId);
|
||||
|
||||
if (!allowed) {
|
||||
throw new Meteor.Error(
|
||||
'not-allowed', `User ${requesterUserId} is not allowed to send an annotation`,
|
||||
);
|
||||
}
|
||||
|
||||
const payload = {
|
||||
annotation,
|
||||
};
|
||||
|
||||
return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
import Acl from '/imports/startup/acl';
|
||||
import { getMultiUserStatus } from '/imports/api/common/server/helpers';
|
||||
import RedisPubSub from '/imports/startup/server/redis2x';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
export default function undoAnnotation(credentials, whiteboardId) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||
const EVENT_NAME = 'UndoWhiteboardPubMsg';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(whiteboardId, String);
|
||||
|
||||
const allowed = Acl.can('methods.undoAnnotation', credentials) || getMultiUserStatus(meetingId);
|
||||
if (!allowed) {
|
||||
throw new Meteor.Error(
|
||||
'not-allowed', `User ${requesterUserId} is not allowed to undo the annotation`,
|
||||
);
|
||||
}
|
||||
|
||||
const payload = {
|
||||
whiteboardId,
|
||||
};
|
||||
|
||||
return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Match, check } from 'meteor/check';
|
||||
import { check } from 'meteor/check';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
import Annotations from '/imports/api/2.0/annotations';
|
||||
|
||||
@ -8,50 +8,17 @@ const ANNOTATION_TYPE_PENCIL = 'pencil';
|
||||
export default function addAnnotation(meetingId, whiteboardId, userId, annotation) {
|
||||
check(meetingId, String);
|
||||
check(whiteboardId, String);
|
||||
check(annotation, {
|
||||
id: String,
|
||||
status: String,
|
||||
annotationType: String,
|
||||
annotationInfo: {
|
||||
x: Match.Maybe(Number), // Text Annotation Only.
|
||||
y: Match.Maybe(Number), // Text Annotation Only.
|
||||
text: Match.Maybe(String), // Text Annotation Only.
|
||||
fontColor: Match.Maybe(Number), // Text Annotation Only.
|
||||
calcedFontSize: Match.Maybe(Number), // Text Annotation Only.
|
||||
textBoxWidth: Match.Maybe(Number), // Text Annotation Only.
|
||||
textBoxHeight: Match.Maybe(Number), // Text Annotation Only.
|
||||
fontSize: Match.Maybe(Number), // Text Annotation Only.
|
||||
dataPoints: Match.Maybe(String), // Text Annotation Only.
|
||||
color: Match.Maybe(Number), // Draw Annotation Only.
|
||||
thickness: Match.Maybe(Number), // Draw Annotation Only.
|
||||
transparency: Match.Maybe(Boolean), // Draw Annotation Only.
|
||||
points: Match.Maybe([Number]), // Draw and Poll Annotation Only.
|
||||
numResponders: Match.Maybe(Number), // Poll Only Annotation.
|
||||
result: Match.Maybe([{
|
||||
id: Number,
|
||||
key: String,
|
||||
numVotes: Number,
|
||||
}]), // Poll Only Annotation.
|
||||
numRespondents: Match.Maybe(Number), // Poll Only Annotation.
|
||||
id: String,
|
||||
whiteboardId: String,
|
||||
status: String,
|
||||
type: String,
|
||||
commands: Match.Maybe([Number]),
|
||||
},
|
||||
wbId: String,
|
||||
userId: String,
|
||||
position: Number,
|
||||
});
|
||||
check(annotation, Object);
|
||||
|
||||
const { id, status, annotationType, annotationInfo, wbId, position } = annotation;
|
||||
|
||||
const selector = {
|
||||
meetingId,
|
||||
id: annotation.id,
|
||||
id,
|
||||
userId,
|
||||
};
|
||||
|
||||
// annotationInfo will be added to the modifier in switch below, depending on the situation
|
||||
const modifier = {
|
||||
$set: {
|
||||
whiteboardId,
|
||||
@ -59,28 +26,38 @@ export default function addAnnotation(meetingId, whiteboardId, userId, annotatio
|
||||
id,
|
||||
status,
|
||||
annotationType,
|
||||
annotationInfo,
|
||||
wbId,
|
||||
position,
|
||||
},
|
||||
$inc: { version: 1 },
|
||||
};
|
||||
|
||||
const shapeType = annotation.annotationType;
|
||||
|
||||
switch (shapeType) {
|
||||
case ANNOTATION_TYPE_TEXT:
|
||||
// Replace flash new lines to html5 new lines if it's text
|
||||
modifier.$set.annotationInfo = annotationInfo;
|
||||
modifier.$set.annotationInfo.text = annotation.annotationInfo.text.replace(/[\r]/g, '\n');
|
||||
break;
|
||||
case ANNOTATION_TYPE_PENCIL:
|
||||
// On the draw_end he send us all the points, we don't need to push, we can simple
|
||||
// set the new points.
|
||||
if (annotation.status !== 'DRAW_END') {
|
||||
// We don't want it to be update twice.
|
||||
delete modifier.$set.annotationInfo;
|
||||
modifier.$push = { 'annotationInfo.points': { $each: annotation.annotationInfo.points } };
|
||||
// In the pencil draw update we need to add a coordinate to the existing array
|
||||
// And update te rest of the properties
|
||||
if (annotation.status === 'DRAW_UPDATE') {
|
||||
modifier.$set['annotationInfo.color'] = annotationInfo.color;
|
||||
modifier.$set['annotationInfo.thickness'] = annotationInfo.thickness;
|
||||
modifier.$set['annotationInfo.id'] = annotationInfo.id;
|
||||
modifier.$set['annotationInfo.whiteboardId'] = annotationInfo.whiteboardId;
|
||||
modifier.$set['annotationInfo.status'] = annotationInfo.status;
|
||||
modifier.$set['annotationInfo.transparency'] = annotationInfo.transparency;
|
||||
modifier.$push = { 'annotationInfo.points': { $each: annotationInfo.points } };
|
||||
break;
|
||||
}
|
||||
|
||||
modifier.$set.annotationInfo = annotationInfo;
|
||||
break;
|
||||
default:
|
||||
modifier.$set.annotationInfo = annotationInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
|
36
bigbluebutton-html5/imports/api/2.0/annotations/server/modifiers/clearAnnotations.js
Executable file → Normal file
36
bigbluebutton-html5/imports/api/2.0/annotations/server/modifiers/clearAnnotations.js
Executable file → Normal file
@ -1,12 +1,36 @@
|
||||
import Annotations from '/imports/api/2.0/annotations';
|
||||
import Logger from '/imports/startup/server/logger';
|
||||
|
||||
export default function clearAnnotations(meetingId, whiteboardId) {
|
||||
if (meetingId && whiteboardId) {
|
||||
return Annotations.remove({ meetingId, whiteboardId }, Logger.info(`Cleared Annotations from whiteboard ${whiteboardId} (${meetingId})`));
|
||||
} else if (meetingId) {
|
||||
return Annotations.remove({ meetingId }, Logger.info(`Cleared Annotations (${meetingId})`));
|
||||
export default function clearAnnotations(meetingId, whiteboardId, userId) {
|
||||
const selector = {};
|
||||
|
||||
if (meetingId) {
|
||||
selector.meetingId = meetingId;
|
||||
}
|
||||
|
||||
return Annotations.remove({}, Logger.info('Cleared Annotations (all)'));
|
||||
if (whiteboardId) {
|
||||
selector.whiteboardId = whiteboardId;
|
||||
}
|
||||
|
||||
if (userId) {
|
||||
selector.userId = userId;
|
||||
}
|
||||
|
||||
const cb = (err) => {
|
||||
if (err) {
|
||||
return Logger.error(`Removing Shapes2x from collection: ${err}`);
|
||||
}
|
||||
|
||||
if (!meetingId) {
|
||||
return Logger.info('Cleared Annotations (all)');
|
||||
}
|
||||
|
||||
if (userId) {
|
||||
return Logger.info(`Removed Shapes2x for userId=${userId} where whiteboard=${whiteboardId}`);
|
||||
}
|
||||
|
||||
return Logger.info(`Removed Shapes2x where whiteboard=${whiteboardId}`);
|
||||
};
|
||||
|
||||
return Annotations.remove(selector, cb);
|
||||
}
|
||||
|
0
bigbluebutton-html5/imports/api/2.0/audio/client/bridge/sip.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/audio/client/bridge/sip.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/audio/client/manager/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/audio/client/manager/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/bbb/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/bbb/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/chat/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/chat/index.js
Executable file → Normal file
@ -15,5 +15,5 @@ export default function clearPublicChatHistory(credentials) {
|
||||
|
||||
const payload = {};
|
||||
|
||||
return RedisPubSub.publish(CHANNEL, eventName, meetingId, payload, { userId: requesterUserId });
|
||||
return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, payload);
|
||||
}
|
||||
|
@ -50,5 +50,5 @@ export default function sendChat(credentials, message) {
|
||||
eventName = 'SendPublicMessagePubMsg';
|
||||
}
|
||||
|
||||
return RedisPubSub.publish(CHANNEL, eventName, meetingId, { message: parsedMessage }, { userId: requesterUserId });
|
||||
return RedisPubSub.publishUserMessage(CHANNEL, eventName, meetingId, requesterUserId, { message: parsedMessage });
|
||||
}
|
||||
|
0
bigbluebutton-html5/imports/api/2.0/chat/server/modifiers/addChat.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/chat/server/modifiers/addChat.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/chat/server/modifiers/clearChats.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/chat/server/modifiers/clearChats.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/index.js
Executable file → Normal file
@ -1,4 +1,6 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import publishCursorUpdate from './methods/publishCursorUpdate';
|
||||
|
||||
Meteor.methods({
|
||||
publishCursorUpdate,
|
||||
});
|
||||
|
@ -0,0 +1,31 @@
|
||||
import { getMultiUserStatus } from '/imports/api/common/server/helpers';
|
||||
import RedisPubSub from '/imports/startup/server/redis2x';
|
||||
import Acl from '/imports/startup/acl';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
|
||||
|
||||
export default function publishCursorUpdate(credentials, payload) {
|
||||
const REDIS_CONFIG = Meteor.settings.redis;
|
||||
const CHANNEL = REDIS_CONFIG.channels.toAkkaApps;
|
||||
const EVENT_NAME = 'SendCursorPositionPubMsg';
|
||||
|
||||
const { meetingId, requesterUserId, requesterToken } = credentials;
|
||||
|
||||
check(meetingId, String);
|
||||
check(requesterUserId, String);
|
||||
check(requesterToken, String);
|
||||
check(payload, {
|
||||
xPercent: Number,
|
||||
yPercent: Number,
|
||||
});
|
||||
|
||||
const allowed = Acl.can('methods.moveCursor', credentials) || getMultiUserStatus(meetingId);
|
||||
if (!allowed) {
|
||||
throw new Meteor.Error(
|
||||
'not-allowed', `User ${requesterUserId} is not allowed to move the cursor`,
|
||||
);
|
||||
}
|
||||
|
||||
return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||
}
|
0
bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/clearCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/clearCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/initializeCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/initializeCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/updateCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/server/modifiers/updateCursor.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/cursor/server/publishers.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/meetings/index.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/meetings/index.js
Executable file → Normal file
@ -1,6 +1,5 @@
|
||||
import changeLockSettings from '../modifiers/changeLockSettings';
|
||||
|
||||
export default function handleLockSettingsInMeeting({ body }, meetingId) {
|
||||
|
||||
return changeLockSettings(meetingId, body);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import changeUserLock from '../modifiers/changeUserLock';
|
||||
|
||||
export default function handleLockSettingsInMeeting({ body }, meetingId) {
|
||||
|
||||
return changeUserLock(meetingId, body);
|
||||
}
|
||||
|
0
bigbluebutton-html5/imports/api/2.0/meetings/server/methods.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/meetings/server/methods.js
Executable file → Normal file
8
bigbluebutton-html5/imports/api/2.0/meetings/server/methods/endMeeting.js
Executable file → Normal file
8
bigbluebutton-html5/imports/api/2.0/meetings/server/methods/endMeeting.js
Executable file → Normal file
@ -18,13 +18,7 @@ export default function endMeeting(credentials) {
|
||||
userId: requesterUserId,
|
||||
};
|
||||
|
||||
const header = {
|
||||
meetingId,
|
||||
name: EVENT_NAME,
|
||||
userId: requesterUserId,
|
||||
};
|
||||
|
||||
Logger.verbose(`Meeting '${meetingId}' is destroyed by '${requesterUserId}'`);
|
||||
|
||||
return RedisPubSub.publish(CHANNEL, EVENT_NAME, meetingId, payload, header);
|
||||
return RedisPubSub.publishUserMessage(CHANNEL, EVENT_NAME, meetingId, requesterUserId, payload);
|
||||
}
|
||||
|
0
bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/addMeeting.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/addMeeting.js
Executable file → Normal file
@ -16,7 +16,7 @@ export default function changeLockSettings(meetingId, payload) {
|
||||
});
|
||||
|
||||
const selector = {
|
||||
meetingId
|
||||
meetingId,
|
||||
};
|
||||
|
||||
const modifier = {
|
||||
@ -25,11 +25,15 @@ export default function changeLockSettings(meetingId, payload) {
|
||||
},
|
||||
};
|
||||
|
||||
const cb = (err) => {
|
||||
const cb = (err, numChanged) => {
|
||||
if (err) {
|
||||
return Logger.error(`Changing meeting={${meetingId}} lock settings: ${err}`);
|
||||
}
|
||||
|
||||
if (numChanged) {
|
||||
return Logger.error(`Changed meeting={${meetingId}} updated lock settings`);
|
||||
}
|
||||
};
|
||||
|
||||
return Meetings.upsert(selector, modifier, cb);
|
||||
};
|
||||
}
|
||||
|
@ -27,4 +27,4 @@ export default function changeUserLock(meetingId, payload) {
|
||||
};
|
||||
|
||||
return Users.upsert(selector, modifier, cb);
|
||||
};
|
||||
}
|
||||
|
0
bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/removeMeeting.js
Executable file → Normal file
0
bigbluebutton-html5/imports/api/2.0/meetings/server/modifiers/removeMeeting.js
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user