+
{{/if}}
diff --git a/bigbluebutton-html5/app/client/views/whiteboard/slide.coffee b/bigbluebutton-html5/app/client/views/whiteboard/slide.coffee
index 883fafb1e7..cf53dcea56 100755
--- a/bigbluebutton-html5/app/client/views/whiteboard/slide.coffee
+++ b/bigbluebutton-html5/app/client/views/whiteboard/slide.coffee
@@ -29,6 +29,9 @@ Template.slide.rendered = ->
wpm.scale(adjustedDimensions.width, adjustedDimensions.height)
@manuallyDisplayShapes = ->
+
+ return if Meteor.WhiteboardCleanStatus.findOne({in_progress: true})?
+
currentSlide = getCurrentSlideDoc()
wpm = @whiteboardPaperModel
shapes = Meteor.Shapes.find({whiteboardId: currentSlide?.slide?.id}).fetch()
diff --git a/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.coffee b/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.coffee
index a09de921d9..a07c3cf596 100755
--- a/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.coffee
+++ b/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.coffee
@@ -21,76 +21,22 @@ Template.whiteboard.helpers
return ''
Template.whiteboard.events
- "click .previousSlide":(event) ->
+ 'click .previousSlide':(event) ->
BBB.goToPreviousPage()
- "click .nextSlide":(event) ->
+ 'click .nextSlide':(event) ->
BBB.goToNextPage()
'click .switchSlideButton': (event) ->
$('.tooltip').hide()
- "click .fullscreenWhiteboardButton": (event, template) ->
- elem = document.getElementById("whiteboard")
- if elem.requestFullscreen
- elem.requestFullscreen()
- else if elem.msRequestFullscreen
- elem.msRequestFullscreen()
- else if elem.mozRequestFullScreen
- elem.mozRequestFullScreen()
- else if elem.webkitRequestFullscreen
- elem.webkitRequestFullscreen()
- $('#whiteboard-paper').addClass('invisible')
- $('#chat').addClass('invisible')
- $('#users').addClass('invisible')
- $('#footer').addClass('invisible')
- $('#navbar').addClass('invisible')
- $('#main').css('padding-top', '0px')
- $('html').css('height', '100%')
- $('html').css('width', '100%')
- $('html').css('overflow', 'hidden')
- $('body').css('height', '100%')
- $('body').css('width', '100%')
- $('body').css('overflow', 'hidden')
- setTimeout () ->
- redrawWhiteboard () ->
- $('#whiteboard-paper').removeClass('invisible')
- $('#whiteboard-paper').addClass('vertically-centered')
- , 100
+ 'click .whiteboardFullscreenButton': (event, template) ->
+ enterWhiteboardFullscreen()
- # Listens for the fullscreen state change (user leaves fullscreen mode)
-
- # Chrome
- $('#whiteboard').bind 'webkitfullscreenchange', (e) ->
- if document.webkitFullscreenElement is null
- $('#whiteboard').unbind('webkitfullscreenchange')
- $('#whiteboard-paper').removeClass('vertically-centered')
- $('#chat').removeClass('invisible')
- $('#users').removeClass('invisible')
- $('#footer').removeClass('invisible')
- $('#navbar').removeClass('invisible')
- $('html').css('height', '')
- $('html').css('width', '')
- $('html').css('overflow', '')
- $('body').css('height', '')
- $('body').css('width', '')
- $('body').css('overflow', '')
- $('#main').css('padding-top', '')
- redrawWhiteboard()
- # Firefox
- $(document).bind 'mozfullscreenchange', (e) -> # target is always the document in Firefox
- if document.mozFullScreenElement is null
- $(document).unbind('mozfullscreenchange')
- $('#whiteboard-paper').removeClass('vertically-centered')
- $('#chat').removeClass('invisible')
- $('#users').removeClass('invisible')
- $('#footer').removeClass('invisible')
- $('#navbar').removeClass('invisible')
- $('html').css('height', '')
- $('html').css('width', '')
- $('html').css('overflow', '')
- $('body').css('height', '')
- $('body').css('width', '')
- $('body').css('overflow', '')
- $('#main').css('padding-top', '')
- redrawWhiteboard()
+ 'click .exitFullscreenButton': (event, template) ->
+ if document.exitFullscreen
+ document.exitFullscreen()
+ else if document.mozCancelFullScreen
+ document.mozCancelFullScreen()
+ else if document.webkitExitFullscreen
+ document.webkitExitFullscreen()
diff --git a/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.html b/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.html
index 330aa39dc6..8acdbb59b2 100755
--- a/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.html
+++ b/bigbluebutton-html5/app/client/views/whiteboard/whiteboard.html
@@ -6,6 +6,9 @@
+ {{#if isMobile}}
+ {{> makeButton btn_class="fullscreenButton whiteboardFullscreenButton" i_class="ion-arrow-expand"}}
+ {{/if}}
{{#if isCurrentUserPresenter}}
diff --git a/bigbluebutton-html5/app/collections/collections.coffee b/bigbluebutton-html5/app/collections/collections.coffee
index 49987e25c0..200fe01e36 100755
--- a/bigbluebutton-html5/app/collections/collections.coffee
+++ b/bigbluebutton-html5/app/collections/collections.coffee
@@ -4,3 +4,5 @@ Meteor.Meetings = new Meteor.Collection("meetings")
Meteor.Presentations = new Meteor.Collection("presentations")
Meteor.Shapes = new Meteor.Collection("shapes")
Meteor.Slides = new Meteor.Collection("slides")
+
+Meteor.WhiteboardCleanStatus = new Meteor.Collection("whiteboard-clean-status")
\ No newline at end of file
diff --git a/bigbluebutton-html5/app/lib/router.coffee b/bigbluebutton-html5/app/lib/router.coffee
index 791efcb5ed..575f6371d2 100755
--- a/bigbluebutton-html5/app/lib/router.coffee
+++ b/bigbluebutton-html5/app/lib/router.coffee
@@ -55,29 +55,30 @@
Meteor.subscribe 'meetings', meetingId, onReady: =>
Meteor.subscribe 'presentations', meetingId, onReady: =>
Meteor.subscribe 'users', meetingId, userId, authToken, onError: onErrorFunction, onReady: =>
- # done subscribing
- onLoadComplete()
+ Meteor.subscribe 'whiteboard-clean-status', meetingId, onReady: =>
+ # done subscribing
+ onLoadComplete()
- handleLogourUrlError = () ->
- alert "Error: could not find the logoutURL"
- setInSession("logoutURL", document.location.hostname)
- return
-
- # obtain the logoutURL
- a = $.ajax({dataType: 'json', url: '/bigbluebutton/api/enter'})
- a.done (data) ->
- if data.response.logoutURL? # for a meeting with 0 users
- setInSession("logoutURL", data.response.logoutURL)
+ handleLogourUrlError = () ->
+ alert "Error: could not find the logoutURL"
+ setInSession("logoutURL", document.location.hostname)
return
- else
- if data.response.logoutUrl? # for a running meeting
- setInSession("logoutURL", data.response.logoutUrl)
+
+ # obtain the logoutURL
+ a = $.ajax({dataType: 'json', url: '/bigbluebutton/api/enter'})
+ a.done (data) ->
+ if data.response.logoutURL? # for a meeting with 0 users
+ setInSession("logoutURL", data.response.logoutURL)
return
else
- handleLogourUrlError()
+ if data.response.logoutUrl? # for a running meeting
+ setInSession("logoutURL", data.response.logoutUrl)
+ return
+ else
+ handleLogourUrlError()
- a.fail (data, textStatus, errorThrown) ->
- handleLogourUrlError()
+ a.fail (data, textStatus, errorThrown) ->
+ handleLogourUrlError()
@render('main')
diff --git a/bigbluebutton-html5/app/server/collection_methods/shapes.coffee b/bigbluebutton-html5/app/server/collection_methods/shapes.coffee
index 2f73effb9d..d4c0e1607e 100755
--- a/bigbluebutton-html5/app/server/collection_methods/shapes.coffee
+++ b/bigbluebutton-html5/app/server/collection_methods/shapes.coffee
@@ -67,15 +67,13 @@
@removeAllShapesFromSlide = (meetingId, whiteboardId) ->
Meteor.log.info "removeAllShapesFromSlide__" + whiteboardId
if meetingId? and whiteboardId? and Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId})?
- shapesOnSlide = Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch()
- Meteor.log.info "number of shapes:" + shapesOnSlide.length
- for s in shapesOnSlide
- Meteor.log.info "shape=" + s.shape.id
- id = Meteor.Shapes.findOne({meetingId: meetingId, whiteboardId: whiteboardId, "shape.id": s.shape.id})
- if id?
- Meteor.Shapes.remove(id._id)
- Meteor.log.info "----removed shape[" + s.shape.id + "] from " + whiteboardId
- Meteor.log.info "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch().length
+ Meteor.Shapes.remove {meetingId: meetingId, whiteboardId: whiteboardId}, ->
+ Meteor.log.info "clearing all shapes from slide"
+
+ # After shapes are cleared, wait 1 second and set cleaning off
+ Meteor.setTimeout ->
+ Meteor.WhiteboardCleanStatus.update({meetingId: meetingId}, {$set: {in_progress: false}})
+ , 1000
@removeShapeFromSlide = (meetingId, whiteboardId, shapeId) ->
shapeToRemove = Meteor.Shapes.findOne({meetingId: meetingId, whiteboardId: whiteboardId, "shape.id": shapeId})
@@ -88,9 +86,13 @@
# called on server start and meeting end
@clearShapesCollection = (meetingId) ->
if meetingId?
- Meteor.Shapes.remove({meetingId: meetingId}, Meteor.log.info "cleared Shapes Collection (meetingId: #{meetingId}!")
+ Meteor.Shapes.remove {}, ->
+ Meteor.log.info "cleared Shapes Collection (meetingId: #{meetingId}!"
+ Meteor.WhiteboardCleanStatus.update({meetingId: meetingId}, {$set: {in_progress: false}})
else
- Meteor.Shapes.remove({}, Meteor.log.info "cleared Shapes Collection (all meetings)!")
+ Meteor.Shapes.remove {}, ->
+ Meteor.log.info "cleared Shapes Collection (all meetings)!"
+ Meteor.WhiteboardCleanStatus.update({meetingId: meetingId}, {$set: {in_progress: false}})
# --------------------------------------------------------------------------------------------
# end Private methods on server
diff --git a/bigbluebutton-html5/app/server/publish.coffee b/bigbluebutton-html5/app/server/publish.coffee
index ef7510d74d..b1500de47f 100755
--- a/bigbluebutton-html5/app/server/publish.coffee
+++ b/bigbluebutton-html5/app/server/publish.coffee
@@ -70,3 +70,7 @@ Meteor.publish 'meetings', (meetingId) ->
Meteor.publish 'presentations', (meetingId) ->
Meteor.log.info "publishing presentations for #{meetingId}"
Meteor.Presentations.find({meetingId: meetingId})
+
+Meteor.publish 'whiteboard-clean-status', (meetingId) ->
+ Meteor.log.info "whiteboard clean status #{meetingId}"
+ Meteor.WhiteboardCleanStatus.find({meetingId: meetingId})
diff --git a/bigbluebutton-html5/app/server/redispubsub.coffee b/bigbluebutton-html5/app/server/redispubsub.coffee
index 3d81454bb1..07bebcf6fe 100755
--- a/bigbluebutton-html5/app/server/redispubsub.coffee
+++ b/bigbluebutton-html5/app/server/redispubsub.coffee
@@ -219,6 +219,11 @@ class Meteor.RedisPubSub
return
if message.header.name is "get_whiteboard_shapes_reply" and message.payload.requester_id is "nodeJSapp"
+
+ # Create a whiteboard clean status or find one for the current meeting
+ if not Meteor.WhiteboardCleanStatus.findOne({meetingId: meetingId})?
+ Meteor.WhiteboardCleanStatus.insert({meetingId: meetingId, in_progress: false})
+
for shape in message.payload.shapes
whiteboardId = shape.wb_id
addShapeToCollection meetingId, whiteboardId, shape
@@ -238,6 +243,7 @@ class Meteor.RedisPubSub
if message.header.name is "whiteboard_cleared_message"
whiteboardId = message.payload.whiteboard_id
+ Meteor.WhiteboardCleanStatus.update({meetingId: meetingId}, {$set: {'in_progress': true}})
removeAllShapesFromSlide meetingId, whiteboardId
return
diff --git a/bigbluebutton-html5/app/server/server.coffee b/bigbluebutton-html5/app/server/server.coffee
index 125492a669..e85cf7dd06 100755
--- a/bigbluebutton-html5/app/server/server.coffee
+++ b/bigbluebutton-html5/app/server/server.coffee
@@ -2,6 +2,7 @@ Meteor.startup ->
Meteor.log.info "server start"
#remove all data
+ Meteor.WhiteboardCleanStatus.remove({})
clearUsersCollection()
clearChatCollection()
clearMeetingsCollection()
diff --git a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java
index 7f3fba3a61..eef9e30b16 100755
--- a/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java
+++ b/bigbluebutton-web/src/java/org/bigbluebutton/api/ParamsProcessorUtil.java
@@ -542,18 +542,22 @@ public class ParamsProcessorUtil {
public boolean isChecksumSame(String apiCall, String checksum, String queryString) {
log.debug("checksum: [{}] ; query string: [{}]", checksum, queryString);
-
+
if (StringUtils.isEmpty(securitySalt)) {
log.warn("Security is disabled in this service. Make sure this is intentional.");
return true;
}
-
- // handle either checksum as first or middle / end parameter
- // TODO: this is hackish - should be done better
- queryString = queryString.replace("&checksum=" + checksum, "");
- queryString = queryString.replace("checksum=" + checksum + "&", "");
- queryString = queryString.replace("checksum=" + checksum, "");
-
+
+ if( queryString == null ) {
+ queryString = "";
+ } else {
+ // handle either checksum as first or middle / end parameter
+ // TODO: this is hackish - should be done better
+ queryString = queryString.replace("&checksum=" + checksum, "");
+ queryString = queryString.replace("checksum=" + checksum + "&", "");
+ queryString = queryString.replace("checksum=" + checksum, "");
+ }
+
log.debug("query string after checksum removed: [{}]", queryString);
String cs = DigestUtils.shaHex(apiCall + queryString + securitySalt);
log.debug("our checksum: [{}], client: [{}]", cs, checksum);