Merge branch 'testing-version-008' of github.com:antobinary/bigbluebutton into testing-version-008
This commit is contained in:
commit
d40e7250b7
@ -1 +1 @@
|
||||
METEOR@1.0
|
||||
METEOR@1.0.2
|
||||
|
@ -1,77 +1,84 @@
|
||||
agnito:raphael@0.1.0
|
||||
alanning:package-stubber@0.0.9
|
||||
amplify@1.0.0
|
||||
application-configuration@1.0.3
|
||||
application-configuration@1.0.4
|
||||
arunoda:npm@0.2.6
|
||||
autoupdate@1.1.3
|
||||
base64@1.0.1
|
||||
binary-heap@1.0.1
|
||||
blaze-tools@1.0.1
|
||||
blaze@2.0.3
|
||||
boilerplate-generator@1.0.1
|
||||
autoupdate@1.1.4
|
||||
base64@1.0.2
|
||||
binary-heap@1.0.2
|
||||
blaze@2.0.4
|
||||
blaze-tools@1.0.2
|
||||
boilerplate-generator@1.0.2
|
||||
brentjanderson:winston-client@0.2.0
|
||||
callback-hook@1.0.1
|
||||
check@1.0.2
|
||||
coffeescript@1.0.4
|
||||
ctl-helper@1.0.4
|
||||
ctl@1.0.2
|
||||
ddp@1.0.11
|
||||
deps@1.0.5
|
||||
callback-hook@1.0.2
|
||||
check@1.0.3
|
||||
coffeescript@1.0.5
|
||||
ddp@1.0.13
|
||||
deps@1.0.6
|
||||
duongthienduc:meteor-winston@1.0.0
|
||||
ejson@1.0.4
|
||||
fastclick@1.0.1
|
||||
follower-livedata@1.0.2
|
||||
ejson@1.0.5
|
||||
fastclick@1.0.2
|
||||
follower-livedata@1.0.3
|
||||
francocatena:status@1.0.3
|
||||
geojson-utils@1.0.1
|
||||
html-tools@1.0.2
|
||||
htmljs@1.0.2
|
||||
http@1.0.8
|
||||
id-map@1.0.1
|
||||
geojson-utils@1.0.2
|
||||
html-tools@1.0.3
|
||||
htmljs@1.0.3
|
||||
http@1.0.9
|
||||
id-map@1.0.2
|
||||
infinitedg:winston@0.7.3
|
||||
iron:controller@1.0.0
|
||||
iron:core@1.0.0
|
||||
iron:dynamic-template@1.0.0
|
||||
iron:layout@1.0.0
|
||||
iron:location@1.0.1
|
||||
iron:middleware-stack@1.0.0
|
||||
iron:router@1.0.1
|
||||
iron:url@1.0.0
|
||||
jquery@1.0.1
|
||||
json@1.0.1
|
||||
launch-screen@1.0.0
|
||||
less@1.0.11
|
||||
livedata@1.0.11
|
||||
logging@1.0.5
|
||||
meteor-platform@1.2.0
|
||||
meteor@1.1.3
|
||||
minifiers@1.1.2
|
||||
minimongo@1.0.5
|
||||
mizzao:bootstrap-3@3.3.0
|
||||
iron:controller@1.0.6
|
||||
iron:core@1.0.6
|
||||
iron:dynamic-template@1.0.6
|
||||
iron:layout@1.0.6
|
||||
iron:location@1.0.6
|
||||
iron:middleware-stack@1.0.6
|
||||
iron:router@1.0.6
|
||||
iron:url@1.0.6
|
||||
jquery@1.0.2
|
||||
json@1.0.2
|
||||
launch-screen@1.0.1
|
||||
less@1.0.12
|
||||
livedata@1.0.12
|
||||
logging@1.0.6
|
||||
meteor@1.1.4
|
||||
meteor-platform@1.2.1
|
||||
minifiers@1.1.3
|
||||
minimongo@1.0.6
|
||||
mizzao:bootstrap-3@3.3.1_1
|
||||
mizzao:build-fetcher@0.2.0
|
||||
mizzao:jquery-ui@1.11.2
|
||||
mizzao:timesync@0.2.2
|
||||
mobile-status-bar@1.0.1
|
||||
mongo@1.0.8
|
||||
mobile-status-bar@1.0.2
|
||||
mongo@1.0.10
|
||||
mrt:external-file-loader@0.1.4
|
||||
mrt:redis@0.1.3
|
||||
observe-sequence@1.0.3
|
||||
ordered-dict@1.0.1
|
||||
random@1.0.1
|
||||
reactive-dict@1.0.4
|
||||
reactive-var@1.0.3
|
||||
reload@1.1.1
|
||||
retry@1.0.1
|
||||
routepolicy@1.0.2
|
||||
sanjo:jasmine@0.1.0
|
||||
session@1.0.4
|
||||
spacebars-compiler@1.0.3
|
||||
spacebars@1.0.3
|
||||
standard-app-packages@1.0.3
|
||||
observe-sequence@1.0.4
|
||||
ordered-dict@1.0.2
|
||||
practicalmeteor:chai@1.9.2_3
|
||||
practicalmeteor:loglevel@1.1.0_3
|
||||
random@1.0.2
|
||||
reactive-dict@1.0.5
|
||||
reactive-var@1.0.4
|
||||
reload@1.1.2
|
||||
retry@1.0.2
|
||||
routepolicy@1.0.3
|
||||
sanjo:jasmine@0.9.0
|
||||
sanjo:karma@1.1.1
|
||||
session@1.0.5
|
||||
spacebars@1.0.4
|
||||
spacebars-compiler@1.0.4
|
||||
standard-app-packages@1.0.4
|
||||
tap:http-methods@0.0.23
|
||||
tap:i18n@1.0.7
|
||||
templating@1.0.9
|
||||
tracker@1.0.3
|
||||
ui@1.0.4
|
||||
underscore@1.0.1
|
||||
url@1.0.2
|
||||
webapp-hashing@1.0.1
|
||||
webapp@1.1.4
|
||||
templating@1.0.10
|
||||
tracker@1.0.4
|
||||
ui@1.0.5
|
||||
underscore@1.0.2
|
||||
url@1.0.3
|
||||
velocity:core@0.4.3
|
||||
velocity:meteor-stubs@1.0.0_2
|
||||
velocity:node-soft-mirror@0.1.0
|
||||
velocity:shim@0.1.0
|
||||
velocity:test-proxy@0.0.4
|
||||
webapp@1.1.5
|
||||
webapp-hashing@1.0.2
|
||||
|
@ -243,6 +243,19 @@ Handlebars.registerHelper "visibility", (section) ->
|
||||
setInSession "display_whiteboard", !getInSession "display_whiteboard"
|
||||
setTimeout(redrawWhiteboard, 0)
|
||||
|
||||
@toggleSlidingMenu = ->
|
||||
if $('#sliding-menu').hasClass('sliding-menu-opened')
|
||||
setInSession 'display_slidingMenu', false
|
||||
$('#sliding-menu').removeClass('sliding-menu-opened')
|
||||
$('#darkened-screen').css('display', 'none')
|
||||
$(document).unbind('scroll')
|
||||
else
|
||||
setInSession 'display_slidingMenu', true
|
||||
$('#sliding-menu').addClass('sliding-menu-opened')
|
||||
$('#darkened-screen').css('display', 'block')
|
||||
$(document).bind 'scroll', () ->
|
||||
window.scrollTo(0, 0)
|
||||
|
||||
# Starts the entire logout procedure.
|
||||
# meeting: the meeting the user is in
|
||||
# the user's userId
|
||||
@ -257,7 +270,6 @@ Handlebars.registerHelper "visibility", (section) ->
|
||||
delete SessionAmplify.keys['bbbServerVersion']
|
||||
delete SessionAmplify.keys['chatTabs']
|
||||
delete SessionAmplify.keys['dateOfBuild']
|
||||
delete SessionAmplify.keys['displayChatNotifications']
|
||||
delete SessionAmplify.keys['display_chatPane']
|
||||
delete SessionAmplify.keys['display_chatbar']
|
||||
delete SessionAmplify.keys['display_navbar']
|
||||
@ -270,7 +282,6 @@ Handlebars.registerHelper "visibility", (section) ->
|
||||
delete SessionAmplify.keys['tabsRenderedTime']
|
||||
delete SessionAmplify.keys['userId']
|
||||
delete SessionAmplify.keys['userName']
|
||||
console.log "clearSessionVar"
|
||||
callback()
|
||||
|
||||
# assign the default values for the Session vars
|
||||
@ -284,7 +295,7 @@ Handlebars.registerHelper "visibility", (section) ->
|
||||
setInSession "joinedAt", getTime()
|
||||
setInSession "inChatWith", 'PUBLIC_CHAT'
|
||||
setInSession "messageFontSize", 12
|
||||
setInSession "displayChatNotifications", true
|
||||
setInSession 'display_slidingMenu', false
|
||||
|
||||
|
||||
@onLoadComplete = ->
|
||||
|
@ -8,46 +8,6 @@ loadLib = (libname) ->
|
||||
|
||||
Meteor.Loader.loadJs("http://#{window.location.hostname}/client/lib/#{libname}", successCallback, 10000).fail(retryMessageCallback)
|
||||
|
||||
recalculateLayout = ->
|
||||
usersDisplayed = getInSession "display_usersList"
|
||||
whiteboardDisplayed = getInSession "display_whiteboard"
|
||||
chatDisplayed = getInSession "display_chatbar"
|
||||
# If only one module is selected (presentation), it should take up
|
||||
# the entire width of the screen. If it's two modules, each module
|
||||
# should take up 50% of the screen. If it's 3 modules (25%, 50%, 25%)
|
||||
|
||||
console.log "recalculateLayout #{usersDisplayed} #{whiteboardDisplayed} #{chatDisplayed}"
|
||||
|
||||
# clear the default width
|
||||
# $("#users").removeAttr('style')#.css("width","")
|
||||
# $("#whiteboard").removeAttr('style')#.css("width","")
|
||||
# $("#chat").removeAttr('style')#.css("width","")
|
||||
|
||||
if whiteboardDisplayed
|
||||
if chatDisplayed and usersDisplayed
|
||||
$("#users").removeClass("halfScreen").addClass("quarterScreen")
|
||||
$("#whiteboard").removeClass("fullScreenPresentation").addClass("halfScreen")
|
||||
$("#chat").removeClass("halfScreen").addClass("quarterScreen")
|
||||
displaySlide @whiteboardPaperModel
|
||||
else
|
||||
if chatDisplayed or usersDisplayed
|
||||
if chatDisplayed
|
||||
$("#whiteboard").removeClass("fullScreenPresentation").addClass("halfScreen")
|
||||
$("#chat").removeClass("quarterScreen").addClass("halfScreen")
|
||||
if usersDisplayed
|
||||
$("#whiteboard").removeClass("fullScreenPresentation").addClass("halfScreen")
|
||||
$("#users").removeClass("quarterScreen").addClass("halfScreen")
|
||||
else
|
||||
console.log "fullscreen"
|
||||
$("#whiteboard").removeClass("halfScreen").addClass("fullScreenPresentation")
|
||||
else
|
||||
if chatDisplayed
|
||||
$("#chat").removeClass("quarterScreen").addClass("halfScreen")
|
||||
return
|
||||
if usersDisplayed
|
||||
$("#users").removeClass("quarterScreen").addClass("halfScreen")
|
||||
return
|
||||
|
||||
# These settings can just be stored locally in session, created at start up
|
||||
Meteor.startup ->
|
||||
|
||||
@ -76,25 +36,19 @@ Template.footer.helpers
|
||||
Template.header.events
|
||||
"click .audioFeedIcon": (event) ->
|
||||
$('.audioFeedIcon').blur()
|
||||
toggleSlidingMenu()
|
||||
toggleVoiceCall @
|
||||
|
||||
"click .chatBarIcon": (event) ->
|
||||
$(".tooltip").hide()
|
||||
toggleSlidingMenu()
|
||||
toggleChatbar()
|
||||
#recalculateLayout()
|
||||
|
||||
"click .collapseButton": (event) ->
|
||||
toggleSlidingMenu()
|
||||
$(".tooltip").hide()
|
||||
if $('.collapseSection').css('display') is 'block'
|
||||
$('.collapseSection').css({'display': 'none'})
|
||||
$('.navbarTitle').css({ 'margin-left': 'auto', 'margin-right': 'auto', 'width': '80%' })
|
||||
$('.collapseButton > i').removeClass('glyphicon-chevron-left')
|
||||
$('.collapseButton > i').addClass('glyphicon-chevron-right')
|
||||
else
|
||||
$('.collapseSection').css({'display': 'block'})
|
||||
$('.navbarTitle').css({ 'width': '30%' })
|
||||
$('.collapseButton > i').removeClass('glyphicon-chevron-right')
|
||||
$('.collapseButton > i').addClass('glyphicon-chevron-left')
|
||||
$('.collapseButton').blur()
|
||||
$('.myNavbar').css('z-index', 1032)
|
||||
|
||||
"click .hideNavbarIcon": (event) ->
|
||||
$(".tooltip").hide()
|
||||
@ -102,6 +56,7 @@ Template.header.events
|
||||
|
||||
"click .lowerHand": (event) ->
|
||||
$(".tooltip").hide()
|
||||
toggleSlidingMenu()
|
||||
Meteor.call('userLowerHand', getInSession("meetingId"), getInSession("userId"), getInSession("userId"), getInSession("authToken"))
|
||||
|
||||
"click .muteIcon": (event) ->
|
||||
@ -112,11 +67,21 @@ Template.header.events
|
||||
#Meteor.log.info "navbar raise own hand from client"
|
||||
console.log "navbar raise own hand from client"
|
||||
$(".tooltip").hide()
|
||||
toggleSlidingMenu()
|
||||
Meteor.call('userRaiseHand', getInSession("meetingId"), getInSession("userId"), getInSession("userId"), getInSession("authToken"))
|
||||
# "click .settingsIcon": (event) ->
|
||||
# alert "settings"
|
||||
|
||||
"click .signOutIcon": (event) ->
|
||||
$('.signOutIcon').blur()
|
||||
if window.matchMedia('(orientation: portrait)').matches
|
||||
if $('#dialog').dialog('option', 'height') isnt 450
|
||||
$('#dialog').dialog('option', 'width', '100%')
|
||||
$('#dialog').dialog('option', 'height', 450)
|
||||
else
|
||||
if $('#dialog').dialog('option', 'height') isnt 115
|
||||
$('#dialog').dialog('option', 'width', 270)
|
||||
$('#dialog').dialog('option', 'height', 115)
|
||||
$("#dialog").dialog("open")
|
||||
"click .hideNavbarIcon": (event) ->
|
||||
$(".tooltip").hide()
|
||||
@ -126,8 +91,8 @@ Template.header.events
|
||||
|
||||
"click .usersListIcon": (event) ->
|
||||
$(".tooltip").hide()
|
||||
toggleSlidingMenu
|
||||
toggleUsersList()
|
||||
#recalculateLayout()
|
||||
|
||||
"click .videoFeedIcon": (event) ->
|
||||
$(".tooltip").hide()
|
||||
@ -135,8 +100,8 @@ Template.header.events
|
||||
|
||||
"click .whiteboardIcon": (event) ->
|
||||
$(".tooltip").hide()
|
||||
toggleSlidingMenu
|
||||
toggleWhiteBoard()
|
||||
#recalculateLayout()
|
||||
|
||||
"mouseout #navbarMinimizedButton": (event) ->
|
||||
$("#navbarMinimizedButton").removeClass("navbarMinimizedButtonLarge")
|
||||
@ -146,6 +111,47 @@ Template.header.events
|
||||
$("#navbarMinimizedButton").removeClass("navbarMinimizedButtonSmall")
|
||||
$("#navbarMinimizedButton").addClass("navbarMinimizedButtonLarge")
|
||||
|
||||
Template.slidingMenu.events
|
||||
'click .audioFeedIcon': (event) ->
|
||||
$('.audioFeedIcon').blur()
|
||||
toggleSlidingMenu()
|
||||
toggleVoiceCall @
|
||||
if BBB.amISharingAudio()
|
||||
$('.navbarTitle').css('width', '70%')
|
||||
else
|
||||
$('.navbarTitle').css('width', '55%')
|
||||
|
||||
'click .chatBarIcon': (event) ->
|
||||
$('.tooltip').hide()
|
||||
toggleSlidingMenu()
|
||||
toggleChatbar()
|
||||
|
||||
'click .lowerHand': (event) ->
|
||||
$('.tooltip').hide()
|
||||
toggleSlidingMenu()
|
||||
Meteor.call('userLowerHand', getInSession('meetingId'), getInSession('userId'), getInSession('userId'), getInSession('authToken'))
|
||||
|
||||
'click .raiseHand': (event) ->
|
||||
console.log 'navbar raise own hand from client'
|
||||
$('.tooltip').hide()
|
||||
toggleSlidingMenu()
|
||||
Meteor.call('userRaiseHand', getInSession("meetingId"), getInSession("userId"), getInSession("userId"), getInSession("authToken"))
|
||||
|
||||
'click .usersListIcon': (event) ->
|
||||
$('.tooltip').hide()
|
||||
toggleSlidingMenu()
|
||||
toggleUsersList()
|
||||
|
||||
'click .whiteboardIcon': (event) ->
|
||||
$('.tooltip').hide()
|
||||
toggleSlidingMenu()
|
||||
toggleWhiteBoard()
|
||||
|
||||
'click .collapseButton': (event) ->
|
||||
$('.tooltip').hide()
|
||||
toggleSlidingMenu()
|
||||
$('.collapseButton').blur()
|
||||
|
||||
Template.main.helpers
|
||||
setTitle: ->
|
||||
document.title = "BigBlueButton #{window.getMeetingName() ? 'HTML5'}"
|
||||
@ -156,8 +162,6 @@ Template.main.rendered = ->
|
||||
draggable: false
|
||||
resizable: false
|
||||
autoOpen: false
|
||||
height: 115
|
||||
width: 270
|
||||
dialogClass: 'no-close logout-dialog'
|
||||
buttons: [
|
||||
{
|
||||
@ -181,6 +185,13 @@ Template.main.rendered = ->
|
||||
of: '.signOutIcon'
|
||||
)
|
||||
|
||||
$(window).resize( ->
|
||||
$('#dialog').dialog('close')
|
||||
)
|
||||
|
||||
$('#darkened-screen').click () ->
|
||||
toggleSlidingMenu()
|
||||
|
||||
Template.makeButton.rendered = ->
|
||||
$('button[rel=tooltip]').tooltip()
|
||||
|
||||
|
@ -9,29 +9,32 @@
|
||||
<div id="navbar" class="myNavbar gradientBar navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="navbarUserButtons navbarSection">
|
||||
<div id="collapseButtonSection">
|
||||
{{> makeButton btn_class="navbarButton collapseButton" i_class="chevron-right" rel="tooltip" data_placement="bottom" title="Expand"}}
|
||||
{{#if getInSession "display_slidingMenu"}}
|
||||
{{> makeButton btn_class="navbarButton collapseButton" i_class="chevron-left" rel="tooltip" data_placement="bottom" title="Collapse"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="navbarButton collapseButton" i_class="chevron-right" rel="tooltip" data_placement="bottom" title="Expand"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div id='collapse-container' class='collapseSection'>
|
||||
|
||||
<div class='collapseSection'>
|
||||
<!-- display/hide users list toggle -->
|
||||
{{#if getInSession "display_usersList"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive usersListIcon navbarButton" i_class="user" rel="tooltip" data_placement="bottom" title="Hide List of Users"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive usersListIcon navbarButton collapseSectionButton" i_class="user" rel="tooltip" data_placement="bottom" title="Hide List of Users"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="usersListIcon navbarButton" i_class="user" rel="tooltip" data_placement="bottom" title="Show List of Users"}}
|
||||
{{> makeButton btn_class="usersListIcon navbarButton collapseSectionButton" i_class="user" rel="tooltip" data_placement="bottom" title="Show List of Users"}}
|
||||
{{/if}}
|
||||
|
||||
<!-- display/hide whiteboard toggle -->
|
||||
{{#if getInSession "display_whiteboard"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive whiteboardIcon navbarButton" i_class="pencil" rel="tooltip" data_placement="bottom" title="Hide Whiteboard"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive whiteboardIcon navbarButton collapseSectionButton" i_class="pencil" rel="tooltip" data_placement="bottom" title="Hide Whiteboard"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="whiteboardIcon navbarButton" i_class="pencil" rel="tooltip" data_placement="bottom" title="Show Whiteboard"}}
|
||||
{{> makeButton btn_class="whiteboardIcon navbarButton collapseSectionButton" i_class="pencil" rel="tooltip" data_placement="bottom" title="Show Whiteboard"}}
|
||||
{{/if}}
|
||||
|
||||
<!-- display/hide chat bar toggle -->
|
||||
{{#if getInSession "display_chatbar"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive chatBarIcon navbarButton" i_class="comment" rel="tooltip" data_placement="bottom" title="Hide Message Pane"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive chatBarIcon navbarButton collapseSectionButton" i_class="comment" rel="tooltip" data_placement="bottom" title="Hide Message Pane"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="chatBarIcon navbarButton" i_class="comment" rel="tooltip" data_placement="bottom" title="Show Message Pane"}}
|
||||
{{> makeButton btn_class="chatBarIcon navbarButton collapseSectionButton" i_class="comment" rel="tooltip" data_placement="bottom" title="Show Message Pane"}}
|
||||
{{/if}}
|
||||
|
||||
<!-- display/hide webcam streams toggle -->
|
||||
@ -40,29 +43,33 @@
|
||||
{{else}}
|
||||
{{> makeButton btn_class="videoFeedIcon navbarButton" i_class="facetime-video" sharingVideo=false rel="tooltip" data_placement="bottom" title="Show Webcams"}}
|
||||
{{/if}} -->
|
||||
|
||||
</div>
|
||||
<div class='audioControllersSection'>
|
||||
<!-- Join/hang up audio call -->
|
||||
{{#if isCurrentUserSharingAudio}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive audioFeedIcon navbarButton" i_class="volume-off" sharingAudio=true rel="tooltip" data_placement="bottom" title="Leave Audio Call"}}
|
||||
|
||||
<div class='collapseSection'>
|
||||
{{> makeButton btn_class="navbarIconToggleActive audioFeedIcon navbarButton audioButton" i_class="volume-off" sharingAudio=true rel="tooltip" data_placement="bottom" title="Leave Audio Call"}}
|
||||
</div>
|
||||
{{#if isCurrentUserMuted}}
|
||||
{{> makeButton btn_class="muteIcon navbarButton" i_class="volume-off" sharingAudio=true rel="tooltip" data_placement="bottom" title="Unmute"}}
|
||||
{{> makeButton btn_class="muteIcon navbarButton audioButton" i_class="volume-off" sharingAudio=true rel="tooltip" data_placement="bottom" title="Unmute"}}
|
||||
{{else}}
|
||||
{{#if isCurrentUserTalking}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive muteIcon navbarButton" i_class="volume-up" sharingAudio=true rel="tooltip" data_placement="bottom" title="Mute"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive muteIcon navbarButton audioButton" i_class="volume-up" sharingAudio=true rel="tooltip" data_placement="bottom" title="Mute"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive muteIcon navbarButton" i_class="volume-down" sharingAudio=true rel="tooltip" data_placement="bottom" title="Mute"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive muteIcon navbarButton audioButton" i_class="volume-down" sharingAudio=true rel="tooltip" data_placement="bottom" title="Mute"}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{else}}
|
||||
{{> makeButton btn_class="audioFeedIcon navbarButton" i_class="headphones" sharingAudio=false rel="tooltip" data_placement="bottom" title="Join Audio Call"}}
|
||||
<div class='collapseSection'>
|
||||
{{> makeButton btn_class="audioFeedIcon navbarButton audioButton" i_class="headphones" sharingAudio=false rel="tooltip" data_placement="bottom" title="Join Audio Call"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
<div class='collapseSection'>
|
||||
{{#if isCurrentUserRaisingHand}}
|
||||
{{> makeButton btn_class="lowerHand navbarIconToggleActive navbarButton" i_class="hand-up" rel="tooltip" data_placement="bottom" title="Lower your hand"}}
|
||||
{{> makeButton btn_class="lowerHand navbarIconToggleActive navbarButton collapseSectionButton" i_class="hand-up" rel="tooltip" data_placement="bottom" title="Lower your hand"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="raiseHand navbarButton" i_class="hand-up" rel="tooltip" data_placement="bottom" title="Raise your hand"}}
|
||||
{{> makeButton btn_class="raiseHand navbarButton collapseSectionButton" i_class="hand-up" rel="tooltip" data_placement="bottom" title="Raise your hand"}}
|
||||
{{/if}}
|
||||
|
||||
{{> recordingStatus}}
|
||||
@ -99,6 +106,8 @@
|
||||
{{> footer}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{> slidingMenu}}
|
||||
<div id='darkened-screen'></div>
|
||||
</body>
|
||||
</template>
|
||||
|
||||
@ -114,3 +123,39 @@
|
||||
{{/if}}
|
||||
{{/with}}
|
||||
</template>
|
||||
|
||||
<template name='slidingMenu'>
|
||||
<div class="sliding-menu" id="sliding-menu">
|
||||
<div class="slideSection">
|
||||
{{#if getInSession "display_usersList"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive usersListIcon slideButton" i_class="user" rel="tooltip" data_placement="right" title="Hide List of Users"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="usersListIcon slideButton" i_class="user" rel="tooltip" data_placement="right" title="Show List of Users"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if getInSession "display_whiteboard"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive whiteboardIcon slideButton" i_class="pencil" rel="tooltip" data_placement="right" title="Hide Whiteboard"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="whiteboardIcon slideButton" i_class="pencil" rel="tooltip" data_placement="right" title="Show Whiteboard"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if getInSession "display_chatbar"}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive chatBarIcon slideButton" i_class="comment" rel="tooltip" data_placement="right" title="Hide Message Pane"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="chatBarIcon slideButton" i_class="comment" rel="tooltip" data_placement="right" title="Show Message Pane"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if isCurrentUserSharingAudio}}
|
||||
{{> makeButton btn_class="navbarIconToggleActive audioFeedIcon slideButton" i_class="volume-off" sharingAudio=true rel="tooltip" data_placement="right" title="Leave Audio Call"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="audioFeedIcon slideButton" i_class="headphones" sharingAudio=false rel="tooltip" data_placement="right" title="Join Audio Call"}}
|
||||
{{/if}}
|
||||
|
||||
{{#if isCurrentUserRaisingHand}}
|
||||
{{> makeButton btn_class="lowerHand navbarIconToggleActive slideButton" i_class="hand-up" rel="tooltip" data_placement="right" title="Lower your hand"}}
|
||||
{{else}}
|
||||
{{> makeButton btn_class="raiseHand slideButton" i_class="hand-up" rel="tooltip" data_placement="right" title="Raise your hand"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -44,7 +44,7 @@ bottomEntry {
|
||||
}
|
||||
|
||||
#chatbody {
|
||||
height: 80%;
|
||||
height: 90%;
|
||||
overflow-y: scroll;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
|
@ -30,7 +30,7 @@ body {
|
||||
background: extract(@white, 1);
|
||||
border: 1px solid extract(@lightGrey, 3);
|
||||
float: left;
|
||||
height: 80%;
|
||||
height: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@ -207,19 +207,16 @@ body {
|
||||
.logout-dialog.ui-dialog {
|
||||
.ui-widget-header {
|
||||
color: extract(@white, 1);
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
background: extract(@darkGrey, 3);
|
||||
}
|
||||
.ui-dialog-content {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.logout-dialog.ui-widget-content {
|
||||
font-size: 10px;
|
||||
background: extract(@white, 3);
|
||||
border: 5px solid extract(@darkGrey, 3);
|
||||
}
|
||||
|
@ -17,3 +17,10 @@
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
#whiteboard-navbar {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
@ -65,4 +65,17 @@
|
||||
.collapseSection {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.logout-dialog.ui-dialog {
|
||||
.ui-widget-header {
|
||||
font-size: 12px;
|
||||
}
|
||||
.ui-dialog-content {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.logout-dialog.ui-widget-content {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
@ -16,13 +16,12 @@
|
||||
|
||||
body {
|
||||
position: relative;
|
||||
height: 1440px;
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
.navbarButton {
|
||||
height: 100px;
|
||||
width: 10%;
|
||||
width: 15%;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
@ -32,7 +31,7 @@
|
||||
padding-left: 5px;
|
||||
overflow: hidden;
|
||||
height: 72px;
|
||||
width: 80%;
|
||||
width: 70%;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-left: auto;
|
||||
@ -62,4 +61,86 @@
|
||||
.collapseSection {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.logout-dialog.ui-dialog {
|
||||
.ui-widget-header {
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.logout-dialog.ui-widget-content {
|
||||
font-size: 280%;
|
||||
}
|
||||
|
||||
.ui-dialog-buttonset {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui-dialog-buttonset button {
|
||||
width: 40%;
|
||||
margin-left: 5% !important;
|
||||
margin-right: 5% !important;
|
||||
}
|
||||
|
||||
/* Sliding menu */
|
||||
|
||||
.sliding-menu {
|
||||
width: 15%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: -15%;
|
||||
z-index: 1031;
|
||||
&.sliding-menu-opened {
|
||||
left: 0px;
|
||||
}
|
||||
a {
|
||||
border-bottom: 1px solid #258ecd;
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.slideSection {
|
||||
float: left;
|
||||
margin-top: 101px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.slideButton {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: calc(~'20% - 20px');
|
||||
}
|
||||
|
||||
.slideSection {
|
||||
margin-bottom: 0.5%;
|
||||
&.gradientBar {
|
||||
.linear-gradient(rgb(72,76,85), rgb(65,68,77));
|
||||
}
|
||||
.btn {
|
||||
.linear-gradient(rgb(72,76,85), rgb(65,68,77));
|
||||
border-left: 1px solid extract(@darkGrey, 2);
|
||||
border-right: 1px solid extract(@darkGrey, 4);
|
||||
&.navbarIconToggleActive {
|
||||
background: extract(@darkGrey, 3);
|
||||
border-bottom: 4px solid extract(@azure, 1);
|
||||
}
|
||||
i {
|
||||
color: extract(@white, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#darkened-screen {
|
||||
display: none;
|
||||
background: black;
|
||||
opacity: 0.7;
|
||||
z-index: 1030;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,5 @@
|
||||
#whiteboard {
|
||||
-webkit-order: 1;
|
||||
order: 1;
|
||||
min-height: 40%;
|
||||
max-height: 40%;
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +141,7 @@ Template.message.rendered = ->
|
||||
|
||||
Template.chatInput.events
|
||||
'click #sendMessageButton': (event) ->
|
||||
$('#sendMessageButton').blur()
|
||||
sendMessage()
|
||||
|
||||
'keypress #newMessageInput': (event) -> # user pressed a button inside the chatbox
|
||||
@ -294,7 +295,7 @@ Template.tabButtons.events
|
||||
|
||||
Template.tabButtons.helpers
|
||||
hasGotUnreadMailClass: (gotMail) ->
|
||||
if gotMail and getInSession("displayChatNotifications")
|
||||
if gotMail
|
||||
return "gotUnreadMail"
|
||||
else
|
||||
return ""
|
||||
@ -338,12 +339,3 @@ Template.message.helpers
|
||||
res = str.replace(/&/g, '&').replace(/<(?![au\/])/g, '<').replace(/\/([^au])>/g, '$1>').replace(/([^=])"(?!>)/g, '$1"');
|
||||
res = toClickable res
|
||||
res = activateBreakLines res
|
||||
|
||||
Template.notificationSettings.events
|
||||
"click #chatNotificationOff": (event) ->
|
||||
console.log "off"
|
||||
setInSession "displayChatNotifications", false
|
||||
|
||||
"click #chatNotificationOn": (event) ->
|
||||
console.log "on"
|
||||
setInSession "displayChatNotifications", true
|
||||
|
@ -52,8 +52,6 @@
|
||||
<template name="chatOptions">
|
||||
<p>Chat Options:</p>
|
||||
{{> optionsFontSize}}
|
||||
<br/><br/>
|
||||
{{> notificationSettings}}
|
||||
</template>
|
||||
|
||||
<template name="extraConversations">
|
||||
@ -89,16 +87,6 @@
|
||||
{{autoscroll}}
|
||||
</template>
|
||||
|
||||
<template name="notificationSettings">
|
||||
New Message Notifications:
|
||||
<form>
|
||||
<input type="radio" name="chatNotification" id="chatNotificationOn" value="chatNotificationOn" checked="checked" />
|
||||
<label for="chatNotificationOn">On</label>
|
||||
<input type="radio" name="chatNotification" id="chatNotificationOff" value="chatNotificationOff" />
|
||||
<label for="chatNotificationOff">Off</label>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<!-- Displays the list of options available -->
|
||||
<template name="optionsBar">
|
||||
<div class="optionsBar">
|
||||
|
@ -1,8 +1,18 @@
|
||||
Template.slide.rendered = ->
|
||||
currentSlide = getCurrentSlideDoc()
|
||||
if currentSlide?.slide?.png_uri?
|
||||
createWhiteboardPaper (wpm) ->
|
||||
displaySlide wpm
|
||||
pic = new Image()
|
||||
pic.onload = ->
|
||||
setInSession 'slideOriginalWidth', this.width
|
||||
setInSession 'slideOriginalHeight', this.height
|
||||
$(window).resize( ->
|
||||
redrawWhiteboard()
|
||||
)
|
||||
if window.matchMedia('(orientation: portrait)').matches
|
||||
$('#whiteboard-paper').height($('#whiteboard-paper').width() * this.height / this.width)
|
||||
if currentSlide?.slide?.png_uri?
|
||||
createWhiteboardPaper (wpm) ->
|
||||
displaySlide wpm
|
||||
pic.src = currentSlide?.slide?.png_uri
|
||||
|
||||
@createWhiteboardPaper = (callback) =>
|
||||
@whiteboardPaperModel = new Meteor.WhiteboardPaperModel('whiteboard-paper')
|
||||
@ -11,14 +21,10 @@ Template.slide.rendered = ->
|
||||
@displaySlide = (wpm) ->
|
||||
currentSlide = getCurrentSlideDoc()
|
||||
wpm.create()
|
||||
pic = new Image()
|
||||
pic.onload = ->
|
||||
adjustedDimensions = scaleSlide(this.width, this.height)
|
||||
wpm._displayPage(currentSlide?.slide?.png_uri, this.width, this.height)
|
||||
manuallyDisplayShapes()
|
||||
wpm.scale(adjustedDimensions.width, adjustedDimensions.height)
|
||||
|
||||
pic.src = currentSlide?.slide?.png_uri
|
||||
adjustedDimensions = scaleSlide(getInSession('slideOriginalWidth'), getInSession('slideOriginalHeight'))
|
||||
wpm._displayPage(currentSlide?.slide?.png_uri, getInSession('slideOriginalWidth'), getInSession('slideOriginalHeight'))
|
||||
manuallyDisplayShapes()
|
||||
wpm.scale(adjustedDimensions.width, adjustedDimensions.height)
|
||||
|
||||
@manuallyDisplayShapes = ->
|
||||
currentSlide = getCurrentSlideDoc()
|
||||
@ -35,9 +41,16 @@ Template.slide.rendered = ->
|
||||
wpm?.makeShape(shapeType, shapeInfo)
|
||||
wpm?.updateShape(shapeType, shapeInfo)
|
||||
|
||||
@scaleSlide = (originalWidth, originalHeight) ->
|
||||
boardWidth = $("#whiteboard").width()
|
||||
|
||||
# calculates and returns the best fitting {width, height} pair
|
||||
# based on the image's original width and height
|
||||
@scaleSlide = (originalWidth, originalHeight) ->
|
||||
|
||||
# the size of the whiteboard space (frame) where the slide will be displayed
|
||||
boardWidth = $("#whiteboard").width()
|
||||
boardHeight = null # see under
|
||||
|
||||
# calculate boardHeight
|
||||
whiteboardBottom = $("#whiteboard").offset().top + $("#whiteboard").height()
|
||||
footerTop = $(".myFooter").offset().top
|
||||
if footerTop < whiteboardBottom
|
||||
@ -45,24 +58,28 @@ Template.slide.rendered = ->
|
||||
else
|
||||
boardHeight = $("#whiteboard").height() - $("#whiteboard-navbar").height() - 10
|
||||
|
||||
# this is the best fitting pair
|
||||
adjustedWidth = null
|
||||
adjustedHeight = null
|
||||
|
||||
|
||||
# the slide image is in portrait orientation
|
||||
if originalWidth <= originalHeight
|
||||
adjustedWidth = boardHeight * originalWidth / originalHeight
|
||||
$('#whiteboard-paper').width(adjustedWidth)
|
||||
if boardWidth < adjustedWidth
|
||||
adjustedHeight = boardHeight * boardWidth / adjustedWidth
|
||||
adjustedWidth = boardWidth
|
||||
else
|
||||
adjustedHeight = boardHeight
|
||||
$("#whiteboard-paper").height(adjustedHeight)
|
||||
|
||||
# ths slide image is in landscape orientation
|
||||
else
|
||||
adjustedHeight = boardWidth * originalHeight / originalWidth
|
||||
$('#whiteboard-paper').height(adjustedHeight)
|
||||
if boardHeight < adjustedHeight
|
||||
adjustedWidth = boardWidth * boardHeight / adjustedHeight
|
||||
adjustedHeight = boardHeight
|
||||
else
|
||||
adjustedWidth = boardWidth
|
||||
$("#whiteboard-paper").width(adjustedWidth)
|
||||
|
||||
{ width: adjustedWidth, height: adjustedHeight }
|
||||
|
||||
|
@ -1,19 +1,12 @@
|
||||
Template.whiteboard.rendered = ->
|
||||
$(window).resize( ->
|
||||
redrawWhiteboard()
|
||||
)
|
||||
|
||||
@redrawWhiteboard = () ->
|
||||
currentSlide = getCurrentSlideDoc()
|
||||
pic = new Image()
|
||||
pic.onload = ->
|
||||
adjustedDimensions = scaleSlide(this.width, this.height)
|
||||
wpm = whiteboardPaperModel
|
||||
wpm.setAdjustedDimensions(adjustedDimensions.width, adjustedDimensions.height)
|
||||
wpm.clearShapes()
|
||||
wpm.clearCursor()
|
||||
manuallyDisplayShapes()
|
||||
wpm.scale(adjustedDimensions.width, adjustedDimensions.height)
|
||||
wpm.createCursor()
|
||||
|
||||
pic.src = currentSlide?.slide?.png_uri
|
||||
if window.matchMedia('(orientation: portrait)').matches
|
||||
$('#whiteboard').height($('#whiteboard').width() * getInSession('slideOriginalHeight') / getInSession('slideOriginalWidth') + $('#whiteboard-navbar').height() + 10)
|
||||
else if $('#whiteboard').height() isnt $('#users').height() + 10
|
||||
$('#whiteboard').height($('#users').height() + 10)
|
||||
adjustedDimensions = scaleSlide(getInSession('slideOriginalWidth'), getInSession('slideOriginalHeight'))
|
||||
wpm = whiteboardPaperModel
|
||||
wpm.clearShapes()
|
||||
wpm.clearCursor()
|
||||
manuallyDisplayShapes()
|
||||
wpm.scale(adjustedDimensions.width, adjustedDimensions.height)
|
||||
wpm.createCursor()
|
||||
|
@ -28,22 +28,8 @@ class Meteor.WhiteboardPaperModel
|
||||
@shiftPressed = false
|
||||
@currentPathCount = 0
|
||||
|
||||
# $container = $('#whiteboard-paper')
|
||||
# @containerWidth = $container.innerWidth()
|
||||
# @containerHeight = $container.innerHeight()
|
||||
@_updateContainerDimensions()
|
||||
|
||||
# $(window).on "resize.whiteboard_paper", _.bind(@_onWindowResize, @)
|
||||
# $(document).on "keydown.whiteboard_paper", _.bind(@_onKeyDown, @)
|
||||
# $(document).on "keyup.whiteboard_paper", _.bind(@_onKeyUp, @)
|
||||
|
||||
# Bind to the event triggered when the client connects to the server
|
||||
# if globals.connection.isConnected()
|
||||
# @_registerEvents()
|
||||
# else
|
||||
# globals.events.on "connection:connected", =>
|
||||
# @_registerEvents()
|
||||
|
||||
@zoomObserver = null
|
||||
|
||||
@adjustedWidth = 0
|
||||
@ -52,13 +38,6 @@ class Meteor.WhiteboardPaperModel
|
||||
@widthRatio = 100
|
||||
@heightRatio = 100
|
||||
|
||||
# Override the close() to unbind events.
|
||||
unbindEvents: ->
|
||||
$(window).off "resize.whiteboard_paper"
|
||||
$(document).off "keydown.whiteboard_paper"
|
||||
$(document).off "keyup.whiteboard_paper"
|
||||
# TODO: other events are being used in the code and should be off() here
|
||||
|
||||
# Initializes the paper in the page.
|
||||
# Can't do these things in initialize() because by then some elements
|
||||
# are not yet created in the page.
|
||||
@ -68,19 +47,13 @@ class Meteor.WhiteboardPaperModel
|
||||
|
||||
h = $("#"+@container).height()
|
||||
w = $("#"+@container).width()
|
||||
#console.log "h: #{h}"
|
||||
#console.log "w: #{w}"
|
||||
|
||||
# @raphaelObj ?= ScaleRaphael(@container, "900", "500")
|
||||
@raphaelObj ?= ScaleRaphael(@container, w, h)
|
||||
|
||||
# $container = $('#whiteboard-contents')
|
||||
@raphaelObj ?= ScaleRaphael(@container, $container.innerHeight(), $container.innerWidth())
|
||||
|
||||
@raphaelObj.canvas.setAttribute "preserveAspectRatio", "xMinYMin slice"
|
||||
|
||||
@createCursor()
|
||||
#@cursor.on "cursor:mousewheel", _.bind(@_zoomSlide, @)
|
||||
|
||||
if @slides
|
||||
@rebuild()
|
||||
@ -89,13 +62,6 @@ class Meteor.WhiteboardPaperModel
|
||||
unless navigator.userAgent.indexOf("Firefox") is -1
|
||||
@raphaelObj.renderfix()
|
||||
|
||||
# initializing border around slide to cover up areas which shouldnt show
|
||||
# @borders = {}
|
||||
# for border in ['left', 'right', 'top', 'bottom']
|
||||
# @borders[border] = @raphaelObj.rect(0, 0, 0, 0)
|
||||
# @borders[border].attr("fill", "#ababab")
|
||||
# @borders[border].attr( {stroke:"#ababab"} )
|
||||
|
||||
@raphaelObj
|
||||
|
||||
# Re-add the images to the paper that are found
|
||||
@ -106,27 +72,6 @@ class Meteor.WhiteboardPaperModel
|
||||
if @slides.hasOwnProperty(url)
|
||||
@addImageToPaper url, @slides[url].getWidth(), @slides[url].getHeight()
|
||||
|
||||
# A wrapper around ScaleRaphael's `changeSize()` method, more details at:
|
||||
# http://www.shapevent.com/scaleraphael/
|
||||
# Also makes sure that the images are redraw in the canvas so they are actually resized.
|
||||
changeSize: (windowWidth, windowHeight, center=true, clipping=false) ->
|
||||
if @raphaelObj?
|
||||
@raphaelObj.changeSize(windowWidth, windowHeight, center, clipping)
|
||||
|
||||
# TODO: we can scale the slides and drawings instead of re-adding them, but the logic
|
||||
# will change quite a bit
|
||||
# slides
|
||||
slidesTmp = _.clone(@slides)
|
||||
urlTmp = @current.slide
|
||||
@removeAllImagesFromPaper()
|
||||
@slides = slidesTmp
|
||||
@rebuild()
|
||||
@showImageFromPaper(urlTmp?.url)
|
||||
# drawings
|
||||
tmp = _.clone(@current.shapeDefinitions)
|
||||
@clearShapes()
|
||||
@drawListOfShapes(tmp)
|
||||
|
||||
scale: (width, height) ->
|
||||
@raphaelObj?.changeSize(width, height)
|
||||
|
||||
@ -161,10 +106,6 @@ class Meteor.WhiteboardPaperModel
|
||||
img.toBack()
|
||||
else
|
||||
img.hide()
|
||||
$(@container).on "mousemove", _.bind(@_onMouseMove, @)
|
||||
$(@container).on "mousewheel", _.bind(@_zoomSlide, @)
|
||||
# TODO $(img.node).bind "mousewheel", zoomSlide
|
||||
#@trigger('paper:image:added', img)
|
||||
|
||||
# TODO: other places might also required an update in these dimensions
|
||||
@_updateContainerDimensions()
|
||||
@ -183,60 +124,6 @@ class Meteor.WhiteboardPaperModel
|
||||
@slides = {}
|
||||
@current.slide = null
|
||||
|
||||
# Shows an image from the paper.
|
||||
# The url must be in the slides array.
|
||||
# @param {string} url the url of the image (must be in slides array)
|
||||
showImageFromPaper: (url) ->
|
||||
# TODO: temporary solution
|
||||
url = @_slideUrl(url)
|
||||
if not @current.slide? or (@slides[url]? and @current.slide.url isnt url)
|
||||
@_hideImageFromPaper(@current.slide.url) if @current.slide?
|
||||
next = @_getImageFromPaper(url)
|
||||
if next
|
||||
next.show()
|
||||
next.toFront()
|
||||
@current.shapes.forEach (element) ->
|
||||
element.toFront()
|
||||
@cursor.toFront()
|
||||
@current.slide = @slides[url]
|
||||
|
||||
# Updates the paper from the server values.
|
||||
# @param {number} cx_ the x-offset value as a percentage of the original width
|
||||
# @param {number} cy_ the y-offset value as a percentage of the original height
|
||||
# @param {number} sw_ the slide width value as a percentage of the original width
|
||||
# @param {number} sh_ the slide height value as a percentage of the original height
|
||||
# TODO: not working as it should
|
||||
updatePaperFromServer: (cx_, cy_, sw_, sh_) ->
|
||||
# # if updating the slide size (zooming!)
|
||||
# [slideWidth, slideHeight] = @_currentSlideOriginalDimensions()
|
||||
# if sw_ and sh_
|
||||
# @raphaelObj.setViewBox cx_ * slideWidth, cy_ * slideHeight, sw_ * slideWidth, sh_ * slideHeight,
|
||||
# sw = slideWidth / sw_
|
||||
# sh = slideHeight / sh_
|
||||
# # just panning, so use old slide size values
|
||||
# else
|
||||
# [sw, sh] = @_currentSlideDimensions()
|
||||
# @raphaelObj.setViewBox cx_ * slideWidth, cy_ * slideHeight, @raphaelObj._viewBox[2], @raphaelObj._viewBox[3]
|
||||
|
||||
# # update corners
|
||||
# cx = cx_ * sw
|
||||
# cy = cy_ * sh
|
||||
# # update position of svg object in the window
|
||||
# sx = (@containerWidth - slideWidth) / 2
|
||||
# sy = (@containerHeight - slideHeight) / 2
|
||||
# sy = 0 if sy < 0
|
||||
# @raphaelObj.canvas.style.left = sx + "px"
|
||||
# @raphaelObj.canvas.style.top = sy + "px"
|
||||
# @raphaelObj.setSize slideWidth - 2, slideHeight - 2
|
||||
|
||||
# # update zoom level and cursor position
|
||||
# z = @raphaelObj._viewBox[2] / slideWidth
|
||||
# @zoomLevel = z
|
||||
# dcr = 1
|
||||
# @cursor.setRadius(dcr * z)
|
||||
|
||||
# # force the slice attribute despite Raphael changing it
|
||||
# @raphaelObj.canvas.setAttribute "preserveAspectRatio", "xMinYMin slice"
|
||||
|
||||
# Switches the tool and thus the functions that get
|
||||
# called when certain events are fired from Raphael.
|
||||
@ -254,95 +141,9 @@ class Meteor.WhiteboardPaperModel
|
||||
@cursor.undrag()
|
||||
@current.rectangle = @_createTool(tool)
|
||||
@cursor.drag(@current.rectangle.dragOnMove, @current.rectangle.dragOnStart, @current.rectangle.dragOnEnd)
|
||||
|
||||
# TODO: the shapes below are still in the old format
|
||||
# when "panzoom"
|
||||
# @cursor.undrag()
|
||||
# @cursor.drag _.bind(@_panDragging, @),
|
||||
# _.bind(@_panGo, @), _.bind(@_panStop, @)
|
||||
# when "ellipse"
|
||||
# @cursor.undrag()
|
||||
# @cursor.drag _.bind(@_ellipseDragging, @),
|
||||
# _.bind(@_ellipseDragStart, @), _.bind(@_ellipseDragStop, @)
|
||||
# when "text"
|
||||
# @cursor.undrag()
|
||||
# @cursor.drag _.bind(@_rectDragging, @),
|
||||
# _.bind(@_textStart, @), _.bind(@_textStop, @)
|
||||
else
|
||||
console.log "ERROR: Cannot set invalid tool:", tool
|
||||
|
||||
# Sets the fit to page.
|
||||
# @param {boolean} value If true fit to page. If false fit to width.
|
||||
# TODO: not really working as it should be
|
||||
setFitToPage: (value) ->
|
||||
@fitToPage = value
|
||||
|
||||
# TODO: we can scale the slides and drawings instead of re-adding them, but the logic
|
||||
# will change quite a bit
|
||||
temp = @slides
|
||||
@removeAllImagesFromPaper()
|
||||
@slides = temp
|
||||
# re-add all the images as they should fit differently
|
||||
@rebuild()
|
||||
|
||||
# set to default zoom level
|
||||
#globals.connection.emitPaperUpdate 0, 0, 1, 1
|
||||
# get the shapes to reprocess
|
||||
#globals.connection.emitAllShapes()
|
||||
|
||||
# Socket response - Update zoom variables and viewbox
|
||||
# @param {number} d the delta value from the scroll event
|
||||
# @return {undefined}
|
||||
setZoom: (d) ->
|
||||
step = 0.05 # step size
|
||||
if d < 0
|
||||
@zoomLevel += step # zooming out
|
||||
else
|
||||
@zoomLevel -= step # zooming in
|
||||
|
||||
[sw, sh] = @_currentSlideDimensions()
|
||||
[cx, cy] = @_currentSlideOffsets()
|
||||
x = cx / sw
|
||||
y = cy / sh
|
||||
# cannot zoom out further than 100%
|
||||
z = (if @zoomLevel > 1 then 1 else @zoomLevel)
|
||||
# cannot zoom in further than 400% (1/4)
|
||||
z = (if z < 0.25 then 0.25 else z)
|
||||
# cannot zoom to make corner less than (x,y) = (0,0)
|
||||
x = (if x < 0 then 0 else x)
|
||||
y = (if y < 0 then 0 else y)
|
||||
# cannot view more than the bottom corners
|
||||
zz = 1 - z
|
||||
x = (if x > zz then zz else x)
|
||||
y = (if y > zz then zz else y)
|
||||
#globals.connection.emitPaperUpdate x, y, z, z # send update to all clients
|
||||
|
||||
stopPanning: ->
|
||||
# nothing to do
|
||||
|
||||
# Draws an array of shapes to the paper.
|
||||
# @param {array} shapes the array of shapes to draw
|
||||
drawListOfShapes: (shapes) ->
|
||||
@current.shapeDefinitions = shapes
|
||||
@current.shapes = @raphaelObj.set()
|
||||
for shape in shapes
|
||||
shapeType = shape?.shape?.shape_type
|
||||
dataBlock = shape?.shape?.shape
|
||||
data = if _.isString(dataBlock) then JSON.parse(dataBlock) else dataBlock
|
||||
tool = @_createTool(shapeType)
|
||||
if tool?
|
||||
@current.shapes.push tool.draw.apply(tool, data)
|
||||
else
|
||||
console.log "shape not recognized at drawListOfShapes", shape
|
||||
|
||||
# make sure the cursor is still on top
|
||||
@cursor.toFront()
|
||||
|
||||
#Changes the currently displayed presentation (if any) with this one
|
||||
#@param {object} containing the "presentation" object -id,name,pages[]
|
||||
sharePresentation: (data) ->
|
||||
#globals.events.trigger("connection:all_slides", data.payload)
|
||||
|
||||
# Clear all shapes from this paper.
|
||||
clearShapes: ->
|
||||
if @current.shapes?
|
||||
@ -393,76 +194,8 @@ class Meteor.WhiteboardPaperModel
|
||||
if @viewBoxXpos? && @viewBoxYPos? && @viewBoxWidth? && @viewBoxHeight?
|
||||
@cursor.setPosition( @viewBoxXpos + x * @viewBoxWidth, @viewBoxYPos + y * @viewBoxHeight )
|
||||
|
||||
# Update the slide to move and zoom
|
||||
# @param {number} xOffset the x value of offset
|
||||
# @param {number} yOffset the y value of offset
|
||||
# @param {number} widthRatio the ratio of the previous width
|
||||
# @param {number} heightRatio the ratio of the previous height
|
||||
moveAndZoom: (xOffset, yOffset, widthRatio, heightRatio) ->
|
||||
@globalxOffset = xOffset
|
||||
@globalyOffset = yOffset
|
||||
@globalwidthRatio = widthRatio
|
||||
@globalheightRatio = heightRatio
|
||||
|
||||
[slideWidth, slideHeight] = @_currentSlideOriginalDimensions()
|
||||
#console.log("xOffset: " + xOffset + ", yOffset: " + yOffset);
|
||||
#console.log("@containerWidth: " + @containerWidth + " @containerHeight: " + @containerHeight);
|
||||
#console.log("slideWidth: " + slideWidth + " slideHeight: " + slideHeight);
|
||||
baseWidth = (@containerWidth - slideWidth) / 2
|
||||
baseHeight = (@containerHeight - slideHeight) / 2
|
||||
|
||||
|
||||
#get the actual size of the slide, depending on the limiting factor (container width or container height)
|
||||
|
||||
actualWidth = @current.slide.displayWidth
|
||||
actualHeight = @current.slide.displayHeight
|
||||
#console.log("actualWidth:" + actualWidth + " actualHeight: " + actualHeight)
|
||||
|
||||
#calculate parameters to pass
|
||||
newXPos = baseWidth - 2* xOffset * actualWidth / 100
|
||||
newyPos = baseHeight - 2* yOffset * actualHeight / 100
|
||||
newWidth = actualWidth / 100 * widthRatio
|
||||
newHeight = actualHeight / 100 * heightRatio
|
||||
|
||||
@viewBoxXpos = newXPos
|
||||
@viewBoxYPos = newyPos
|
||||
@viewBoxWidth = newWidth
|
||||
@viewBoxHeight = newHeight
|
||||
|
||||
#console.log("newXPos: " + newXPos + " newyPos: " + newyPos + " newWidth: " + newWidth + " newHeight: " + newHeight)
|
||||
|
||||
#set parameters to raphael viewbox
|
||||
@raphaelObj.setViewBox(newXPos , newyPos, newWidth , newHeight , true)
|
||||
|
||||
# update the rectangle elements which create the border when page is zoomed
|
||||
@borders.left.attr( {width:newXPos, height: @containerHeight} )
|
||||
|
||||
@borders.right.attr(
|
||||
x: newXPos + newWidth
|
||||
y: 0
|
||||
width:newXPos
|
||||
height:@containerHeight
|
||||
)
|
||||
|
||||
@borders.top.attr(
|
||||
width: @containerWidth
|
||||
height: newyPos
|
||||
)
|
||||
|
||||
@borders.bottom.attr(
|
||||
y: newyPos + newHeight
|
||||
width: @containerWidth
|
||||
height: @containerHeight
|
||||
)
|
||||
|
||||
# borders should appear infront of every other element (i.e. shapes)
|
||||
for _, border of @borders
|
||||
border.toFront()
|
||||
|
||||
#update cursor to appear the same size even when page is zoomed in
|
||||
@cursor.setRadius( 3 * widthRatio / 100 )
|
||||
|
||||
zoomAndPan: (widthRatio, heightRatio, xOffset, yOffset) ->
|
||||
console.log "zoomAndPan #{widthRatio} #{heightRatio} #{xOffset} #{yOffset}"
|
||||
newX = - xOffset * 2 * @adjustedWidth / 100
|
||||
newY = - yOffset * 2 * @adjustedHeight / 100
|
||||
newWidth = @adjustedWidth * widthRatio / 100
|
||||
@ -473,86 +206,6 @@ class Meteor.WhiteboardPaperModel
|
||||
@adjustedWidth = width
|
||||
@adjustedHeight = height
|
||||
|
||||
# Registers listeners for events in the gloval event bus
|
||||
_registerEvents: ->
|
||||
|
||||
# globals.events.on "connection:whiteboardDrawPen", (startingData) =>
|
||||
# type = startingData.payload.shape_type
|
||||
# color = startingData.payload.data.line.color
|
||||
# thickness = startingData.payload.data.line.weight
|
||||
# points = startingData.shape.points
|
||||
# if type is "line"
|
||||
# for i in [0..points.length - 1]
|
||||
# if i is 0
|
||||
# #make these compatible with a line
|
||||
# console.log "points[i]: " + points[i]
|
||||
# lineObject = {
|
||||
# shape: {
|
||||
# type: "line",
|
||||
# coordinate: {
|
||||
# firstX : points[i].x/100,
|
||||
# firstY : points[i].y/100
|
||||
# },
|
||||
# color: startingData.payload.data.line.color,
|
||||
# thickness : startingData.payload.data.line.weight
|
||||
# }
|
||||
# adding : false #tell the line object that we are NOT adding points but creating a new line
|
||||
# }
|
||||
# console.log "lineObject: " + lineObject
|
||||
# @makeShape type, lineObject
|
||||
# else
|
||||
# console.log "points[i]: "+ points[i]
|
||||
# lineObject = {
|
||||
# shape: {
|
||||
# type: "line",
|
||||
# coordinate: {
|
||||
# firstX : points[i].x/100,
|
||||
# firstY : points[i].y/100
|
||||
# },
|
||||
# color: startingData.payload.data.line.color,
|
||||
# thickness : startingData.payload.data.line.weight
|
||||
# }
|
||||
# adding : true #tell the line object that we ARE adding points and NOT creating a new line
|
||||
# }
|
||||
# console.log "lineObject: " + lineObject
|
||||
# @updateShape type, lineObject
|
||||
|
||||
|
||||
# globals.events.on "connection:move_and_zoom", (xOffset, yOffset, widthRatio, heightRatio) =>
|
||||
# @moveAndZoom(xOffset, yOffset, widthRatio, heightRatio)
|
||||
|
||||
# globals.events.on "connection:changeslide", (url) =>
|
||||
# @showImageFromPaper(url)
|
||||
|
||||
# globals.events.on "connection:viewBox", (xperc, yperc, wperc, hperc) =>
|
||||
# xperc = parseFloat(xperc, 10)
|
||||
# yperc = parseFloat(yperc, 10)
|
||||
# wperc = parseFloat(wperc, 10)
|
||||
# hperc = parseFloat(hperc, 10)
|
||||
# @updatePaperFromServer(xperc, yperc, wperc, hperc)
|
||||
|
||||
# globals.events.on "connection:fitToPage", (value) =>
|
||||
# @setFitToPage(value)
|
||||
|
||||
# globals.events.on "connection:zoom", (delta) =>
|
||||
# @setZoom(delta)
|
||||
|
||||
# globals.events.on "connection:paper", (cx, cy, sw, sh) =>
|
||||
# @updatePaperFromServer(cx, cy, sw, sh)
|
||||
|
||||
# globals.events.on "connection:panStop", =>
|
||||
# @stopPanning()
|
||||
|
||||
# globals.events.on "connection:toolChanged", (tool) =>
|
||||
# @setCurrentTool(tool)
|
||||
|
||||
# globals.events.on "connection:textDone", =>
|
||||
# @textDone()
|
||||
|
||||
# globals.events.on "connection:uploadStatus", (message, fade) =>
|
||||
# globals.events.trigger("whiteboard:paper:uploadStatus", message, fade)
|
||||
|
||||
|
||||
# Update the dimensions of the container.
|
||||
_updateContainerDimensions: ->
|
||||
#console.log "update Container Dimensions"
|
||||
@ -579,149 +232,6 @@ class Meteor.WhiteboardPaperModel
|
||||
return @raphaelObj.getById(id) if id?
|
||||
null
|
||||
|
||||
# Hides an image from the paper given the URL.
|
||||
# The url must be in the slides array.
|
||||
# @param {string} url the url of the image (must be in slides array)
|
||||
_hideImageFromPaper: (url) ->
|
||||
img = @_getImageFromPaper(url)
|
||||
img.hide() if img?
|
||||
|
||||
# Update zoom variables on all clients
|
||||
# @param {Event} e the event that occurs when scrolling
|
||||
# @param {number} delta the speed/direction at which the scroll occurred
|
||||
_zoomSlide: (e, delta) ->
|
||||
#globals.connection.emitZoom delta
|
||||
|
||||
# Called when the cursor is moved over the presentation.
|
||||
# Sends cursor moving event to server.
|
||||
# @param {Event} e the mouse event
|
||||
# @param {number} x the x value of cursor at the time in relation to the left side of the browser
|
||||
# @param {number} y the y value of cursor at the time in relation to the top of the browser
|
||||
# TODO: this should only be done if the user is the presenter
|
||||
_onMouseMove: (e, x, y) ->
|
||||
[sw, sh] = @_currentSlideDimensions()
|
||||
xLocal = (e.pageX - @containerOffsetLeft) / sw
|
||||
yLocal = (e.pageY - @containerOffsetTop) / sh
|
||||
#globals.connection.emitMoveCursor xLocal, yLocal
|
||||
|
||||
# When the user is dragging the cursor (click + move)
|
||||
# @param {number} dx the difference between the x value from panGo and now
|
||||
# @param {number} dy the difference between the y value from panGo and now
|
||||
_panDragging: (dx, dy) ->
|
||||
[slideWidth, slideHeight] = @_currentSlideOriginalDimensions()
|
||||
sx = (@containerWidth - slideWidth) / 2
|
||||
sy = (@containerHeight - slideHeight) / 2
|
||||
[sw, sh] = @_currentSlideDimensions()
|
||||
|
||||
# ensuring that we cannot pan outside of the boundaries
|
||||
x = (@panX - dx)
|
||||
# cannot pan past the left edge of the page
|
||||
x = (if x < 0 then 0 else x)
|
||||
y = (@panY - dy)
|
||||
# cannot pan past the top of the page
|
||||
y = (if y < 0 then 0 else y)
|
||||
if @fitToPage
|
||||
x2 = slideWidth + x
|
||||
else
|
||||
x2 = @containerWidth + x
|
||||
# cannot pan past the width
|
||||
x = (if x2 > sw then sw - (@containerWidth - sx * 2) else x)
|
||||
if @fitToPage
|
||||
y2 = slideHeight + y
|
||||
else
|
||||
# height of image could be greater (or less) than the box it fits in
|
||||
y2 = @containerHeight + y
|
||||
# cannot pan below the height
|
||||
y = (if y2 > sh then sh - (@containerHeight - sy * 2) else y)
|
||||
#globals.connection.emitPaperUpdate x / sw, y / sh, null, null
|
||||
|
||||
# When panning starts
|
||||
# @param {number} x the x value of the cursor
|
||||
# @param {number} y the y value of the cursor
|
||||
_panGo: (x, y) ->
|
||||
[cx, cy] = @_currentSlideOffsets()
|
||||
@panX = cx
|
||||
@panY = cy
|
||||
|
||||
# When panning finishes
|
||||
# @param {Event} e the mouse event
|
||||
_panStop: (e) ->
|
||||
@stopPanning()
|
||||
|
||||
# Called when the application window is resized.
|
||||
_onWindowResize: ->
|
||||
@_updateContainerDimensions()
|
||||
console.log "_onWindowResize"
|
||||
|
||||
#TODO: temporary hacked away fix so that the buttons resize correctly when the window resizes
|
||||
$("#users-btn").click();
|
||||
$("#users-btn").click();
|
||||
|
||||
|
||||
#TODO: maybe find solution besides these global values..no conflicts however
|
||||
|
||||
[slideWidth, slideHeight] = @_currentSlideOriginalDimensions()
|
||||
#console.log("xOffset: " + xOffset + ", yOffset: " + yOffset);
|
||||
#console.log("@containerWidth: " + @containerWidth + " @containerHeight: " + @containerHeight);
|
||||
#console.log("slideWidth: " + slideWidth + " slideHeight: " + slideHeight);
|
||||
baseWidth = (@containerWidth - slideWidth) / 2
|
||||
baseHeight = (@containerHeight - slideHeight) / 2
|
||||
|
||||
|
||||
#get the actual size of the slide, depending on the limiting factor (container width or container height)
|
||||
if(@containerWidth - slideWidth < @containerHeight - slideHeight)
|
||||
actualHeight = @containerWidth * slideHeight / slideWidth
|
||||
actualWidth = @containerWidth
|
||||
else
|
||||
actualWidth = @containerHeight * slideWidth / slideHeight
|
||||
actualHeight = @containerHeight
|
||||
|
||||
#console.log("actualWidth:" + actualWidth + " actualHeight: " + actualHeight)
|
||||
|
||||
#calculate parameters to pass
|
||||
newXPos = baseWidth
|
||||
newyPos = baseHeight
|
||||
newWidth = actualWidth
|
||||
newHeight = actualHeight
|
||||
|
||||
#now the zooming will still be correct when the window is resized
|
||||
#and hopefully when rotated on a mobile device
|
||||
if @globalxOffset? && @globalyOffset? && @globalwidthRatio? && @globalheightRatio?
|
||||
console.log "has zoomed in"
|
||||
@moveAndZoom(@globalxOffset, @globalyOffset, @globalwidthRatio, @globalheightRatio)
|
||||
|
||||
else
|
||||
obj =
|
||||
globalxOffset : @globalxOffset
|
||||
globalyOffset : @globalyOffset
|
||||
globalwidthRatio : @globalwidthRatio
|
||||
globalheightRatio : @globalheightRatio
|
||||
|
||||
console.log obj
|
||||
console.log "not zoomed"
|
||||
@raphaelObj.setViewBox(newXPos, newyPos, newWidth, newHeight,true)
|
||||
|
||||
|
||||
# when pressing down on a key at anytime
|
||||
_onKeyDown: (event) ->
|
||||
unless event
|
||||
keyCode = window.event.keyCode
|
||||
else
|
||||
keyCode = event.keyCode
|
||||
switch keyCode
|
||||
when 16 # shift key
|
||||
@shiftPressed = true
|
||||
|
||||
# when releasing any key at any time
|
||||
_onKeyUp: ->
|
||||
unless event
|
||||
keyCode = window.event.keyCode
|
||||
else
|
||||
keyCode = event.keyCode
|
||||
switch keyCode
|
||||
when 16 # shift key
|
||||
@shiftPressed = false
|
||||
|
||||
_currentSlideDimensions: ->
|
||||
if @current.slide? then @current.slide.getDimensions() else [0, 0]
|
||||
|
||||
@ -774,24 +284,6 @@ class Meteor.WhiteboardPaperModel
|
||||
_displayPage: (data, originalWidth, originalHeight) ->
|
||||
@removeAllImagesFromPaper()
|
||||
|
||||
# get dimensions for available whiteboard space
|
||||
# get where to start from the left -> either the end of the user's list or the left edge of the screen
|
||||
# if getInSession "display_usersList" then xBegin = $("#userListContainer").width()
|
||||
# else xBegin = 0
|
||||
# # get where to start from the right -> either the beginning of the chat bar or the right edge of the screen
|
||||
# if getInSession "display_chatbar" then xEnd = $("#chat").position().left
|
||||
# else xEnd = $( document ).width();
|
||||
|
||||
# # find the height to start the top of the image at
|
||||
# if getInSession "display_navbar" then yBegin = $("#navbar").height()
|
||||
# else yBegin = 0
|
||||
# yEnd = $( document ).height();
|
||||
|
||||
# # TODO: add some form of padding to the left, right, top, and bottom boundaries
|
||||
# #
|
||||
# boardWidth = xEnd - xBegin
|
||||
# boardHeight = yEnd - yBegin
|
||||
|
||||
@_updateContainerDimensions()
|
||||
boardWidth = @containerWidth
|
||||
boardHeight = @containerHeight
|
||||
@ -801,7 +293,7 @@ class Meteor.WhiteboardPaperModel
|
||||
# TODO currentSlide undefined in some cases - will check later why
|
||||
imageWidth = boardWidth * (currentSlide?.slide.width_ratio/100) or boardWidth
|
||||
imageHeight = boardHeight * (currentSlide?.slide.height_ratio/100) or boardHeight
|
||||
#alert("_displayPage")
|
||||
|
||||
# console.log "xBegin: #{xBegin}"
|
||||
# console.log "xEnd: #{xEnd}"
|
||||
# console.log "yBegin: #{yBegin}"
|
||||
@ -832,7 +324,8 @@ class Meteor.WhiteboardPaperModel
|
||||
|
||||
oldRatio = (oldDoc.slide.width_ratio + oldDoc.slide.height_ratio) / 2
|
||||
newRatio = (newDoc.slide.width_ratio + newDoc.slide.height_ratio) / 2
|
||||
_this?.currentShapes?.forEach (shape) ->
|
||||
|
||||
_this?.current?.shapes?.forEach (shape) ->
|
||||
shape.attr "stroke-width", shape.attr('stroke-width') * oldRatio / newRatio
|
||||
|
||||
_this.cursor.setRadius(6 * newDoc.slide.width_ratio / 100)
|
||||
|
@ -15,7 +15,7 @@ class @WhiteboardTextModel extends WhiteboardToolModel
|
||||
y = startingData.y
|
||||
width = startingData.textBoxWidth
|
||||
height = startingData.textBoxHeight
|
||||
colour = startingData.fontColor
|
||||
colour = formatColor(startingData.fontColor)
|
||||
fontSize = startingData.fontSize
|
||||
calcFontSize = startingData.calcedFontSize
|
||||
text = startingData.text
|
||||
@ -28,11 +28,10 @@ class @WhiteboardTextModel extends WhiteboardToolModel
|
||||
x = (x * @gw) + @xOffset
|
||||
y = (y * @gh) + @yOffset + calcFontSize
|
||||
width = width/100 * @gw
|
||||
colour = Meteor.call("strokeAndThickness",colour, false)
|
||||
|
||||
@obj = @paper.text(x/100, y/100, "")
|
||||
@obj.attr
|
||||
fill: Meteor.call("strokeAndThickness",colour, false)
|
||||
"fill": colour
|
||||
"font-family": "Arial" # TODO: make dynamic
|
||||
"font-size": calcFontSize
|
||||
@obj.node.style["text-anchor"] = "start" # force left align
|
||||
@ -48,7 +47,7 @@ class @WhiteboardTextModel extends WhiteboardToolModel
|
||||
y = startingData.y
|
||||
maxWidth = startingData.textBoxWidth
|
||||
height = startingData.textBoxHeight
|
||||
colour = startingData.fontColor
|
||||
colour = formatColor(startingData.fontColor)
|
||||
fontSize = startingData.fontSize
|
||||
calcFontSize = startingData.calcedFontSize
|
||||
myText = startingData.text
|
||||
@ -61,7 +60,8 @@ class @WhiteboardTextModel extends WhiteboardToolModel
|
||||
maxWidth = maxWidth/100 * @gw
|
||||
|
||||
@obj.attr
|
||||
fill: "#000"
|
||||
"fill": colour
|
||||
"font-family": "Arial" # TODO: make dynamic
|
||||
"font-size": calcFontSize
|
||||
cell = @obj.node
|
||||
while cell? and cell.hasChildNodes()
|
||||
|
@ -61,7 +61,16 @@ Meteor.methods
|
||||
from_lang: messageObject.from_lang
|
||||
|
||||
id = Meteor.Chat.insert(entry)
|
||||
Meteor.log.info "added chat id=[#{id}]:#{messageObject.message}. Chat.size is now #{Meteor.Chat.find({meetingId: meetingId}).count()}"
|
||||
Meteor.log.info "added chat id=[#{id}]:#{messageObject.message}." #" Chat.size is now #{Meteor.Chat.find({meetingId: meetingId}).count()}"
|
||||
|
||||
|
||||
# called on server start and meeting end
|
||||
@clearChatCollection = (meetingId) ->
|
||||
if meetingId?
|
||||
Meteor.Chat.remove({meetingId: meetingId}, Meteor.log.info "cleared Chat Collection (meetingId: #{meetingId}!")
|
||||
else
|
||||
Meteor.Chat.remove({}, Meteor.log.info "cleared Chat Collection (all meetings)!")
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# end Private methods on server
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
@ -14,17 +14,34 @@
|
||||
duration: duration)
|
||||
Meteor.log.info "added meeting _id=[#{id}]:meetingId=[#{meetingId}]:name=[#{name}]:duration=[#{duration}]:voiceConf=[#{voiceConf}]."
|
||||
|
||||
|
||||
@clearMeetingsCollection = (meetingId) ->
|
||||
if meetingId?
|
||||
Meteor.Meetings.remove({meetingId: meetingId}, Meteor.log.info "cleared Meetings Collection (meetingId: #{meetingId}!")
|
||||
else
|
||||
Meteor.Meetings.remove({}, Meteor.log.info "cleared Meetings Collection (all meetings)!")
|
||||
|
||||
|
||||
@removeMeetingFromCollection = (meetingId) ->
|
||||
if Meteor.Meetings.findOne({meetingId: meetingId})?
|
||||
if Meteor.Users.find({meetingId: meetingId}).count() isnt 0
|
||||
Meteor.log.info "!!removing a meeting which has users in it"
|
||||
for user in Meteor.Users.find({meetingId: meetingId}).fetch()
|
||||
Meteor.log.info "in meetings::removeMeetingFromCollection #{meetingId} #{user.userId}"
|
||||
removeUserFromCollection meetingId, user.userId
|
||||
id = Meteor.Meetings.findOne({meetingId: meetingId})
|
||||
if id?
|
||||
Meteor.Meetings.remove(id._id)
|
||||
Meteor.log.info "removed from Meetings:#{meetingId} now there are only #{Meteor.Meetings.find().count()} meetings running"
|
||||
Meteor.log.info "end of meeting #{meetingId}. Clear the meeting data from all collections"
|
||||
# delete all users in the meeting
|
||||
clearUsersCollection(meetingId)
|
||||
|
||||
# delete all slides in the meeting
|
||||
clearSlidesCollection(meetingId)
|
||||
|
||||
# delete all shapes in the meeting
|
||||
clearShapesCollection(meetingId)
|
||||
|
||||
# delete all presentations in the meeting
|
||||
clearPresentationsCollection(meetingId)
|
||||
|
||||
# delete all chat messages in the meeting
|
||||
clearChatCollection(meetingId)
|
||||
|
||||
# delete the meeting
|
||||
clearMeetingsCollection(meetingId)
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# end Private methods on server
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
@ -24,6 +24,15 @@
|
||||
if id?
|
||||
Meteor.Presentations.remove(id._id)
|
||||
Meteor.log.info "----removed presentation[" + presentationId + "] from " + meetingId
|
||||
|
||||
|
||||
# called on server start and meeting end
|
||||
@clearPresentationsCollection = (meetingId) ->
|
||||
if meetingId?
|
||||
Meteor.Presentations.remove({meetingId: meetingId}, Meteor.log.info "cleared Presentations Collection (meetingId: #{meetingId}!")
|
||||
else
|
||||
Meteor.Presentations.remove({}, Meteor.log.info "cleared Presentations Collection (all meetings)!")
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# end Private methods on server
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
@ -76,6 +76,15 @@
|
||||
Meteor.Shapes.remove(shapeToRemove._id)
|
||||
Meteor.log.info "----removed shape[" + shapeId + "] from " + whiteboardId
|
||||
Meteor.log.info "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).count()
|
||||
|
||||
|
||||
# called on server start and meeting end
|
||||
@clearShapesCollection = (meetingId) ->
|
||||
if meetingId?
|
||||
Meteor.Shapes.remove({meetingId: meetingId}, Meteor.log.info "cleared Shapes Collection (meetingId: #{meetingId}!")
|
||||
else
|
||||
Meteor.Shapes.remove({}, Meteor.log.info "cleared Shapes Collection (all meetings)!")
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# end Private methods on server
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
@ -39,6 +39,14 @@
|
||||
if id?
|
||||
Meteor.Slides.remove(id._id)
|
||||
Meteor.log.info "----removed slide[" + slideId + "] from " + meetingId
|
||||
|
||||
# called on server start and meeting end
|
||||
@clearSlidesCollection = (meetingId) ->
|
||||
if meetingId?
|
||||
Meteor.Slides.remove({meetingId: meetingId}, Meteor.log.info "cleared Slides Collection (meetingId: #{meetingId}!")
|
||||
else
|
||||
Meteor.Slides.remove({}, Meteor.log.info "cleared Slides Collection (all meetings)!")
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# end Private methods on server
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
@ -117,17 +117,6 @@ Meteor.methods
|
||||
Meteor.log.info "marking user [#{userId}] as offline in meeting[#{meetingId}]"
|
||||
Meteor.Users.update({'meetingId': meetingId, 'userId': userId}, {$set:{'user.connection_status':'offline'}})
|
||||
|
||||
# Only callable from server
|
||||
# when the meeting ends
|
||||
@removeUserFromCollection = (meetingId, userId) ->
|
||||
Meteor.log.info "in users::removeUserFromCollection, #{meetingId} #{userId}"
|
||||
u = Meteor.Users.findOne({'meetingId': meetingId, 'userId': userId})
|
||||
if u?
|
||||
Meteor.Users.remove(u._id)
|
||||
Meteor.log.info "----removed user[" + userId + "] from " + meetingId
|
||||
else
|
||||
Meteor.log.info "did not find a user [userId] to delete in meetingid:#{meetingId}"
|
||||
|
||||
|
||||
# Corresponds to a valid action on the HTML clientside
|
||||
# After authorization, publish a user_leaving_request in redis
|
||||
@ -272,3 +261,10 @@ Meteor.methods
|
||||
id = Meteor.Users.insert(entry)
|
||||
Meteor.log.info "added user dummy user id=[#{id}]:#{user.name}.
|
||||
Users.size is now #{Meteor.Users.find({meetingId: meetingId}).count()}"
|
||||
|
||||
# called on server start and on meeting end
|
||||
@clearUsersCollection = (meetingId) ->
|
||||
if meetingId?
|
||||
Meteor.Users.remove({meetingId: meetingId}, Meteor.log.info "cleared Users Collection (meetingId: #{meetingId}!")
|
||||
else
|
||||
Meteor.Users.remove({}, Meteor.log.info "cleared Users Collection (all meetings)!")
|
||||
|
@ -64,18 +64,3 @@ Meteor.publish 'meetings', (meetingId) ->
|
||||
Meteor.publish 'presentations', (meetingId) ->
|
||||
Meteor.log.info "publishing presentations for #{meetingId}"
|
||||
Meteor.Presentations.find({meetingId: meetingId})
|
||||
|
||||
# Clear all data in subcriptions
|
||||
@clearCollections = ->
|
||||
Meteor.Users.remove({})
|
||||
Meteor.log.info "cleared Users Collection!"
|
||||
Meteor.Chat.remove({})
|
||||
Meteor.log.info "cleared Chat Collection!"
|
||||
Meteor.Meetings.remove({})
|
||||
Meteor.log.info "cleared Meetings Collection!"
|
||||
Meteor.Shapes.remove({})
|
||||
Meteor.log.info "cleared Shapes Collection!"
|
||||
Meteor.Slides.remove({})
|
||||
Meteor.log.info "cleared Slides Collection!"
|
||||
Meteor.Presentations.remove({})
|
||||
Meteor.log.info "cleared Presentations Collection!"
|
||||
|
@ -2,7 +2,12 @@ Meteor.startup ->
|
||||
Meteor.log.info "server start"
|
||||
|
||||
#remove all data
|
||||
clearCollections()
|
||||
clearUsersCollection()
|
||||
clearChatCollection()
|
||||
clearMeetingsCollection()
|
||||
clearShapesCollection()
|
||||
clearSlidesCollection()
|
||||
clearPresentationsCollection()
|
||||
|
||||
# create create a PubSub connection, start listening
|
||||
Meteor.redisPubSub = new Meteor.RedisPubSub(->
|
||||
|
@ -1,4 +1,4 @@
|
||||
xdescribe("Collections", function () {
|
||||
describe("Collections", function () {
|
||||
beforeEach(function () {
|
||||
MeteorStubs.install();
|
||||
});
|
||||
@ -19,7 +19,12 @@ xdescribe("Collections", function () {
|
||||
spyOn(Meteor.Slides, "remove");
|
||||
spyOn(Meteor.Presentations, "remove");
|
||||
|
||||
clearCollections();
|
||||
clearUsersCollection();
|
||||
clearChatCollection();
|
||||
clearMeetingsCollection();
|
||||
clearShapesCollection();
|
||||
clearSlidesCollection();
|
||||
clearPresentationsCollection();
|
||||
|
||||
expect(Meteor.Users.remove).toHaveBeenCalled();
|
||||
expect(Meteor.Chat.remove).toHaveBeenCalled();
|
||||
@ -35,8 +40,8 @@ xdescribe("Collections", function () {
|
||||
|
||||
it("should be handled correctly by insert() on calling addChatToCollection() in case of private chat", function () {
|
||||
spyOn(Meteor.Users, "findOne").and.callFake(function(doc) {
|
||||
if(doc.userId == "user001") return { _id: "dbid001" };
|
||||
else if(doc.userId == "user002") return { _id: "dbid002" };
|
||||
if(doc.userId == "user001") return { userId: "user001" };
|
||||
else if(doc.userId == "user002") return { userUd: "user002" };
|
||||
});
|
||||
spyOn(Meteor.Chat, "insert");
|
||||
|
||||
@ -61,8 +66,8 @@ xdescribe("Collections", function () {
|
||||
to_username: "Anton",
|
||||
from_tz_offset: "240",
|
||||
from_color: "0x000000",
|
||||
to_userid: "dbid002",//not "user002"
|
||||
from_userid: "dbid001",//not "user001"
|
||||
to_userid: "user002",//not "dbid002"
|
||||
from_userid: "user001",//not "dbid001"
|
||||
from_time: "123",
|
||||
from_username: "Maxim",
|
||||
from_lang: "en"
|
||||
@ -99,7 +104,7 @@ xdescribe("Collections", function () {
|
||||
from_tz_offset: "240",
|
||||
from_color: "0x000000",
|
||||
to_userid: "public_chat_userid",
|
||||
from_userid: "dbid001",
|
||||
from_userid: "user001",
|
||||
from_time: "123",
|
||||
from_username: "Maxim",
|
||||
from_lang: "en"
|
||||
|
Loading…
Reference in New Issue
Block a user