From 1df46bb201d506af6949af8699995d67086985d9 Mon Sep 17 00:00:00 2001 From: Oswaldo Acauan <oswaldoacauan@gmail.com> Date: Fri, 11 Nov 2016 19:02:46 +0000 Subject: [PATCH] Refactor of Presentations API --- .../server/modifiers/clearMeetings.js | 9 +- .../server/modifiers/removeMeeting.js | 9 +- .../api/presentations/server/eventHandlers.js | 8 ++ .../server/handlers/presentationChange.js | 44 +++++++++ .../server/handlers/presentationInfoReply.js | 24 +++++ .../server/handlers/presentationRemove.js | 14 +++ .../imports/api/presentations/server/index.js | 3 + .../api/presentations/server/methods.js | 4 + .../server/modifiers/addPresentation.js | 55 +++++++++++ .../modifiers/addPresentationToCollection.js | 23 ----- .../modifiers/changeCurrentPresentation.js | 53 ++++++++++ .../server/modifiers/clearPresentations.js | 11 +++ .../modifiers/clearPresentationsCollection.js | 14 --- .../server/modifiers/eventHandlers.js | 96 ------------------- .../server/modifiers/removePresentation.js | 28 ++++++ .../removePresentationFromCollection.js | 17 ---- .../api/presentations/server/publications.js | 10 -- .../api/presentations/server/publishers.js | 22 +++++ .../{addSlideToCollection.js => addSlide.js} | 55 ++++++++--- .../server/modifiers/changeCurrentSlide.js | 6 +- ...learSlidesCollection.js => clearSlides.js} | 2 +- .../modifiers/clearSlidesPresentation.js | 4 +- .../slides/server/modifiers/resizeSlide.js | 16 ++-- .../imports/api/slides/server/publishers.js | 2 +- .../ui/components/whiteboard/container.jsx | 10 +- .../ui/components/whiteboard/service.js | 69 +++++++------ bigbluebutton-html5/server/main.js | 6 +- 27 files changed, 372 insertions(+), 242 deletions(-) create mode 100644 bigbluebutton-html5/imports/api/presentations/server/eventHandlers.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/handlers/presentationChange.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/handlers/presentationInfoReply.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/handlers/presentationRemove.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/index.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/methods.js create mode 100755 bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js delete mode 100755 bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentationToCollection.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/modifiers/changeCurrentPresentation.js create mode 100755 bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js delete mode 100755 bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentationsCollection.js delete mode 100755 bigbluebutton-html5/imports/api/presentations/server/modifiers/eventHandlers.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentation.js delete mode 100755 bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentationFromCollection.js delete mode 100755 bigbluebutton-html5/imports/api/presentations/server/publications.js create mode 100644 bigbluebutton-html5/imports/api/presentations/server/publishers.js rename bigbluebutton-html5/imports/api/slides/server/modifiers/{addSlideToCollection.js => addSlide.js} (52%) rename bigbluebutton-html5/imports/api/slides/server/modifiers/{clearSlidesCollection.js => clearSlides.js} (83%) diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/clearMeetings.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/clearMeetings.js index 627b149114..65e2e45fdc 100755 --- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/clearMeetings.js +++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/clearMeetings.js @@ -5,13 +5,12 @@ import removeMeeting from './removeMeeting'; import { clearUsersCollection } from '/imports/api/users/server/modifiers/clearUsersCollection'; import clearChats from '/imports/api/chat/server/modifiers/clearChats'; import { clearShapesCollection } from '/imports/api/shapes/server/modifiers/clearShapesCollection'; -import { clearSlidesCollection } from '/imports/api/slides/server/modifiers/clearSlidesCollection'; +import clearSlides from '/imports/api/slides/server/modifiers/clearSlides'; import { clearPollCollection } from '/imports/api/polls/server/modifiers/clearPollCollection'; import { clearCursorCollection } from '/imports/api/cursor/server/modifiers/clearCursorCollection'; import { clearCaptionsCollection } from '/imports/api/captions/server/modifiers/clearCaptionsCollection'; -import { clearPresentationsCollection } - from '/imports/api/presentations/server/modifiers/clearPresentationsCollection'; +import clearPresentations from '/imports/api/presentations/server/modifiers/clearPresentations'; export default function clearMeetings() { return Meetings.remove({}, (err) => { @@ -19,9 +18,9 @@ export default function clearMeetings() { clearChats(); clearCursorCollection(); clearPollCollection(); - clearPresentationsCollection(); + clearPresentations(); clearShapesCollection(); - clearSlidesCollection(); + clearSlides(); clearUsersCollection(); return Logger.info('Cleared Meetings (all)'); diff --git a/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js b/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js index 2fc7118f68..d3379a15f9 100755 --- a/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js +++ b/bigbluebutton-html5/imports/api/meetings/server/modifiers/removeMeeting.js @@ -5,13 +5,12 @@ import Logger from '/imports/startup/server/logger'; import { clearUsersCollection } from '/imports/api/users/server/modifiers/clearUsersCollection'; import clearChats from '/imports/api/chat/server/modifiers/clearChats'; import { clearShapesCollection } from '/imports/api/shapes/server/modifiers/clearShapesCollection'; -import { clearSlidesCollection } from '/imports/api/slides/server/modifiers/clearSlidesCollection'; +import clearSlides from '/imports/api/slides/server/modifiers/clearSlides'; import { clearPollCollection } from '/imports/api/polls/server/modifiers/clearPollCollection'; import { clearCursorCollection } from '/imports/api/cursor/server/modifiers/clearCursorCollection'; import { clearCaptionsCollection } from '/imports/api/captions/server/modifiers/clearCaptionsCollection'; -import { clearPresentationsCollection } - from '/imports/api/presentations/server/modifiers/clearPresentationsCollection'; +import clearPresentations from '/imports/api/presentations/server/modifiers/clearPresentations'; export default function removeMeeting(meetingId) { check(meetingId, String); @@ -30,9 +29,9 @@ export default function removeMeeting(meetingId) { clearChats(meetingId); clearCursorCollection(meetingId); clearPollCollection(meetingId); - clearPresentationsCollection(meetingId); + clearPresentations(meetingId); clearShapesCollection(meetingId); - clearSlidesCollection(meetingId); + clearSlides(meetingId); clearUsersCollection(meetingId); return Logger.info(`Removed meeting id=${meetingId}`); diff --git a/bigbluebutton-html5/imports/api/presentations/server/eventHandlers.js b/bigbluebutton-html5/imports/api/presentations/server/eventHandlers.js new file mode 100644 index 0000000000..aebbffb09b --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/eventHandlers.js @@ -0,0 +1,8 @@ +import RedisPubSub from '/imports/startup/server/redis'; +import handlePresentationRemove from './handlers/presentationRemove'; +import handlePresentationChange from './handlers/presentationChange'; +import handlePresentationInfoReply from './handlers/presentationInfoReply'; + +RedisPubSub.on('presentation_removed_message', handlePresentationRemove); +RedisPubSub.on('presentation_shared_message', handlePresentationChange); +RedisPubSub.on('get_presentation_info_reply', handlePresentationInfoReply); diff --git a/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationChange.js b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationChange.js new file mode 100644 index 0000000000..3c1731aa1d --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationChange.js @@ -0,0 +1,44 @@ +import { check } from 'meteor/check'; +import Logger from '/imports/startup/server/logger'; +import Presentations from '/imports/api/presentations'; + +import addPresentation from '../modifiers/addPresentation'; + +const clearCurrentPresentation = (meetingId, presentationId) => { + let selector = { + meetingId, + presentationId: { $ne: presentationId }, + 'presentation.current': true, + }; + + let modifier = { + $set: { 'presentation.current': false }, + }; + + let cb = (err, numChanged) => { + if (err) { + return Logger.error(`Unsetting the current presentation: ${err}`); + } + + if (numChanged) { + return Logger.info(`Unsetted as current presentation`); + } + }; + + return Presentations.update(selector, modifier, cb); +}; + +export default function handlePresentationChange({ payload }) { + const meetingId = payload.meeting_id; + const presentation = payload.presentation; + + check(meetingId, String); + check(presentation, Object); + + // We need to clear the flag of the older current presentation ¯\_(ツ)_/¯ + if (presentation.current) { + clearCurrentPresentation(meetingId, presentation.id); + } + + return addPresentation(meetingId, presentation); +}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationInfoReply.js b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationInfoReply.js new file mode 100644 index 0000000000..0b42afd2db --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationInfoReply.js @@ -0,0 +1,24 @@ +import Logger from '/imports/startup/server/logger'; +import { check } from 'meteor/check'; +import { inReplyToHTML5Client } from '/imports/api/common/server/helpers'; + +import addPresentation from '../modifiers/addPresentation'; + +export default function handlePresentationInfoReply({ payload }) { + if (!inReplyToHTML5Client({ payload })) { + return; + } + + const meetingId = payload.meeting_id; + const presentations = payload.presentations; + + check(meetingId, String); + check(presentations, Array); + + let presentationsAdded = []; + presentations.forEach(presentation => { + presentationsAdded.push(addPresentation(meetingId, presentation)); + }); + + return presentationsAdded; +}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationRemove.js b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationRemove.js new file mode 100644 index 0000000000..ba589c6484 --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/handlers/presentationRemove.js @@ -0,0 +1,14 @@ +import Logger from '/imports/startup/server/logger'; +import { check } from 'meteor/check'; + +import removePresentation from '../modifiers/removePresentation'; + +export default function handlePresentationRemove({ payload }) { + const meetingId = payload.meeting_id; + const presentationId = payload.presentation_id; + + check(meetingId, String); + check(presentationId, String); + + return removePresentation(meetingId, presentationId); +}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/index.js b/bigbluebutton-html5/imports/api/presentations/server/index.js new file mode 100644 index 0000000000..92451ac76b --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/index.js @@ -0,0 +1,3 @@ +import './eventHandlers'; +import './methods'; +import './publishers'; diff --git a/bigbluebutton-html5/imports/api/presentations/server/methods.js b/bigbluebutton-html5/imports/api/presentations/server/methods.js new file mode 100644 index 0000000000..1ce65c3698 --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/methods.js @@ -0,0 +1,4 @@ +import { Meteor } from 'meteor/meteor'; + +Meteor.methods({ +}); diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js new file mode 100755 index 0000000000..e87c110988 --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentation.js @@ -0,0 +1,55 @@ +import { check } from 'meteor/check'; +import Presentations from '/imports/api/presentations'; +import Logger from '/imports/startup/server/logger'; + +import addSlide from '/imports/api/slides/server/modifiers/addSlide'; + +const addSlides = (meetingId, presentationId, slides) => { + let slidesAdded = []; + + slides.forEach(slide => { + slidesAdded.push(addSlide(meetingId, presentationId, slide)); + }); + + return slidesAdded; +}; + +export default function addPresentation(meetingId, presentation) { + check(meetingId, String); + check(presentation, Object); + + const selector = { + meetingId, + 'presentation.id': presentation.id, + }; + + const modifier = { + $set: { + meetingId, + presentation: { + id: presentation.id, + name: presentation.name, + current: presentation.current, + }, + }, + }; + + const cb = (err, numChanged) => { + if (err) { + return Logger.error(`Adding presentation to collection: ${err}`); + } + + addSlides(meetingId, presentation.id, presentation.pages); + + const { insertedId } = numChanged; + if (insertedId) { + return Logger.info(`Added presentation id=${presentation.id} meeting=${meetingId}`); + } + + if (numChanged) { + return Logger.info(`Upserted presentation id=${presentation.id} meeting=${meetingId}`); + } + }; + + return Presentations.upsert(selector, modifier, cb); +}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentationToCollection.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentationToCollection.js deleted file mode 100755 index 7ee32531da..0000000000 --- a/bigbluebutton-html5/imports/api/presentations/server/modifiers/addPresentationToCollection.js +++ /dev/null @@ -1,23 +0,0 @@ -import Presentations from '/imports/api/presentations'; - -export function addPresentationToCollection(meetingId, presentationObject) { - //check if the presentation is already in the collection - const presentationObj = Presentations.findOne({ - meetingId: meetingId, - 'presentation.id': presentationObject.id, - }); - if (presentationObj == null) { - const entry = { - meetingId: meetingId, - presentation: { - id: presentationObject.id, - name: presentationObject.name, - current: presentationObject.current, - }, - }; - return Presentations.insert(entry); - - //logger.info "presentation added id =[#{id}]:#{presentationObject.id} in #{meetingId}. - // Presentations.size is now #{Presentations.find({meetingId: meetingId}).count()}" - } -}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/changeCurrentPresentation.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/changeCurrentPresentation.js new file mode 100644 index 0000000000..8657e563aa --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/modifiers/changeCurrentPresentation.js @@ -0,0 +1,53 @@ +import { check } from 'meteor/check'; +import Presentations from '/imports/api/presentations'; +import Logger from '/imports/startup/server/logger'; + +export default function changeCurrentPresentation(meetingId, presentationId) { + check(meetingId, String); + check(presentationId, String); + + const oldCurrent = { + selector: { + meetingId, + 'presentation.current': true, + }, + modifier: { + $set: { 'presentation.current': false }, + }, + callback: (err) => { + if (err) { + return Logger.error(`Unsetting the current presentation: ${err}`); + } + + return Logger.info(`Unsetted as current presentation`); + }, + }; + + const newCurrent = { + selector: { + meetingId, + 'presentation.id': presentationId, + }, + modifier: { + $set: { 'presentation.current': true }, + }, + callback: (err) => { + if (err) { + return Logger.error(`Setting as current presentation id=${presentationId}: ${err}`); + } + + return Logger.info(`Setted as current presentation id=${presentationId}`); + }, + }; + + const oldPresentation = Presentations.findOne(oldCurrent.selector); + const newPresentation = Presentations.findOne(newCurrent.selector); + + if (newPresentation) { + Presentations.update(newPresentation._id, newCurrent.modifier, newCurrent.callback); + } + + if (oldPresentation) { + Presentations.update(oldPresentation._id, oldCurrent.modifier, oldCurrent.callback); + } +}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js new file mode 100755 index 0000000000..4301e51856 --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentations.js @@ -0,0 +1,11 @@ +import Presentations from '/imports/api/slides'; +import Logger from '/imports/startup/server/logger'; + +export default function clearPresentations(meetingId) { + if (meetingId) { + return Presentations.remove({ meetingId: meetingId }, + Logger.info(`Cleared Presentations (${meetingId})`)); + } else { + return Presentations.remove({}, Logger.info('Cleared Presentations (all)')); + } +}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentationsCollection.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentationsCollection.js deleted file mode 100755 index 2fb5af1d18..0000000000 --- a/bigbluebutton-html5/imports/api/presentations/server/modifiers/clearPresentationsCollection.js +++ /dev/null @@ -1,14 +0,0 @@ -import Presentations from '/imports/api/presentations'; -import { logger } from '/imports/startup/server/logger'; - -// called on server start and meeting end -export function clearPresentationsCollection() { - const meetingId = arguments[0]; - if (meetingId != null) { - return Presentations.remove({ - meetingId: meetingId, - }, logger.info(`cleared Presentations Collection (meetingId: ${meetingId}!`)); - } else { - return Presentations.remove({}, logger.info('cleared Presentations Collection(all meetings)!')); - } -}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/eventHandlers.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/eventHandlers.js deleted file mode 100755 index 1808939f76..0000000000 --- a/bigbluebutton-html5/imports/api/presentations/server/modifiers/eventHandlers.js +++ /dev/null @@ -1,96 +0,0 @@ -import { eventEmitter } from '/imports/startup/server'; -import { removePresentationFromCollection } from './removePresentationFromCollection'; -import { addPresentationToCollection } from './addPresentationToCollection'; -import { appendMessageHeader, publish, inReplyToHTML5Client } - from '/imports/api/common/server/helpers'; -import addSlideToCollection from '/imports/api/slides/server/modifiers/addSlideToCollection'; -import Slides from '/imports/api/slides'; -import Presentations from '/imports/api/presentations'; -import { logger } from '/imports/startup/server/logger'; - -eventEmitter.on('presentation_removed_message', function (arg) { - const meetingId = arg.payload.meeting_id; - const presentationId = arg.payload.presentation_id; - if (meetingId != null && presentationId != null) { - removePresentationFromCollection(meetingId, presentationId); - } - - return arg.callback(); -}); - -eventEmitter.on('presentation_shared_message', function (arg) { - const payload = arg.payload; - const meetingId = payload.meeting_id; - if (payload.presentation != null && payload.presentation.id != null && meetingId != null) { - const presentationId = payload.presentation.id; - - // change the currently displayed presentation to presentation.current = false - Presentations.update({ - 'presentation.current': true, - meetingId: meetingId, - }, { - $set: { - 'presentation.current': false, - }, - }); - - //update(if already present) entirely the presentation with the fresh data - removePresentationFromCollection(meetingId, presentationId); - addPresentationToCollection(meetingId, payload.presentation); - const pages = payload.presentation.pages; - for (j = 0; j < pages.length; j++) { - const slide = pages[j]; - addSlideToCollection( - meetingId, - presentationId, - slide - ); - } - } - - return arg.callback(); -}); - -eventEmitter.on('get_presentation_info_reply', function (arg) { - const REDIS_CONFIG = Meteor.settings.redis; - - if (inReplyToHTML5Client(arg)) { - const payload = arg.payload; - const meetingId = payload.meeting_id; - const presentations = payload.presentations; - for (let k = 0; k < payload.presentations.length; k++) { - const presentation = presentations[k]; - addPresentationToCollection(meetingId, presentation); - const pages = presentation.pages; - for (let l = 0; l < pages.length; l++) { - const page = pages[l]; - - //add the slide to the collection - addSlideToCollection(meetingId, presentation.id, page); - - //request for shapes - const whiteboardId = `${presentation.id}/${page.num}`; - - //logger.info "the whiteboard_id here is:" + whiteboardId - - const replyTo = `${meetingId}/nodeJSapp`; - let message = { - payload: { - meeting_id: meetingId, - requester_id: 'nodeJSapp', - whiteboard_id: whiteboardId, - reply_to: replyTo, - }, - }; - if (!!whiteboardId && !!meetingId) { - message = appendMessageHeader('request_whiteboard_annotation_history_request', message); - publish(REDIS_CONFIG.channels.toBBBApps.whiteboard, message); - } else { - logger.info('did not have enough information to send a user_leaving_request'); - } - } - } - } - - return arg.callback(); -}); diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentation.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentation.js new file mode 100644 index 0000000000..5af60c05c3 --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentation.js @@ -0,0 +1,28 @@ +import { check } from 'meteor/check'; +import Presentations from '/imports/api/presentations'; +import Logger from '/imports/startup/server/logger'; + +import clearSlidesPresentation from '/imports/api/slides/server/modifiers/clearSlidesPresentation'; + +export default function removePresentation(meetingId, presentationId) { + check(meetingId, String); + check(presentationId, String); + + const selector = { + meetingId, + presentationId, + }; + + const cb = (err, numChanged) => { + if (err) { + return Logger.error(`Removing presentation from collection: ${err}`); + } + + if (numChanged) { + clearSlidesPresentation(meetingId, presentationId); + return Logger.info(`Removed presentation id=${presentationId} meeting=${meetingId}`); + } + }; + + return Presentations.remove(selector, cb); +}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentationFromCollection.js b/bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentationFromCollection.js deleted file mode 100755 index d0c74e7743..0000000000 --- a/bigbluebutton-html5/imports/api/presentations/server/modifiers/removePresentationFromCollection.js +++ /dev/null @@ -1,17 +0,0 @@ -import Slides from '/imports/api/slides'; -import Presentations from '/imports/api/presentations'; -import { logger } from '/imports/startup/server/logger'; - -export function removePresentationFromCollection(meetingId, presentationId) { - const presentationObject = Presentations.findOne({ - meetingId: meetingId, - 'presentation.id': presentationId, - }); - if (presentationObject != null) { - Slides.remove({ - presentationId: presentationId, - }, logger.info(`cleared Slides Collection (presentationId: ${presentationId}!`)); - Presentations.remove(presentationObject._id); - return logger.info(`----removed presentation[${presentationId}] from ${meetingId}`); - } -}; diff --git a/bigbluebutton-html5/imports/api/presentations/server/publications.js b/bigbluebutton-html5/imports/api/presentations/server/publications.js deleted file mode 100755 index ba6d95022f..0000000000 --- a/bigbluebutton-html5/imports/api/presentations/server/publications.js +++ /dev/null @@ -1,10 +0,0 @@ -import Presentations from '/imports/api/presentations'; -import { logger } from '/imports/startup/server/logger'; - -Meteor.publish('presentations', function (credentials) { - const { meetingId } = credentials; - logger.info(`publishing presentations for ${meetingId}`); - return Presentations.find({ - meetingId: meetingId, - }); -}); diff --git a/bigbluebutton-html5/imports/api/presentations/server/publishers.js b/bigbluebutton-html5/imports/api/presentations/server/publishers.js new file mode 100644 index 0000000000..cd6be803fd --- /dev/null +++ b/bigbluebutton-html5/imports/api/presentations/server/publishers.js @@ -0,0 +1,22 @@ +import { Meteor } from 'meteor/meteor'; +import { check } from 'meteor/check'; +import Presentations from '/imports/api/presentations'; +import Logger from '/imports/startup/server/logger'; +import { isAllowedTo } from '/imports/startup/server/userPermissions'; + +Meteor.publish('presentations', (credentials) => { + // TODO: Some publishers have ACL and others dont + // if (!isAllowedTo('@@@', credentials)) { + // this.error(new Meteor.Error(402, "The user was not authorized to subscribe for 'presentations'")); + // } + + const { meetingId, requesterUserId, requesterToken } = credentials; + + check(meetingId, String); + check(requesterUserId, String); + check(requesterToken, String); + + Logger.info(`Publishing Presentations for ${meetingId} ${requesterUserId} ${requesterToken}`); + + return Presentations.find({ meetingId }); +}); diff --git a/bigbluebutton-html5/imports/api/slides/server/modifiers/addSlideToCollection.js b/bigbluebutton-html5/imports/api/slides/server/modifiers/addSlide.js similarity index 52% rename from bigbluebutton-html5/imports/api/slides/server/modifiers/addSlideToCollection.js rename to bigbluebutton-html5/imports/api/slides/server/modifiers/addSlide.js index 020ae8c8bb..93b1e0571c 100755 --- a/bigbluebutton-html5/imports/api/slides/server/modifiers/addSlideToCollection.js +++ b/bigbluebutton-html5/imports/api/slides/server/modifiers/addSlide.js @@ -1,12 +1,29 @@ import probe from 'probe-image-size'; +import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; +import RedisPubSub from '/imports/startup/server/redis'; import Slides from '/imports/api/slides'; import Logger from '/imports/startup/server/logger'; import { SVG, PNG } from '/imports/utils/mimeTypes'; +const requestWhiteboardHistory = (meetingId, slideId) => { + const REDIS_CONFIG = Meteor.settings.redis; + const CHANNEL = REDIS_CONFIG.channels.toBBBApps.whiteboard; + const EVENT_NAME = 'request_whiteboard_annotation_history_request'; + + let payload = { + meeting_id: meetingId, + requester_id: 'nodeJSapp', + whiteboard_id: slideId, + reply_to: `${meetingId}/nodeJSapp`, + }; + + return RedisPubSub.publish(CHANNEL, EVENT_NAME, payload); +}; + const SUPPORTED_TYPES = [SVG, PNG]; -export default function addSlideToCollection(meetingId, presentationId, slide) { +export default function addSlide(meetingId, presentationId, slide) { check(meetingId, String); check(presentationId, String); check(slide, Object); @@ -21,9 +38,10 @@ export default function addSlideToCollection(meetingId, presentationId, slide) { const modifier = { $set: { - meetingId: meetingId, - presentationId: presentationId, + meetingId, + presentationId, slide: { + id: slide.id, height_ratio: slide.height_ratio, y_offset: slide.y_offset, num: slide.num, @@ -31,7 +49,6 @@ export default function addSlideToCollection(meetingId, presentationId, slide) { current: slide.current, img_uri: imageUri, txt_uri: slide.txt_uri, - id: slide.id, width_ratio: slide.width_ratio, swf_uri: slide.swf_uri, thumb_uri: slide.thumb_uri, @@ -49,27 +66,37 @@ export default function addSlideToCollection(meetingId, presentationId, slide) { const { insertedId } = numChanged; if (insertedId) { - fetchImageSizes(insertedId, imageUri); - return Logger.info(`Added slide id=${insertedId} to presentation=${presentationId}`); + requestWhiteboardHistory(meetingId, slide.id); + return Logger.info(`Added slide id=${slide.id} to presentation=${presentationId}`); + } + + if (numChanged) { + return Logger.info(`Upserted slide id=${slide.id} to presentation=${presentationId}`); } }; - return Slides.upsert(selector, modifier, cb); + return fetchImageSizes(imageUri) + .then(({ width, height }) => { + modifier.$set.slide.width = width; + modifier.$set.slide.height = height; + + return Slides.upsert(selector, modifier, cb); + }) + .catch(reason => + Logger.error(`Error parsing image size. ${reason}. slide=${slide.id} uri=${imageUri}`)); }; -const fetchImageSizes = (slideId, imageUri) => +const fetchImageSizes = (imageUri) => probe(imageUri) .then(result => { if (!SUPPORTED_TYPES.includes(result.mime)) { throw `Invalid image type, received ${result.mime} expecting ${SUPPORTED_TYPES.join()}`; } - return Slides.update(slideId, { - $set: { - width: result.width, - height: result.height, - }, - }); + return { + width: result.width, + height: result.height, + }; }) .catch(reason => { Logger.error(`Error parsing image size. ${reason}. slide=${slide.id} uri=${imageUri}`); diff --git a/bigbluebutton-html5/imports/api/slides/server/modifiers/changeCurrentSlide.js b/bigbluebutton-html5/imports/api/slides/server/modifiers/changeCurrentSlide.js index f3b6db32e7..c022d5f042 100755 --- a/bigbluebutton-html5/imports/api/slides/server/modifiers/changeCurrentSlide.js +++ b/bigbluebutton-html5/imports/api/slides/server/modifiers/changeCurrentSlide.js @@ -21,7 +21,7 @@ export default function changeCurrentSlide(meetingId, presentationId, slideId) { return Logger.error(`Unsetting the current slide: ${err}`); } - return Logger.info(`Unsetted as current slide`); + return Logger.info(`Unsetted the current slide`); }, }; @@ -47,10 +47,10 @@ export default function changeCurrentSlide(meetingId, presentationId, slideId) { const newSlide = Slides.findOne(newCurrent.selector); if (newSlide) { - Slides.update(newSlide.id, newCurrent.modifier, newCurrent.callback); + Slides.update(newSlide._id, newCurrent.modifier, newCurrent.callback); } if (oldSlide) { - Slides.update(oldSlide.id, oldCurrent.modifier, oldCurrent.callback); + Slides.update(oldSlide._id, oldCurrent.modifier, oldCurrent.callback); } }; diff --git a/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlidesCollection.js b/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlides.js similarity index 83% rename from bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlidesCollection.js rename to bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlides.js index 9de4c1f04f..868290d952 100755 --- a/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlidesCollection.js +++ b/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlides.js @@ -1,7 +1,7 @@ import Slides from '/imports/api/slides'; import Logger from '/imports/startup/server/logger'; -export default function clearSlidesCollection(meetingId) { +export default function clearSlides(meetingId) { if (meetingId) { return Slides.remove({ meetingId: meetingId }, Logger.info(`Cleared Slides (${meetingId})`)); } else { diff --git a/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlidesPresentation.js b/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlidesPresentation.js index ff7be924fe..4d65bab039 100644 --- a/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlidesPresentation.js +++ b/bigbluebutton-html5/imports/api/slides/server/modifiers/clearSlidesPresentation.js @@ -2,10 +2,12 @@ import Slides from '/imports/api/slides'; import Logger from '/imports/startup/server/logger'; import { check } from 'meteor/check'; -export default function clearSlidesPresentation(presentationId) { +export default function clearSlidesPresentation(meetingId, presentationId) { + check(meetingId, String); check(presentationId, String); const selector = { + meetingId, presentationId, }; diff --git a/bigbluebutton-html5/imports/api/slides/server/modifiers/resizeSlide.js b/bigbluebutton-html5/imports/api/slides/server/modifiers/resizeSlide.js index 80a5ebed30..6eae4cdc3c 100644 --- a/bigbluebutton-html5/imports/api/slides/server/modifiers/resizeSlide.js +++ b/bigbluebutton-html5/imports/api/slides/server/modifiers/resizeSlide.js @@ -17,21 +17,21 @@ export default function resizeSlide(meetingId, presentationId, slideId, slide) { const modifier = { $set: { - slide: { - width_ratio: slide.width_ratio, - height_ratio: slide.height_ratio, - x_offset: slide.x_offset, - y_offset: slide.y_offset, - }, + 'slide.width_ratio': slide.width_ratio, + 'slide.height_ratio': slide.height_ratio, + 'slide.x_offset': slide.x_offset, + 'slide.y_offset': slide.y_offset, }, }; - const cb = (err) => { + const cb = (err, numChanged) => { if (err) { return Logger.error(`Resizing slide id=${slideId}: ${err}`); } - return Logger.info(`Resized slide id=${slideId}`); + if (numChanged) { + return Logger.info(`Resized slide id=${slideId}`); + } }; return Slides.update(selector, modifier, cb); diff --git a/bigbluebutton-html5/imports/api/slides/server/publishers.js b/bigbluebutton-html5/imports/api/slides/server/publishers.js index d1c68318a5..0c121386e0 100644 --- a/bigbluebutton-html5/imports/api/slides/server/publishers.js +++ b/bigbluebutton-html5/imports/api/slides/server/publishers.js @@ -18,5 +18,5 @@ Meteor.publish('slides', (credentials) => { Logger.info(`Publishing Slides for ${meetingId} ${requesterUserId} ${requesterToken}`); - return Slides.find({ meetingId: meetingId }); + return Slides.find({ meetingId }); }); diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx index 09b93f2688..3f26411e35 100755 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/container.jsx @@ -17,7 +17,9 @@ class WhiteboardContainer extends Component { } } -export default createContainer(() => { - const data = WhiteboardService.getWhiteboardData(); - return data; -}, WhiteboardContainer); +export default createContainer(() => ({ + currentSlide: WhiteboardService.getCurrentSlide(), + shapes: WhiteboardService.getCurrentShapes(), + cursor: WhiteboardService.getCurrentCursor(), + userIsPresenter: WhiteboardService.isPresenter(), +}), WhiteboardContainer); diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/service.js b/bigbluebutton-html5/imports/ui/components/whiteboard/service.js index 2bb735ab82..9d1b3cc356 100755 --- a/bigbluebutton-html5/imports/ui/components/whiteboard/service.js +++ b/bigbluebutton-html5/imports/ui/components/whiteboard/service.js @@ -3,48 +3,47 @@ import Shapes from '/imports/api/shapes'; import Slides from '/imports/api/slides'; import Cursor from '/imports/api/cursor'; import Users from '/imports/api/users'; -import AuthSingleton from '/imports/ui/services/auth/index.js'; - -let getWhiteboardData = () => { - let currentSlide; - let shapes; - let cursor; - let userIsPresenter; - let currentPresentation = Presentations.findOne({ - 'presentation.current': true, - }); - - if (currentPresentation != null) { - currentSlide = Slides.findOne({ - presentationId: currentPresentation.presentation.id, - 'slide.current': true, - }); +import Auth from '/imports/ui/services/auth'; + +const getCurrentPresentation = () => Presentations.findOne({ + 'presentation.current': true, +}); + +const getCurrentSlide = () => { + const currentPresentation = getCurrentPresentation(); + + if (!currentPresentation) { + return null; } - if (currentSlide != null) { - shapes = Shapes.find({ - whiteboardId: currentSlide.slide.id, - }).fetch(); + return Slides.findOne({ + presentationId: currentPresentation.presentation.id, + 'slide.current': true, + }); +}; - cursor = Cursor.findOne({ - meetingId: currentSlide.meetingId, - }); +const getCurrentShapes = () => { + const currentSlide = getCurrentSlide(); - // Get user to check if they are the presenter - userIsPresenter = Users.findOne({ - meetingId: currentSlide.meetingId, - userId: AuthSingleton.getCredentials().requesterUserId, - }).user.presenter; + if (!currentSlide) { + return null; } - return { - currentSlide: currentSlide, - shapes: shapes, - cursor: cursor, - userIsPresenter: userIsPresenter, - }; + return Shapes.find({ + whiteboardId: currentSlide.slide.id, + }).fetch(); }; +const getCurrentCursor = () => Cursor.findOne({}); + +const isPresenter = () => Users.findOne({ + userId: Auth.userID, +}).user.presenter; + export default { - getWhiteboardData, + getCurrentPresentation, + getCurrentSlide, + getCurrentShapes, + getCurrentCursor, + isPresenter, }; diff --git a/bigbluebutton-html5/server/main.js b/bigbluebutton-html5/server/main.js index f0d0eca31a..6d0a06ca78 100755 --- a/bigbluebutton-html5/server/main.js +++ b/bigbluebutton-html5/server/main.js @@ -24,11 +24,7 @@ import '/imports/api/polls/server/modifiers/clearPollCollection'; import '/imports/api/polls/server/modifiers/updatePollCollection'; import '/imports/api/polls/server/modifiers/eventHandlers'; -import '/imports/api/presentations/server/publications'; -import '/imports/api/presentations/server/modifiers/addPresentationToCollection'; -import '/imports/api/presentations/server/modifiers/clearPresentationsCollection'; -import '/imports/api/presentations/server/modifiers/removePresentationFromCollection'; -import '/imports/api/presentations/server/modifiers/eventHandlers'; +import '/imports/api/presentations/server'; import '/imports/api/shapes/server/publications'; import '/imports/api/shapes/server/modifiers/addShapeToCollection'; -- GitLab