diff --git a/bigbluebutton-html5/app/.meteor/packages b/bigbluebutton-html5/app/.meteor/packages
index 6979814ab4..29fd9b6c68 100644
--- a/bigbluebutton-html5/app/.meteor/packages
+++ b/bigbluebutton-html5/app/.meteor/packages
@@ -26,3 +26,5 @@ pagebakers:ionicons
ewall:foundation
maibaum:foundation-icons
gthacoder:sled
+chriswessels:hammer@3.1.1
+fastclick
diff --git a/bigbluebutton-html5/app/.meteor/versions b/bigbluebutton-html5/app/.meteor/versions
index 0171800fdf..0ef915fabd 100644
--- a/bigbluebutton-html5/app/.meteor/versions
+++ b/bigbluebutton-html5/app/.meteor/versions
@@ -1,5 +1,6 @@
agnito:raphael@0.1.0
aldeed:simple-schema@1.3.2
+aldeed:template-extension@3.4.3
amplify@1.0.0
arunoda:npm@0.2.6
autoupdate@1.2.1
@@ -12,6 +13,7 @@ brentjanderson:winston-client@0.2.1
callback-hook@1.0.3
cfs:http-methods@0.0.27
check@1.0.5
+chriswessels:hammer@3.1.1
clinical:nightwatch@2.0.1
coffeescript@1.0.6
ddp@1.1.0
diff --git a/bigbluebutton-html5/app/client/globals.coffee b/bigbluebutton-html5/app/client/globals.coffee
index 07309b2d6d..9f3c413af9 100755
--- a/bigbluebutton-html5/app/client/globals.coffee
+++ b/bigbluebutton-html5/app/client/globals.coffee
@@ -34,6 +34,10 @@
@getTime = -> # returns epoch in ms
(new Date).valueOf()
+# checks if the pan gesture is mostly horizontal
+@isPanHorizontal = (event) ->
+ Math.abs(event.deltaX) > Math.abs(event.deltaY)
+
# helper to determine whether user has joined any type of audio
Handlebars.registerHelper "amIInAudio", ->
BBB.amIInAudio()
@@ -253,10 +257,14 @@ Handlebars.registerHelper 'whiteboardSize', (section) ->
setInSession 'chats', chats
@toggleShield = ->
- if $('.shield').hasClass('darken')
- $('.shield').removeClass('darken')
- else
+ if parseFloat($('.shield').css('opacity')) is 0.5 # triggered during a pan gesture
+ $('.shield').css('opacity', '')
+
+ if !$('.shield').hasClass('darken') and !$('.shield').hasClass('animatedShield')
$('.shield').addClass('darken')
+ else
+ $('.shield').removeClass('darken')
+ $('.shield').removeClass('animatedShield')
@removeFullscreenStyles = ->
$('#whiteboard-paper').removeClass('verticallyCentered')
diff --git a/bigbluebutton-html5/app/client/main.coffee b/bigbluebutton-html5/app/client/main.coffee
index 8c8bac3b4b..355f0464c4 100755
--- a/bigbluebutton-html5/app/client/main.coffee
+++ b/bigbluebutton-html5/app/client/main.coffee
@@ -141,5 +141,177 @@ Template.main.events
$('.signOutIcon').blur()
$("#logoutModal").foundation('reveal', 'open');
+Template.main.gestures
+ 'panstart #container': (event, template) ->
+ if isPortraitMobile() and isPanHorizontal(event)
+ panIsValid = getInSession('panIsValid')
+ initTransformValue = getInSession('initTransform')
+ menuPanned = getInSession('menuPanned')
+ screenWidth = $('#container').width()
+
+ setInSession 'panStarted', true
+
+ if panIsValid and
+ menuPanned is 'left' and
+ initTransformValue + event.deltaX >= 0 and
+ initTransformValue + event.deltaX <= $('.left-drawer').width()
+ $('.left-drawer').css('transform', 'translateX(' + (initTransformValue + event.deltaX) + 'px)')
+
+ else if panIsValid and
+ menuPanned is 'right' and
+ initTransformValue + event.deltaX >= screenWidth - $('.right-drawer').width() and
+ initTransformValue + event.deltaX <= screenWidth
+ $('.right-drawer').css('transform', 'translateX(' + (initTransformValue + event.deltaX) + 'px)')
+
+ 'panend #container': (event, template) ->
+ if isPortraitMobile()
+ panIsValid = getInSession('panIsValid')
+ menuPanned = getInSession('menuPanned')
+ leftDrawerWidth = $('.left-drawer').width()
+ screenWidth = $('#container').width()
+
+ setInSession 'panStarted', false
+
+ if panIsValid and
+ menuPanned is 'left' and
+ $('.left-drawer').css('transform') isnt 'none'
+
+ if parseInt($('.left-drawer').css('transform').split(',')[4]) < leftDrawerWidth / 2
+ $('.shield').removeClass('animatedShield')
+ $('.shield').css('opacity', '')
+ $('.left-drawer').removeClass('sl-left-drawer-out')
+ $('.left-drawer').css('transform', '')
+ $('.toggleUserlistButton').removeClass('sl-toggled-on')
+ $('.shield').removeClass('darken') # in case it was opened by clicking a button
+ else
+ $('.left-drawer').css('transform', 'translateX(' + leftDrawerWidth + 'px)')
+ $('.shield').css('opacity', 0.5)
+ $('.left-drawer').addClass('sl-left-drawer-out')
+ $('.left-drawer').css('transform', '')
+ $('.toggleUserlistButton').addClass('sl-toggled-on')
+
+ if panIsValid and
+ menuPanned is 'right' and
+ parseInt($('.right-drawer').css('transform').split(',')[4]) isnt leftDrawerWidth
+
+ if parseInt($('.right-drawer').css('transform').split(',')[4]) > screenWidth - $('.right-drawer').width() / 2
+ $('.shield').removeClass('animatedShield')
+ $('.shield').css('opacity', '')
+ $('.right-drawer').css('transform', 'translateX(' + screenWidth + 'px)')
+ $('.right-drawer').removeClass('sl-right-drawer-out')
+ $('.right-drawer').css('transform', '')
+ $('.toggleMenuButton').removeClass('sl-toggled-on')
+ $('.shield').removeClass('darken') # in case it was opened by clicking a button
+ else
+ $('.shield').css('opacity', 0.5)
+ $('.right-drawer').css('transform', 'translateX(' + (screenWidth - $('.right-drawer').width()) + 'px)')
+ $('.right-drawer').addClass('sl-right-drawer-out')
+ $('.right-drawer').css('transform', '')
+ $('.toggleMenuButton').addClass('sl-toggled-on')
+
+ $('.left-drawer').addClass('sl-left-drawer')
+ $('.sl-left-drawer').removeClass('left-drawer')
+
+ $('.right-drawer').addClass('sl-right-drawer')
+ $('.sl-right-drawer').removeClass('right-drawer')
+
+ 'panright #container, panleft #container': (event, template) ->
+ if isPortraitMobile() and isPanHorizontal(event)
+
+ # panright/panleft is always triggered once right before panstart
+ if !getInSession('panStarted')
+
+ # opening the left-hand menu
+ if event.type is 'panright' and
+ event.center.x <= $('#container').width() * 0.1
+ setInSession 'panIsValid', true
+ setInSession 'menuPanned', 'left'
+
+ # closing the left-hand menu
+ else if event.type is 'panleft' and
+ event.center.x < $('#container').width() * 0.9
+ setInSession 'panIsValid', true
+ setInSession 'menuPanned', 'left'
+
+ # opening the right-hand menu
+ else if event.type is 'panleft' and
+ event.center.x >= $('#container').width() * 0.9
+ setInSession 'panIsValid', true
+ setInSession 'menuPanned', 'right'
+
+ # closing the right-hand menu
+ else if event.type is 'panright' and
+ event.center.x > $('#container').width() * 0.1
+ setInSession 'panIsValid', true
+ setInSession 'menuPanned', 'right'
+
+ else
+ setInSession 'panIsValid', false
+
+ setInSession 'eventType', event.type
+
+ if getInSession('menuPanned') is 'left'
+ if $('.sl-left-drawer').css('transform') isnt 'none' # menu is already transformed
+ setInSession 'initTransform', parseInt($('.sl-left-drawer').css('transform').split(',')[4]) # translateX value
+ else if $('.sl-left-drawer').hasClass('sl-left-drawer-out')
+ setInSession 'initTransform', $('.sl-left-drawer').width()
+ else
+ setInSession 'initTransform', 0
+ $('.sl-left-drawer').addClass('left-drawer')
+ $('.left-drawer').removeClass('sl-left-drawer') # to prevent animations from Sled library
+ $('.left-drawer').removeClass('sl-left-drawer-content-delay') # makes the menu content movable too
+
+ else if getInSession('menuPanned') is 'right'
+ if $('.sl-right-drawer').css('transform') isnt 'none' # menu is already transformed
+ setInSession 'initTransform', parseInt($('.sl-right-drawer').css('transform').split(',')[4]) # translateX value
+ else if $('.sl-right-drawer').hasClass('sl-right-drawer-out')
+ setInSession 'initTransform', $('.sl-right-drawer').width()
+ else
+ setInSession 'initTransform', 0
+ $('.sl-right-drawer').addClass('right-drawer')
+ $('.right-drawer').removeClass('sl-right-drawer') # to prevent animations from Sled library
+ $('.right-drawer').removeClass('sl-right-drawer-content-delay') # makes the menu content movable too
+
+ initTransformValue = getInSession('initTransform')
+ panIsValid = getInSession('panIsValid')
+ menuPanned = getInSession('menuPanned')
+ leftDrawerWidth = $('.left-drawer').width()
+ rightDrawerWidth = $('.right-drawer').width()
+ screenWidth = $('#container').width()
+
+ # moving the left-hand menu
+ if panIsValid and
+ menuPanned is 'left' and
+ initTransformValue + event.deltaX >= 0 and
+ initTransformValue + event.deltaX <= leftDrawerWidth
+
+ if $('.sl-right-drawer').hasClass('sl-right-drawer-out')
+ toggleRightDrawer()
+ toggleRightArrowClockwise()
+
+ $('.left-drawer').css('transform', 'translateX(' + (initTransformValue + event.deltaX) + 'px)')
+
+ if !getInSession('panStarted')
+ $('.shield').addClass('animatedShield')
+ $('.shield').css('opacity',
+ 0.5 * (initTransformValue + event.deltaX) / leftDrawerWidth)
+
+ # moving the right-hand menu
+ else if panIsValid and
+ menuPanned is 'right' and
+ initTransformValue + event.deltaX >= screenWidth - rightDrawerWidth and
+ initTransformValue + event.deltaX <= screenWidth
+
+ if $('.sl-left-drawer').hasClass('sl-left-drawer-out')
+ toggleLeftDrawer()
+ toggleLeftArrowClockwise()
+
+ $('.right-drawer').css('transform', 'translateX(' + (initTransformValue + event.deltaX) + 'px)')
+
+ if !getInSession('panStarted')
+ $('.shield').addClass('animatedShield')
+ $('.shield').css('opacity',
+ 0.5 * (screenWidth - initTransformValue - event.deltaX) / rightDrawerWidth)
+
Template.makeButton.rendered = ->
$('button[rel=tooltip]').tooltip()
diff --git a/bigbluebutton-html5/app/client/stylesheets/style.less b/bigbluebutton-html5/app/client/stylesheets/style.less
index 23e5ebd4cd..414092a41d 100755
--- a/bigbluebutton-html5/app/client/stylesheets/style.less
+++ b/bigbluebutton-html5/app/client/stylesheets/style.less
@@ -126,25 +126,30 @@ body {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- @media @landscape {
- color: extract(@darkGrey, 1);
- font-size: 16px;
- width: 30% !important;
- }
+ position: absolute;
@media @mobile-portrait-with-keyboard, @mobile-portrait {
color: extract(@white, 1);
- font-size: 30px;
- padding-top: 30px;
- padding-left: 5px;
+ font-size: 35px;
height: 72px;
- width: 70%;
+ max-width: 70%;
margin-left: auto;
margin-right: auto;
+ height: 110px;
+ padding-top: 55px; // half the height
+ padding-left: 30px;
}
@media @desktop-portrait {
+ max-width: calc(~'100% - 155px'); // navbar width minus the space for 3 buttons
+ }
+ @media @landscape {
+ max-width: calc(~'100% - 125px'); // navbar width minus the space for 4 buttons
+ }
+ @media @landscape, @desktop-portrait {
color: extract(@darkGrey, 1);
font-size: 16px;
- width: calc(~'100% - 102.4px');
+ height: 50px;
+ padding-top: 25px; // half the height
+ padding-left: 15px;
}
}
}
@@ -377,6 +382,10 @@ body {
z-index: 1001;
}
+.toggleUserlistButton {
+ outline: none;
+}
+
.settingsIcon {
@media @landscape {
&:hover {
@@ -561,7 +570,7 @@ body {
@media @landscape {
display: none;
}
- &:not(.darken) {
+ &:not(.darken):not(.animatedShield) {
display: none;
}
}
@@ -585,3 +594,22 @@ body {
display: none; // hides the sizing handle everywhere except the landscape mode
}
}
+
+// same as Sled's left drawer except for animations
+.left-drawer {
+ z-index: 1000;
+ position: fixed;
+ width: 60vw;
+ left: -60vw;
+ height: 100%;
+}
+
+// same as Sled's right drawer except for animations
+.right-drawer {
+ z-index: 1000;
+ position: fixed;
+ transform: translateX(100vw);
+ height: 100%;
+ .linear-gradient(rgb(65,68,77), rgb(58,60,69));
+ width: 60vw;
+}