Merge branch 'master' of https://github.com/bigbluebutton/bigbluebutton into meteor-ui
This commit is contained in:
commit
fd71fdfa5a
@ -210,6 +210,49 @@ Handlebars.registerHelper 'whiteboardSize', (section) ->
|
||||
@toggleMenu = ->
|
||||
setInSession 'display_menu', !getInSession 'display_menu'
|
||||
|
||||
@removeFullscreenStyles = ->
|
||||
$('#whiteboard-paper').removeClass('verticallyCentered')
|
||||
$('#chat').removeClass('invisible')
|
||||
$('#users').removeClass('invisible')
|
||||
$('#navbar').removeClass('invisible')
|
||||
$('.fullscreenButton').removeClass('exitFullscreenButton')
|
||||
$('.fullscreenButton').addClass('whiteboardFullscreenButton')
|
||||
$('.fullscreenButton i').removeClass('ion-arrow-shrink')
|
||||
$('.fullscreenButton i').addClass('ion-arrow-expand')
|
||||
|
||||
@enterWhiteboardFullscreen = ->
|
||||
element = document.getElementById('whiteboard')
|
||||
if element.requestFullscreen
|
||||
element.requestFullscreen()
|
||||
else if element.mozRequestFullScreen
|
||||
element.mozRequestFullScreen()
|
||||
$('.fullscreenButton').addClass('iconFirefox') # browser-specific icon sizing
|
||||
else if element.webkitRequestFullscreen
|
||||
element.webkitRequestFullscreen()
|
||||
$('.fullscreenButton').addClass('iconChrome') # browser-specific icon sizing
|
||||
else if element.msRequestFullscreen
|
||||
element.msRequestFullscreen()
|
||||
$('#chat').addClass('invisible')
|
||||
$('#users').addClass('invisible')
|
||||
$('#navbar').addClass('invisible')
|
||||
$('.fullscreenButton').removeClass('whiteboardFullscreenButton')
|
||||
$('.fullscreenButton').addClass('exitFullscreenButton')
|
||||
$('.fullscreenButton i').removeClass('ion-arrow-expand')
|
||||
$('.fullscreenButton i').addClass('ion-arrow-shrink')
|
||||
$('#whiteboard-paper').addClass('verticallyCentered')
|
||||
$('#whiteboard').bind 'webkitfullscreenchange', (e) ->
|
||||
if document.webkitFullscreenElement is null
|
||||
$('#whiteboard').unbind('webkitfullscreenchange')
|
||||
$('.fullscreenButton').removeClass('iconChrome')
|
||||
removeFullscreenStyles()
|
||||
redrawWhiteboard()
|
||||
$(document).bind 'mozfullscreenchange', (e) -> # target is always the document in Firefox
|
||||
if document.mozFullScreenElement is null
|
||||
$(document).unbind('mozfullscreenchange')
|
||||
$('.fullscreenButton').removeClass('iconFirefox')
|
||||
removeFullscreenStyles()
|
||||
redrawWhiteboard()
|
||||
|
||||
@closePushMenus = ->
|
||||
setInSession 'display_usersList', false
|
||||
setInSession 'display_menu', false
|
||||
@ -308,6 +351,7 @@ Handlebars.registerHelper 'whiteboardSize', (section) ->
|
||||
else
|
||||
setInSession 'display_usersList', false
|
||||
setInSession 'display_menu', false
|
||||
TimeSync.loggingEnabled = false # suppresses the log messages from timesync
|
||||
|
||||
@onLoadComplete = ->
|
||||
document.title = "BigBlueButton #{BBB.getMeetingName() ? 'HTML5'}"
|
||||
|
@ -395,8 +395,7 @@ body {
|
||||
}
|
||||
|
||||
#notificationArea {
|
||||
bottom:0;
|
||||
height: 50%;
|
||||
height: auto;
|
||||
left:0;
|
||||
margin: auto;
|
||||
margin-top: 0px;
|
||||
@ -474,3 +473,24 @@ body {
|
||||
.top-bar {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@media @mobile-portrait-with-keyboard, @mobile-portrait {
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
i {
|
||||
@media @desktop-portrait, @landscape {
|
||||
font-size: 30px;
|
||||
}
|
||||
@media @mobile-portrait-with-keyboard, @mobile-portrait {
|
||||
font-size: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.verticallyCentered {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
@ -99,3 +99,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// changing mute/unmute icons on hover:
|
||||
.muteIcon .ion-ios-mic-outline:hover:before {
|
||||
content: "\f45f";
|
||||
}
|
||||
.muteIcon .ion-ios-mic:hover:before {
|
||||
content: "\f45f";
|
||||
}
|
||||
.muteIcon .ion-ios-mic-off:hover:before {
|
||||
content: "\f461";
|
||||
}
|
||||
|
@ -69,6 +69,7 @@
|
||||
}
|
||||
|
||||
#whiteboard-container {
|
||||
position: relative; // makes the fullscreen button's absolute position work
|
||||
@media @landscape {
|
||||
display: -moz-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -168,3 +169,59 @@
|
||||
#presentationProgress {
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.whiteboardFullscreenButton {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
&, &:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
i {
|
||||
color: black;
|
||||
}
|
||||
@media @landscape {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
@media @mobile-portrait-with-keyboard, @mobile-portrait {
|
||||
height: 100px;
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
.exitFullscreenButton {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
&, &:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
i {
|
||||
color: black;
|
||||
}
|
||||
@media @landscape {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
@media @mobile-portrait-with-keyboard, @mobile-portrait {
|
||||
height: 5%;
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
.iconChrome {
|
||||
i {
|
||||
font-size: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
.iconFirefox {
|
||||
i {
|
||||
font-size: 500%;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<span>{{text}}</span>
|
||||
{{else}}
|
||||
{{#if i_class}}
|
||||
<i class="{{i_class}}" style="font-size:30px"></i><span>{{label}}</span>
|
||||
<i class="{{i_class}}"></i><span>{{label}}</span>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</button>
|
||||
|
@ -9,16 +9,16 @@
|
||||
{{else}}
|
||||
{{#if isCurrentUser userId}}
|
||||
{{#if isUserMuted userId}}
|
||||
<span rel="tooltip" data-placement="bottom" title="Unmute yourself">
|
||||
<span class="muteIcon" rel="tooltip" data-placement="bottom" title="Unmute yourself">
|
||||
<i class="ion-ios-mic-off usericon"></i>
|
||||
</span>
|
||||
{{else}}
|
||||
{{#if isCurrentUserTalking}}
|
||||
<span rel="tooltip" data-placement="bottom" title="you are talking">
|
||||
<span class="muteIcon" rel="tooltip" data-placement="bottom" title="you are talking">
|
||||
<i class="ion-ios-mic usericon"></i>
|
||||
</span>
|
||||
{{else}}
|
||||
<span rel="tooltip" data-placement="bottom" title="you are talking">
|
||||
<span class="muteIcon" rel="tooltip" data-placement="bottom" title="you are talking">
|
||||
<i class="ion-ios-mic-outline usericon"></i>
|
||||
</span>
|
||||
{{/if}}
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -6,6 +6,9 @@
|
||||
<div id="whiteboard-container" class="{{whiteboardSize}}">
|
||||
<div id="whiteboard-paper">
|
||||
</div>
|
||||
{{#if isMobile}}
|
||||
{{> makeButton btn_class="fullscreenButton whiteboardFullscreenButton" i_class="ion-arrow-expand"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if isCurrentUserPresenter}}
|
||||
<div id="controllers">
|
||||
|
@ -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")
|
@ -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')
|
||||
|
||||
|
@ -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
|
||||
|
@ -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})
|
||||
|
@ -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
|
||||
|
||||
|
@ -2,6 +2,7 @@ Meteor.startup ->
|
||||
Meteor.log.info "server start"
|
||||
|
||||
#remove all data
|
||||
Meteor.WhiteboardCleanStatus.remove({})
|
||||
clearUsersCollection()
|
||||
clearChatCollection()
|
||||
clearMeetingsCollection()
|
||||
|
@ -548,11 +548,15 @@ public class ParamsProcessorUtil {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user