From c8f53d77588c211fcaacb891c6504d3528281c87 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Wed, 6 Aug 2014 15:16:40 +0200 Subject: [PATCH 01/15] Base ui to support uploading of pictures. --- static/js/directives/buddypictureupload.js | 50 ++++++++++++++++++++++ static/js/directives/directives.js | 4 +- static/partials/buddypicturecapture.html | 4 +- static/partials/buddypictureupload.html | 11 +++++ 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 static/js/directives/buddypictureupload.js create mode 100644 static/partials/buddypictureupload.html diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js new file mode 100644 index 00000000..a30c57e7 --- /dev/null +++ b/static/js/directives/buddypictureupload.js @@ -0,0 +1,50 @@ +/* + * Spreed WebRTC. + * Copyright (C) 2013-2014 struktur AG + * + * This file is part of Spreed WebRTC. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ +define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], function($, _, template) { + + // buddyPictureUpload + return ["$compile", function($compile) { + + var controller = ['$scope', 'safeApply', '$timeout', '$q', function($scope, safeApply, $timeout, $q) { + + $scope.showUploadPicture = false; + + }]; + + var link = function($scope, $element) { + + $scope.canvasUpload = $element.find("canvas.uploadPrev").get(0); + $($scope.canvasUpload).attr($scope.captureSize); + + }; + + return { + restrict: 'E', + transclude: true, + replace: true, + template: template, + controller: controller, + link: link + }; + + }]; + +}); diff --git a/static/js/directives/directives.js b/static/js/directives/directives.js index c233311c..fae2b192 100644 --- a/static/js/directives/directives.js +++ b/static/js/directives/directives.js @@ -26,6 +26,7 @@ define([ 'directives/statusmessage', 'directives/buddylist', 'directives/buddypicturecapture', + 'directives/buddypictureupload', 'directives/settings', 'directives/chat', 'directives/audiovideo', @@ -41,7 +42,7 @@ define([ 'directives/pdfcanvas', 'directives/odfcanvas', 'directives/presentation', - 'directives/youtubevideo',], function(_, onEnter, onEscape, statusMessage, buddyList, buddyPictureCapture, settings, chat, audioVideo, usability, audioLevel, fileInfo, screenshare, roomBar, socialShare, page, contactRequest, defaultDialog, pdfcanvas, odfcanvas, presentation, youtubevideo) { + 'directives/youtubevideo',], function(_, onEnter, onEscape, statusMessage, buddyList, buddyPictureCapture, buddyPictureUpload,settings, chat, audioVideo, usability, audioLevel, fileInfo, screenshare, roomBar, socialShare, page, contactRequest, defaultDialog, pdfcanvas, odfcanvas, presentation, youtubevideo) { var directives = { onEnter: onEnter, @@ -49,6 +50,7 @@ define([ statusMessage: statusMessage, buddyList: buddyList, buddyPictureCapture: buddyPictureCapture, + buddyPictureUpload: buddyPictureUpload, settings: settings, chat: chat, audioVideo: audioVideo, diff --git a/static/partials/buddypicturecapture.html b/static/partials/buddypicturecapture.html index 4c6ef454..57563ad3 100644 --- a/static/partials/buddypicturecapture.html +++ b/static/partials/buddypicturecapture.html @@ -18,7 +18,9 @@ {{_('Set as Profile Picture')}} - {{_('Take picture')}} + + {{_('Take picture')}} + {{_('Upload picture')}} {{_('Waiting for camera')}} diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html new file mode 100644 index 00000000..93795a8f --- /dev/null +++ b/static/partials/buddypictureupload.html @@ -0,0 +1,11 @@ +
+
+ + +

Please choose a picture to upload

+
+
+
+ {{_('Cancel')}} + {{_('Set as Profile Picture')}} +
From ae2163c5926ca391ea7fa2a68af4879832fabeef Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Wed, 6 Aug 2014 16:58:50 +0200 Subject: [PATCH 02/15] Add file events. --- static/js/directives/buddypictureupload.js | 42 ++++++++++++++++++++-- static/partials/buddypictureupload.html | 2 +- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index a30c57e7..b3fd8377 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -26,13 +26,51 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var controller = ['$scope', 'safeApply', '$timeout', '$q', function($scope, safeApply, $timeout, $q) { $scope.showUploadPicture = false; + $scope.previewUpload = false; + + $scope.handleUpload = function(event) { + var file = event.target.files[0]; + console.log('file', file); + + if(!file.type.match(/image/)) { + error({event: {target: {error: {name: 'NotImage'}}}}); + } + + var reader = new FileReader(); + reader.readAsArrayBuffer(file); + + var progress = function(event) { + console.log('file progress', event); + }; + var load = function(event) { + console.log('file load', event); + var fileBuffer = event.target.result; + // var context = $scope.uploadPrev.getContext('2d'); + // context.putImageData(fileBuffer, 0, 0); + // $scope.previewUpload = true; + }; + var error = function(event) { + console.log('file error', event); + if(event.target.error.name == 'NotReadableError') { + // file couldn't be read + } + if(event.target.error.name == 'NotImage') { + // file is not an image + } + }; + + reader.onprogress = progress; + reader.onload = load; + reader.onerror = error; + }; }]; var link = function($scope, $element) { - $scope.canvasUpload = $element.find("canvas.uploadPrev").get(0); - $($scope.canvasUpload).attr($scope.captureSize); + $element.find("#uploadFile").on('change', $scope.handleUpload); + $scope.uploadPrev = $element.find("canvas.uploadPrev").get(0); + $($scope.uploadPrev).attr($scope.captureSize); }; diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html index 93795a8f..c3e23d00 100644 --- a/static/partials/buddypictureupload.html +++ b/static/partials/buddypictureupload.html @@ -3,7 +3,7 @@

Please choose a picture to upload

-
+

{{_('Cancel')}} From 0415ef0def06d03642a34d71639bbeab7c566df4 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Thu, 14 Aug 2014 15:38:00 +0200 Subject: [PATCH 03/15] Initial upload support. --- src/styles/main.scss | 1 + static/js/directives/buddypicturecapture.js | 8 +- static/js/directives/buddypictureupload.js | 90 ++++++++++++++++----- static/partials/buddypictureupload.html | 18 +++-- static/partials/settings.html | 2 - 5 files changed, 85 insertions(+), 34 deletions(-) diff --git a/src/styles/main.scss b/src/styles/main.scss index 0f597648..a260a449 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -39,6 +39,7 @@ @import "components/bar"; @import "components/buddylist"; @import "components/buddypicturecapture"; +@import "components/buddypictureupload"; @import "components/settings"; @import "components/chat"; @import "components/usability"; diff --git a/static/js/directives/buddypicturecapture.js b/static/js/directives/buddypicturecapture.js index 9bd5b048..a10a8987 100644 --- a/static/js/directives/buddypicturecapture.js +++ b/static/js/directives/buddypicturecapture.js @@ -61,7 +61,7 @@ define(['jquery', 'underscore', 'text!partials/buddypicturecapture.html'], funct } }; - var writeVideoToCanvas = function(canvas) { + $scope.writeToCanvas = function(canvas, data) { var videoWidth = $scope.video.videoWidth; var videoHeight = $scope.video.videoHeight; @@ -83,12 +83,12 @@ define(['jquery', 'underscore', 'text!partials/buddypicturecapture.html'], funct height = height * aspectRatio; } - canvas.getContext("2d").drawImage($scope.video, x, y, width, height); + canvas.getContext("2d").drawImage(data, x, y, width, height); } var writePreviewPic = function() { - writeVideoToCanvas($scope.canvasPrev); + $scope.writeToCanvas($scope.canvasPrev, $scope.video); $scope.preview = $scope.canvasPrev.toDataURL("image/jpeg"); }; @@ -167,7 +167,7 @@ define(['jquery', 'underscore', 'text!partials/buddypicturecapture.html'], funct }; $scope.setAsProfilePicture = function() { - writeVideoToCanvas($scope.canvasPic); + $scope.writeToCanvas($scope.canvasPic, $scope.video); $scope.user.buddyPicture = $scope.canvasPic.toDataURL("image/jpeg"); //console.info("Image size", $scope.user.buddyPicture.length); $scope.cancelPicture(); diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index b3fd8377..34762f37 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -23,61 +23,111 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi // buddyPictureUpload return ["$compile", function($compile) { - var controller = ['$scope', 'safeApply', '$timeout', '$q', function($scope, safeApply, $timeout, $q) { + var controller = ['$scope', 'safeApply', '$timeout', '$q', 'translation', function($scope, safeApply, $timeout, $q, translation) { + var previewWidth = 198; + var previewHeight = 198; $scope.showUploadPicture = false; $scope.previewUpload = false; + $scope.imgData = null; + $scope.error = { + msg: null + }; + $scope.text = { + initial: 'Please choose a picture to upload', + again: 'Upload a different picture' + }; + + var setUploadImageDimension = function(data) { + var img = new Image(); + img.onload = function() { + if(this.width < previewWidth && this.height < previewHeight) { + $scope.prevImage.style.height = null; + $scope.prevImage.style.width = null; + return; + } + if (this.width < this.height) { + $scope.prevImage.style.width = previewWidth + 'px'; + $scope.prevImage.style.height = null; + console.log('changed width'); + } else { + $scope.prevImage.style.height = previewHeight + 'px'; + $scope.prevImage.style.width = null; + console.log('changed height'); + } + }; + img.src = data; + }; + + $scope.reset = function() { + $scope.showUploadPicture = false; + $scope.previewUpload = false; + }; $scope.handleUpload = function(event) { var file = event.target.files[0]; - console.log('file', file); - - if(!file.type.match(/image/)) { - error({event: {target: {error: {name: 'NotImage'}}}}); + if(!file) { + return; } - - var reader = new FileReader(); - reader.readAsArrayBuffer(file); + console.log('file', file); var progress = function(event) { console.log('file progress', event); }; var load = function(event) { console.log('file load', event); - var fileBuffer = event.target.result; - // var context = $scope.uploadPrev.getContext('2d'); - // context.putImageData(fileBuffer, 0, 0); - // $scope.previewUpload = true; + $scope.$apply(function(scope) { + scope.imgData = event.target.result; + setUploadImageDimension(scope.imgData); + $scope.previewUpload = true; + }); }; var error = function(event) { console.log('file error', event); if(event.target.error.name == 'NotReadableError') { - // file couldn't be read + $scope.$apply(function(scope) { + scope.error.msg = "The file couldn't be read"; + }); } if(event.target.error.name == 'NotImage') { - // file is not an image + $scope.$apply(function(scope) { + scope.error.msg = "The file is not an image."; + }); } }; - reader.onprogress = progress; - reader.onload = load; - reader.onerror = error; + if(!file.type.match(/image/)) { + error({target: {error: {name: 'NotImage'}}}); + } else { + var reader = new FileReader(); + reader.readAsDataURL(file); + + reader.onprogress = progress; + reader.onload = load; + reader.onerror = error; + } + }; + + $scope.usePicture = function() { + $scope.writeToCanvas($scope.canvasPic, $scope.prevImage); + $scope.user.buddyPicture = $scope.canvasPic.toDataURL("image/jpeg"); + $scope.reset(); + safeApply($scope); }; }]; var link = function($scope, $element) { - + $scope.prevImage = $(".showUploadPicture .preview").get(0); $element.find("#uploadFile").on('change', $scope.handleUpload); $scope.uploadPrev = $element.find("canvas.uploadPrev").get(0); $($scope.uploadPrev).attr($scope.captureSize); - }; return { restrict: 'E', transclude: true, - replace: true, + replace: false, template: template, controller: controller, link: link diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html index c3e23d00..7306b709 100644 --- a/static/partials/buddypictureupload.html +++ b/static/partials/buddypictureupload.html @@ -1,11 +1,13 @@ -
-
+
+
- -

Please choose a picture to upload

-
-
+
- {{_('Cancel')}} - {{_('Set as Profile Picture')}} +
{{error.msg}}
+

{{text.initial}}

+

{{text.again}}

+
+
+ {{_('Cancel')}} + {{_('Set as Profile Picture')}}
diff --git a/static/partials/settings.html b/static/partials/settings.html index e6c8bedf..a3e2719f 100644 --- a/static/partials/settings.html +++ b/static/partials/settings.html @@ -8,9 +8,7 @@
-
From 6a03331f351ecc3838d057495bea028c54d53a01 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Thu, 14 Aug 2014 15:38:55 +0200 Subject: [PATCH 04/15] Styles for feature. --- .../components/_buddypictureupload.scss | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/styles/components/_buddypictureupload.scss diff --git a/src/styles/components/_buddypictureupload.scss b/src/styles/components/_buddypictureupload.scss new file mode 100644 index 00000000..cf19babc --- /dev/null +++ b/src/styles/components/_buddypictureupload.scss @@ -0,0 +1,38 @@ +/* + * Spreed WebRTC. + * Copyright (C) 2013-2014 struktur AG + * + * This file is part of Spreed WebRTC. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +.buddyPictureUpload { + position: relative; + .previewUpload { + } + .showUploadPicture { + border: 1px solid #EEEEEE; + height: 200px; + line-height: 200px; + margin-bottom: 10px; + overflow: hidden; + text-align: center; + width: 200px; + } + .preview { + position: relative; + } +} From 8e31247910bbbda8c0fc8cfb2b8b71e1f5a1a024 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Thu, 14 Aug 2014 16:41:19 +0200 Subject: [PATCH 05/15] Rework how images are auto fit to preview and canvas. --- static/js/directives/buddypicturecapture.js | 8 ++-- static/js/directives/buddypictureupload.js | 44 ++++++++++++++------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/static/js/directives/buddypicturecapture.js b/static/js/directives/buddypicturecapture.js index a10a8987..9bd5b048 100644 --- a/static/js/directives/buddypicturecapture.js +++ b/static/js/directives/buddypicturecapture.js @@ -61,7 +61,7 @@ define(['jquery', 'underscore', 'text!partials/buddypicturecapture.html'], funct } }; - $scope.writeToCanvas = function(canvas, data) { + var writeVideoToCanvas = function(canvas) { var videoWidth = $scope.video.videoWidth; var videoHeight = $scope.video.videoHeight; @@ -83,12 +83,12 @@ define(['jquery', 'underscore', 'text!partials/buddypicturecapture.html'], funct height = height * aspectRatio; } - canvas.getContext("2d").drawImage(data, x, y, width, height); + canvas.getContext("2d").drawImage($scope.video, x, y, width, height); } var writePreviewPic = function() { - $scope.writeToCanvas($scope.canvasPrev, $scope.video); + writeVideoToCanvas($scope.canvasPrev); $scope.preview = $scope.canvasPrev.toDataURL("image/jpeg"); }; @@ -167,7 +167,7 @@ define(['jquery', 'underscore', 'text!partials/buddypicturecapture.html'], funct }; $scope.setAsProfilePicture = function() { - $scope.writeToCanvas($scope.canvasPic, $scope.video); + writeVideoToCanvas($scope.canvasPic); $scope.user.buddyPicture = $scope.canvasPic.toDataURL("image/jpeg"); //console.info("Image size", $scope.user.buddyPicture.length); $scope.cancelPicture(); diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 34762f37..99949a6f 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -41,20 +41,9 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var setUploadImageDimension = function(data) { var img = new Image(); img.onload = function() { - if(this.width < previewWidth && this.height < previewHeight) { - $scope.prevImage.style.height = null; - $scope.prevImage.style.width = null; - return; - } - if (this.width < this.height) { - $scope.prevImage.style.width = previewWidth + 'px'; - $scope.prevImage.style.height = null; - console.log('changed width'); - } else { - $scope.prevImage.style.height = previewHeight + 'px'; - $scope.prevImage.style.width = null; - console.log('changed height'); - } + var dim = getAutoFitDimensions(this, {width: previewWidth, height: previewHeight}); + $scope.prevImage.style.width = dim.width + 'px'; + $scope.prevImage.style.height = dim.height + 'px'; }; img.src = data; }; @@ -108,8 +97,33 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi } }; + // Auto fit by smallest dimension + var getAutoFitDimensions = function(from, to) { + if(!from.width && !from.height && !to.width && !to.height) { + return null; + } + var width = null; + var height = null; + + if (from.width < from.height) { + height = to.width * (from.height/from.width); + width = to.width; + } else { + height = to.height; + width = to.height * (from.width/from.height); + } + return{width: width, height: height}; + }; + + var writeUploadToCanvas = function(canvas, img) { + var x = 0; + var y = 0; + var dim = getAutoFitDimensions(img, canvas); + canvas.getContext("2d").drawImage(img, x, y, dim.width, dim.height); + }; + $scope.usePicture = function() { - $scope.writeToCanvas($scope.canvasPic, $scope.prevImage); + writeUploadToCanvas($scope.canvasPic, $scope.prevImage); $scope.user.buddyPicture = $scope.canvasPic.toDataURL("image/jpeg"); $scope.reset(); safeApply($scope); From 79b17cf0fe5b0ff9e0c6966260a0acec7aa44a25 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Fri, 15 Aug 2014 15:20:22 +0200 Subject: [PATCH 06/15] Support custom positioning image within preview box. --- .../components/_buddypictureupload.scss | 34 ++++++ static/js/directives/buddypictureupload.js | 100 ++++++++++++++++-- static/partials/buddypictureupload.html | 16 ++- 3 files changed, 141 insertions(+), 9 deletions(-) diff --git a/src/styles/components/_buddypictureupload.scss b/src/styles/components/_buddypictureupload.scss index cf19babc..26aa5102 100644 --- a/src/styles/components/_buddypictureupload.scss +++ b/src/styles/components/_buddypictureupload.scss @@ -34,5 +34,39 @@ } .preview { position: relative; + top: 0px; + left: 0px; + } + .moveImage { + position: relative; + visibility:hidden; + z-index: 1; + .fa { + cursor: pointer; + color: $componentbg; + text-shadow: 0 0 5px black; + opacity: 0.8; + font-size: 40px; + } + } + .showUploadPicture:hover .moveImage { + visibility:visible; + } + .moveHorizontal { + width: 200px; + position: absolute; + top: -75px; + left: 0; + .fa { + width: 50px; + } + } + .moveVertical { + position: absolute; + top: -30px; + left: 174px; + .item { + height: 50px; + } } } diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 99949a6f..d6cbd065 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -25,11 +25,14 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var controller = ['$scope', 'safeApply', '$timeout', '$q', 'translation', function($scope, safeApply, $timeout, $q, translation) { - var previewWidth = 198; - var previewHeight = 198; + var previewWidth = 200; + var previewHeight = 200; + $scope.moveHorizontal = false; + $scope.moveVertical = false; $scope.showUploadPicture = false; $scope.previewUpload = false; $scope.imgData = null; + $scope.showEditTools = false; $scope.error = { msg: null }; @@ -44,10 +47,27 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var dim = getAutoFitDimensions(this, {width: previewWidth, height: previewHeight}); $scope.prevImage.style.width = dim.width + 'px'; $scope.prevImage.style.height = dim.height + 'px'; + $scope.prevImage.style.top = '0px'; + $scope.prevImage.style.left = '0px'; + safeApply($scope); }; img.src = data; }; + var handleImageDrag = function(evt) { + evt.preventDefault(); + console.log('draggin image', evt.offsetX, evt.offsetY); + }; + var handleImageDrop = function(evt) { + evt.preventDefault(); + console.log('dropped image', evt); + }; + $scope.addImageMoveHandlers = function() { + $scope.prevImage.addEventListener('dragover', handleImageDrag); + $scope.prevImage.addEventListener('drop', handleImageDrop); + }; + + $scope.reset = function() { $scope.showUploadPicture = false; $scope.previewUpload = false; @@ -97,29 +117,49 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi } }; + var getNumFromPx = function(px) { + return px.match(/[\-0-9]+/) ? Number(px.match(/[\-0-9]+/)[0]) : 0; + }; + // Auto fit by smallest dimension + // (image, canvas) -> object var getAutoFitDimensions = function(from, to) { if(!from.width && !from.height && !to.width && !to.height) { return null; } var width = null; var height = null; + var x = null; + var y = null; + var fromAspectRatio = 1; + var scaleFactorX = 1; + var scaleFactorY = 1; if (from.width < from.height) { - height = to.width * (from.height/from.width); + fromAspectRatio = from.height/from.width; + scaleFactorX = to.width/from.width; + scaleFactorY = to.height/from.height; width = to.width; + height = to.width * fromAspectRatio; + x = scaleFactorX * getNumFromPx(from.style.left); + y = (scaleFactorY * getNumFromPx(from.style.top)) * fromAspectRatio; } else { + fromAspectRatio = from.width/from.height; + scaleFactorX = to.width/from.width; + scaleFactorY = to.height/from.height; + width = to.height * fromAspectRatio; height = to.height; - width = to.height * (from.width/from.height); + x = (scaleFactorX * getNumFromPx(from.style.left)) * fromAspectRatio; + y = scaleFactorY * getNumFromPx(from.style.top); } - return{width: width, height: height}; + + return{width: width, height: height, x: x, y: y}; }; var writeUploadToCanvas = function(canvas, img) { - var x = 0; - var y = 0; var dim = getAutoFitDimensions(img, canvas); - canvas.getContext("2d").drawImage(img, x, y, dim.width, dim.height); + canvas.getContext("2d").drawImage(img, dim.x, dim.y, dim.width, dim.height); + console.log('writeUploadToCanvas', dim); }; $scope.usePicture = function() { @@ -133,9 +173,53 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var link = function($scope, $element) { $scope.prevImage = $(".showUploadPicture .preview").get(0); + $scope.addImageMoveHandlers(); $element.find("#uploadFile").on('change', $scope.handleUpload); $scope.uploadPrev = $element.find("canvas.uploadPrev").get(0); $($scope.uploadPrev).attr($scope.captureSize); + + var intervalNum = { + num: null + }; + + var incrementPx = function(num) { + return ((Number(num.match(/[\-0-9]+/)) + 5) + 'px'); + }; + var decrementPx = function(num) { + return ((Number(num.match(/[\-0-9]+/)) - 5) + 'px'); + }; + var moveImageUp = function() { + $scope.prevImage.style.top = decrementPx($scope.prevImage.style.top); + }; + var moveImageDown = function() { + $scope.prevImage.style.top = incrementPx($scope.prevImage.style.top); + }; + var moveImageLeft = function() { + $scope.prevImage.style.left = decrementPx($scope.prevImage.style.left); + }; + var moveImageRight = function() { + $scope.prevImage.style.left = incrementPx($scope.prevImage.style.left); + }; + var moveImage = function(evt) { + if(evt.data.intervalNum.num || !evt.data.action) { + clearInterval(evt.data.intervalNum.num); + evt.data.intervalNum.num = null; + } else { + evt.data.intervalNum.num = setInterval(function() { + evt.data.action(); + }, 50); + } + }; + + $element.find("#arrow-up").on('mousedown', null, {intervalNum: intervalNum, action: moveImageUp}, moveImage); + $element.find("#arrow-down").on('mousedown', null, {intervalNum: intervalNum, action: moveImageDown}, moveImage); + $element.find("#arrow-up").on('mouseup', null, {intervalNum: intervalNum}, moveImage); + $element.find("#arrow-down").on('mouseup', null, {intervalNum: intervalNum}, moveImage); + + $element.find("#arrow-left").on('mousedown', null, {intervalNum: intervalNum, action: moveImageLeft}, moveImage); + $element.find("#arrow-right").on('mousedown', null, {intervalNum: intervalNum, action: moveImageRight}, moveImage); + $element.find("#arrow-left").on('mouseup', null, {intervalNum: intervalNum}, moveImage); + $element.find("#arrow-right").on('mouseup', null, {intervalNum: intervalNum}, moveImage); }; return { diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html index 7306b709..c1887385 100644 --- a/static/partials/buddypictureupload.html +++ b/static/partials/buddypictureupload.html @@ -1,6 +1,20 @@
-
+
+
+
+ + +
+
+
+ +
+
+ +
+
+
{{error.msg}}
From 2a9ddd18fac2637910e40415ba2fcee9ca901705 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Fri, 15 Aug 2014 17:49:42 +0200 Subject: [PATCH 07/15] Support scaling images larger and smaller. --- .../components/_buddypictureupload.scss | 31 ++++--- static/js/directives/buddypictureupload.js | 80 ++++++++++++------- static/partials/buddypictureupload.html | 14 ++-- 3 files changed, 74 insertions(+), 51 deletions(-) diff --git a/src/styles/components/_buddypictureupload.scss b/src/styles/components/_buddypictureupload.scss index 26aa5102..b155ab75 100644 --- a/src/styles/components/_buddypictureupload.scss +++ b/src/styles/components/_buddypictureupload.scss @@ -37,9 +37,11 @@ top: 0px; left: 0px; } - .moveImage { - position: relative; - visibility:hidden; + .imageUtilites { + line-height: 30px; + position: absolute; + visibility: hidden; + width: 200px; z-index: 1; .fa { cursor: pointer; @@ -47,26 +49,23 @@ text-shadow: 0 0 5px black; opacity: 0.8; font-size: 40px; + width: 50px; + height: 50px; } } - .showUploadPicture:hover .moveImage { + .showUploadPicture:hover .imageUtilites { visibility:visible; } .moveHorizontal { - width: 200px; - position: absolute; - top: -75px; - left: 0; - .fa { - width: 50px; - } + top: -4px; + position: relative; } .moveVertical { position: absolute; - top: -30px; - left: 174px; - .item { - height: 50px; - } + left: 158px; + } + .resize { + position: relative; + top: 108px; } } diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index d6cbd065..2594aafb 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -122,42 +122,53 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi }; // Auto fit by smallest dimension - // (image, canvas) -> object var getAutoFitDimensions = function(from, to) { if(!from.width && !from.height && !to.width && !to.height) { return null; } var width = null; var height = null; - var x = null; - var y = null; - var fromAspectRatio = 1; - var scaleFactorX = 1; - var scaleFactorY = 1; if (from.width < from.height) { - fromAspectRatio = from.height/from.width; - scaleFactorX = to.width/from.width; - scaleFactorY = to.height/from.height; + height = to.width * (from.height/from.width); width = to.width; - height = to.width * fromAspectRatio; - x = scaleFactorX * getNumFromPx(from.style.left); - y = (scaleFactorY * getNumFromPx(from.style.top)) * fromAspectRatio; } else { - fromAspectRatio = from.width/from.height; - scaleFactorX = to.width/from.width; - scaleFactorY = to.height/from.height; - width = to.height * fromAspectRatio; height = to.height; - x = (scaleFactorX * getNumFromPx(from.style.left)) * fromAspectRatio; - y = scaleFactorY * getNumFromPx(from.style.top); + width = to.height * (from.width/from.height); + } + return{width: width, height: height}; + }; + + // (image, canvas) -> object + var getScaledDimensions = function(from, to) { + if(!from.style.width && !from.style.height && !to.width && !to.height) { + return null; + } + var current = { + width: getNumFromPx(from.style.width), + height: getNumFromPx(from.style.height), + top: getNumFromPx(from.style.top), + left: getNumFromPx(from.style.left) + }; + var scaleFactorX = previewWidth / to.width; + var scaleFactorY = previewHeight / to.height; + var width = current.width / scaleFactorX; + var height = current.height / scaleFactorY; + var x = current.left / scaleFactorX; + var y = current.top / scaleFactorY; + if(current.width < previewWidth) { + x = ((previewWidth - current.width) / scaleFactorX ) / 2; + } + if(current.height < previewHeight) { + y = ((previewHeight - current.height) / scaleFactorY ) / 2; } return{width: width, height: height, x: x, y: y}; }; + var writeUploadToCanvas = function(canvas, img) { - var dim = getAutoFitDimensions(img, canvas); + var dim = getScaledDimensions(img, canvas); canvas.getContext("2d").drawImage(img, dim.x, dim.y, dim.width, dim.height); console.log('writeUploadToCanvas', dim); }; @@ -200,7 +211,15 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var moveImageRight = function() { $scope.prevImage.style.left = incrementPx($scope.prevImage.style.left); }; - var moveImage = function(evt) { + var makeImageLarger = function() { + $scope.prevImage.style.height = incrementPx($scope.prevImage.style.height); + $scope.prevImage.style.width = incrementPx($scope.prevImage.style.width); + }; + var makeImageSmaller = function() { + $scope.prevImage.style.height = decrementPx($scope.prevImage.style.height); + $scope.prevImage.style.width = decrementPx($scope.prevImage.style.width); + }; + var changeImage = function(evt) { if(evt.data.intervalNum.num || !evt.data.action) { clearInterval(evt.data.intervalNum.num); evt.data.intervalNum.num = null; @@ -211,15 +230,20 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi } }; - $element.find("#arrow-up").on('mousedown', null, {intervalNum: intervalNum, action: moveImageUp}, moveImage); - $element.find("#arrow-down").on('mousedown', null, {intervalNum: intervalNum, action: moveImageDown}, moveImage); - $element.find("#arrow-up").on('mouseup', null, {intervalNum: intervalNum}, moveImage); - $element.find("#arrow-down").on('mouseup', null, {intervalNum: intervalNum}, moveImage); + $element.find("#arrow-up").on('mousedown', null, {intervalNum: intervalNum, action: moveImageUp}, changeImage); + $element.find("#arrow-down").on('mousedown', null, {intervalNum: intervalNum, action: moveImageDown}, changeImage); + $element.find("#arrow-up").on('mouseup', null, {intervalNum: intervalNum}, changeImage); + $element.find("#arrow-down").on('mouseup', null, {intervalNum: intervalNum}, changeImage); + + $element.find("#arrow-left").on('mousedown', null, {intervalNum: intervalNum, action: moveImageLeft}, changeImage); + $element.find("#arrow-right").on('mousedown', null, {intervalNum: intervalNum, action: moveImageRight}, changeImage); + $element.find("#arrow-left").on('mouseup', null, {intervalNum: intervalNum}, changeImage); + $element.find("#arrow-right").on('mouseup', null, {intervalNum: intervalNum}, changeImage); - $element.find("#arrow-left").on('mousedown', null, {intervalNum: intervalNum, action: moveImageLeft}, moveImage); - $element.find("#arrow-right").on('mousedown', null, {intervalNum: intervalNum, action: moveImageRight}, moveImage); - $element.find("#arrow-left").on('mouseup', null, {intervalNum: intervalNum}, moveImage); - $element.find("#arrow-right").on('mouseup', null, {intervalNum: intervalNum}, moveImage); + $element.find("#larger").on('mousedown', null, {intervalNum: intervalNum, action: makeImageLarger}, changeImage); + $element.find("#smaller").on('mousedown', null, {intervalNum: intervalNum, action: makeImageSmaller}, changeImage); + $element.find("#larger").on('mouseup', null, {intervalNum: intervalNum}, changeImage); + $element.find("#smaller").on('mouseup', null, {intervalNum: intervalNum}, changeImage); }; return { diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html index c1887385..be04858d 100644 --- a/static/partials/buddypictureupload.html +++ b/static/partials/buddypictureupload.html @@ -1,18 +1,18 @@
-
+
-
- -
-
- -
+ + +
+
+ +
From 85a53ceb5872e047c5ece21ba1e757a0fecf328b Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Fri, 15 Aug 2014 18:02:46 +0200 Subject: [PATCH 08/15] Cleanup, make preview background black. --- .../components/_buddypictureupload.scss | 1 + static/js/directives/buddypictureupload.js | 37 ++++++------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/styles/components/_buddypictureupload.scss b/src/styles/components/_buddypictureupload.scss index b155ab75..1da8ebb0 100644 --- a/src/styles/components/_buddypictureupload.scss +++ b/src/styles/components/_buddypictureupload.scss @@ -31,6 +31,7 @@ overflow: hidden; text-align: center; width: 200px; + background-color: black; } .preview { position: relative; diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 2594aafb..692f3397 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -54,20 +54,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi img.src = data; }; - var handleImageDrag = function(evt) { - evt.preventDefault(); - console.log('draggin image', evt.offsetX, evt.offsetY); - }; - var handleImageDrop = function(evt) { - evt.preventDefault(); - console.log('dropped image', evt); - }; - $scope.addImageMoveHandlers = function() { - $scope.prevImage.addEventListener('dragover', handleImageDrag); - $scope.prevImage.addEventListener('drop', handleImageDrop); - }; - - $scope.reset = function() { $scope.showUploadPicture = false; $scope.previewUpload = false; @@ -75,7 +61,7 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi $scope.handleUpload = function(event) { var file = event.target.files[0]; - if(!file) { + if (!file) { return; } console.log('file', file); @@ -93,19 +79,19 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi }; var error = function(event) { console.log('file error', event); - if(event.target.error.name == 'NotReadableError') { + if (event.target.error.name == 'NotReadableError') { $scope.$apply(function(scope) { scope.error.msg = "The file couldn't be read"; }); } - if(event.target.error.name == 'NotImage') { + if (event.target.error.name == 'NotImage') { $scope.$apply(function(scope) { scope.error.msg = "The file is not an image."; }); } }; - if(!file.type.match(/image/)) { + if (!file.type.match(/image/)) { error({target: {error: {name: 'NotImage'}}}); } else { var reader = new FileReader(); @@ -123,7 +109,7 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi // Auto fit by smallest dimension var getAutoFitDimensions = function(from, to) { - if(!from.width && !from.height && !to.width && !to.height) { + if (!from.width && !from.height && !to.width && !to.height) { return null; } var width = null; @@ -136,12 +122,12 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi height = to.height; width = to.height * (from.width/from.height); } - return{width: width, height: height}; + return {width: width, height: height}; }; // (image, canvas) -> object var getScaledDimensions = function(from, to) { - if(!from.style.width && !from.style.height && !to.width && !to.height) { + if (!from.style.width && !from.style.height && !to.width && !to.height) { return null; } var current = { @@ -156,14 +142,14 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var height = current.height / scaleFactorY; var x = current.left / scaleFactorX; var y = current.top / scaleFactorY; - if(current.width < previewWidth) { + if (current.width < previewWidth) { x = ((previewWidth - current.width) / scaleFactorX ) / 2; } - if(current.height < previewHeight) { + if (current.height < previewHeight) { y = ((previewHeight - current.height) / scaleFactorY ) / 2; } - return{width: width, height: height, x: x, y: y}; + return {width: width, height: height, x: x, y: y}; }; @@ -184,7 +170,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var link = function($scope, $element) { $scope.prevImage = $(".showUploadPicture .preview").get(0); - $scope.addImageMoveHandlers(); $element.find("#uploadFile").on('change', $scope.handleUpload); $scope.uploadPrev = $element.find("canvas.uploadPrev").get(0); $($scope.uploadPrev).attr($scope.captureSize); @@ -220,7 +205,7 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi $scope.prevImage.style.width = decrementPx($scope.prevImage.style.width); }; var changeImage = function(evt) { - if(evt.data.intervalNum.num || !evt.data.action) { + if (evt.data.intervalNum.num || !evt.data.action) { clearInterval(evt.data.intervalNum.num); evt.data.intervalNum.num = null; } else { From 293d05ef296f101bbcb732dc1093fe35c5efde1d Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Tue, 19 Aug 2014 16:48:07 +0200 Subject: [PATCH 09/15] Cleanup. Clear canvas before appending data. Change image loading. --- static/js/directives/buddypictureupload.js | 37 +++++++++++----------- static/partials/buddypictureupload.html | 5 ++- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 692f3397..5a2f3d89 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -25,16 +25,15 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var controller = ['$scope', 'safeApply', '$timeout', '$q', 'translation', function($scope, safeApply, $timeout, $q, translation) { - var previewWidth = 200; - var previewHeight = 200; - $scope.moveHorizontal = false; - $scope.moveVertical = false; + var previewWidth = 205; + var previewHeight = 205; $scope.showUploadPicture = false; $scope.previewUpload = false; $scope.imgData = null; - $scope.showEditTools = false; $scope.error = { - msg: null + read: "The file couldn't be read", + image: "The file is not an image.", + current: null }; $scope.text = { initial: 'Please choose a picture to upload', @@ -42,16 +41,18 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi }; var setUploadImageDimension = function(data) { - var img = new Image(); - img.onload = function() { + $scope.prevImage.onload = function() { + // clear old dimensions + this.style.cssText = null; + // get new dimensions var dim = getAutoFitDimensions(this, {width: previewWidth, height: previewHeight}); - $scope.prevImage.style.width = dim.width + 'px'; - $scope.prevImage.style.height = dim.height + 'px'; - $scope.prevImage.style.top = '0px'; - $scope.prevImage.style.left = '0px'; + this.style.width = dim.width + 'px'; + this.style.height = dim.height + 'px'; + this.style.top = '0px'; + this.style.left = '0px'; safeApply($scope); }; - img.src = data; + $scope.prevImage.src = data; }; $scope.reset = function() { @@ -81,12 +82,12 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi console.log('file error', event); if (event.target.error.name == 'NotReadableError') { $scope.$apply(function(scope) { - scope.error.msg = "The file couldn't be read"; + scope.error.current = scope.error.read; }); } if (event.target.error.name == 'NotImage') { $scope.$apply(function(scope) { - scope.error.msg = "The file is not an image."; + scope.error.current = scope.error.image; }); } }; @@ -155,7 +156,9 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var writeUploadToCanvas = function(canvas, img) { var dim = getScaledDimensions(img, canvas); - canvas.getContext("2d").drawImage(img, dim.x, dim.y, dim.width, dim.height); + var context = canvas.getContext("2d"); + context.clearRect(0, 0, canvas.width, canvas.height); + context.drawImage(img, dim.x, dim.y, dim.width, dim.height); console.log('writeUploadToCanvas', dim); }; @@ -171,8 +174,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var link = function($scope, $element) { $scope.prevImage = $(".showUploadPicture .preview").get(0); $element.find("#uploadFile").on('change', $scope.handleUpload); - $scope.uploadPrev = $element.find("canvas.uploadPrev").get(0); - $($scope.uploadPrev).attr($scope.captureSize); var intervalNum = { num: null diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html index be04858d..3e49b54d 100644 --- a/static/partials/buddypictureupload.html +++ b/static/partials/buddypictureupload.html @@ -1,6 +1,5 @@
-
@@ -15,9 +14,9 @@
- +
-
{{error.msg}}
+
{{error.current}}

{{text.initial}}

{{text.again}}

From c6d6d6f6e4c9c0755d4058b442fb83a251110ecc Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Wed, 20 Aug 2014 10:32:58 +0200 Subject: [PATCH 10/15] Add file upload progress visual. --- static/js/directives/buddypictureupload.js | 21 +++++++++++++++++++-- static/partials/buddypictureupload.html | 4 ++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 5a2f3d89..1280ac33 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -25,8 +25,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var controller = ['$scope', 'safeApply', '$timeout', '$q', 'translation', function($scope, safeApply, $timeout, $q, translation) { - var previewWidth = 205; - var previewHeight = 205; $scope.showUploadPicture = false; $scope.previewUpload = false; $scope.imgData = null; @@ -39,6 +37,18 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi initial: 'Please choose a picture to upload', again: 'Upload a different picture' }; + $scope.upload = { + status: 0 + }; + var previewWidth = 205; + var previewHeight = 205; + + var completedUpload = function() { + $scope.upload.status = 99; + $timeout(function() { + $scope.upload.status = 100; + }, 500); + }; var setUploadImageDimension = function(data) { $scope.prevImage.onload = function() { @@ -50,6 +60,7 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi this.style.height = dim.height + 'px'; this.style.top = '0px'; this.style.left = '0px'; + completedUpload(); safeApply($scope); }; $scope.prevImage.src = data; @@ -66,9 +77,15 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi return; } console.log('file', file); + $scope.$apply(function(scope) { + $scope.upload.status = 5; + }); var progress = function(event) { console.log('file progress', event); + $scope.$apply(function(scope) { + $scope.upload.status = event.loaded/event.total * 100; + }); }; var load = function(event) { console.log('file load', event); diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html index 3e49b54d..e289d497 100644 --- a/static/partials/buddypictureupload.html +++ b/static/partials/buddypictureupload.html @@ -20,6 +20,10 @@

{{text.initial}}

{{text.again}}

+
+
+ {{upload.status | number:0}}% +

{{_('Cancel')}} {{_('Set as Profile Picture')}} From 72d3d3a641942a6be3be10175385849a098b5e85 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Wed, 20 Aug 2014 10:57:59 +0200 Subject: [PATCH 11/15] Implement max upload size. Fix progress indicator. --- static/js/directives/buddypictureupload.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 1280ac33..7dadde70 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -25,23 +25,25 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var controller = ['$scope', 'safeApply', '$timeout', '$q', 'translation', function($scope, safeApply, $timeout, $q, translation) { + var previewWidth = 205; + var previewHeight = 205; + var maxUploadMb = 8; $scope.showUploadPicture = false; $scope.previewUpload = false; $scope.imgData = null; $scope.error = { read: "The file couldn't be read", image: "The file is not an image.", + size: "The file is too large. Max upload size is " + maxUploadMb + 'Mb', current: null }; $scope.text = { - initial: 'Please choose a picture to upload', + initial: 'Please choose a picture to upload, max ' + maxUploadMb + 'Mb', again: 'Upload a different picture' }; $scope.upload = { status: 0 }; - var previewWidth = 205; - var previewHeight = 205; var completedUpload = function() { $scope.upload.status = 99; @@ -77,10 +79,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi return; } console.log('file', file); - $scope.$apply(function(scope) { - $scope.upload.status = 5; - }); - var progress = function(event) { console.log('file progress', event); $scope.$apply(function(scope) { @@ -107,11 +105,21 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi scope.error.current = scope.error.image; }); } + if (event.target.error.name == 'Size') { + $scope.$apply(function(scope) { + scope.error.current = scope.error.size; + }); + } }; if (!file.type.match(/image/)) { error({target: {error: {name: 'NotImage'}}}); + } else if (file.size > maxUploadMb * 1024 * 1024) { + error({target: {error: {name: 'Size'}}}); } else { + $scope.$apply(function(scope) { + $scope.upload.status = 5; + }); var reader = new FileReader(); reader.readAsDataURL(file); From a3b8f251afacaa84904f20218aceeaf999b3e2b5 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Wed, 20 Aug 2014 11:25:40 +0200 Subject: [PATCH 12/15] Comment out console logs. --- static/js/directives/buddypictureupload.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 7dadde70..726cb6c6 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -78,15 +78,15 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi if (!file) { return; } - console.log('file', file); + //console.log('file', file); var progress = function(event) { - console.log('file progress', event); + //console.log('file progress', event); $scope.$apply(function(scope) { $scope.upload.status = event.loaded/event.total * 100; }); }; var load = function(event) { - console.log('file load', event); + //console.log('file load', event); $scope.$apply(function(scope) { scope.imgData = event.target.result; setUploadImageDimension(scope.imgData); @@ -94,7 +94,7 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi }); }; var error = function(event) { - console.log('file error', event); + //console.log('file error', event); if (event.target.error.name == 'NotReadableError') { $scope.$apply(function(scope) { scope.error.current = scope.error.read; @@ -184,7 +184,7 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var context = canvas.getContext("2d"); context.clearRect(0, 0, canvas.width, canvas.height); context.drawImage(img, dim.x, dim.y, dim.width, dim.height); - console.log('writeUploadToCanvas', dim); + //console.log('writeUploadToCanvas', dim); }; $scope.usePicture = function() { From bea99f7148e365e699c28542b8b72b2602fafc18 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Wed, 20 Aug 2014 17:16:22 +0200 Subject: [PATCH 13/15] Move text outside of scope. Remove transclude. Improve method ordering. --- static/js/directives/buddypictureupload.js | 142 ++++++++++----------- static/partials/buddypictureupload.html | 8 +- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/static/js/directives/buddypictureupload.js b/static/js/directives/buddypictureupload.js index 726cb6c6..9c719f71 100644 --- a/static/js/directives/buddypictureupload.js +++ b/static/js/directives/buddypictureupload.js @@ -27,19 +27,15 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi var previewWidth = 205; var previewHeight = 205; - var maxUploadMb = 8; + $scope.maxUploadMb = 8; + var maxUploadBytes = $scope.maxUploadMb * 1024 * 1024; $scope.showUploadPicture = false; $scope.previewUpload = false; $scope.imgData = null; $scope.error = { - read: "The file couldn't be read", - image: "The file is not an image.", - size: "The file is too large. Max upload size is " + maxUploadMb + 'Mb', - current: null - }; - $scope.text = { - initial: 'Please choose a picture to upload, max ' + maxUploadMb + 'Mb', - again: 'Upload a different picture' + read: null, + image: null, + size: null }; $scope.upload = { status: 0 @@ -68,67 +64,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi $scope.prevImage.src = data; }; - $scope.reset = function() { - $scope.showUploadPicture = false; - $scope.previewUpload = false; - }; - - $scope.handleUpload = function(event) { - var file = event.target.files[0]; - if (!file) { - return; - } - //console.log('file', file); - var progress = function(event) { - //console.log('file progress', event); - $scope.$apply(function(scope) { - $scope.upload.status = event.loaded/event.total * 100; - }); - }; - var load = function(event) { - //console.log('file load', event); - $scope.$apply(function(scope) { - scope.imgData = event.target.result; - setUploadImageDimension(scope.imgData); - $scope.previewUpload = true; - }); - }; - var error = function(event) { - //console.log('file error', event); - if (event.target.error.name == 'NotReadableError') { - $scope.$apply(function(scope) { - scope.error.current = scope.error.read; - }); - } - if (event.target.error.name == 'NotImage') { - $scope.$apply(function(scope) { - scope.error.current = scope.error.image; - }); - } - if (event.target.error.name == 'Size') { - $scope.$apply(function(scope) { - scope.error.current = scope.error.size; - }); - } - }; - - if (!file.type.match(/image/)) { - error({target: {error: {name: 'NotImage'}}}); - } else if (file.size > maxUploadMb * 1024 * 1024) { - error({target: {error: {name: 'Size'}}}); - } else { - $scope.$apply(function(scope) { - $scope.upload.status = 5; - }); - var reader = new FileReader(); - reader.readAsDataURL(file); - - reader.onprogress = progress; - reader.onload = load; - reader.onerror = error; - } - }; - var getNumFromPx = function(px) { return px.match(/[\-0-9]+/) ? Number(px.match(/[\-0-9]+/)[0]) : 0; }; @@ -178,7 +113,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi return {width: width, height: height, x: x, y: y}; }; - var writeUploadToCanvas = function(canvas, img) { var dim = getScaledDimensions(img, canvas); var context = canvas.getContext("2d"); @@ -194,6 +128,71 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi safeApply($scope); }; + $scope.reset = function() { + $scope.showUploadPicture = false; + $scope.previewUpload = false; + }; + + $scope.handleUpload = function(event) { + var file = event.target.files[0]; + if (!file) { + return; + } + //console.log('file', file); + var progress = function(event) { + //console.log('file progress', event); + var percentComplete = event.loaded/event.total * 100; + // show complete only when src is loaded in image element + if(percentComplete != 100) { + $scope.$apply(function(scope) { + $scope.upload.status = percentComplete; + }); + } + }; + var load = function(event) { + //console.log('file load', event); + $scope.$apply(function(scope) { + scope.imgData = event.target.result; + setUploadImageDimension(scope.imgData); + $scope.previewUpload = true; + }); + }; + var error = function(event) { + //console.log('file error', event); + if (event.target.error.name == 'NotReadableError') { + $scope.$apply(function(scope) { + scope.error.read = true; + }); + } + if (event.target.error.name == 'NotImage') { + $scope.$apply(function(scope) { + scope.error.image = true; + }); + } + if (event.target.error.name == 'Size') { + $scope.$apply(function(scope) { + scope.error.size = true; + }); + } + }; + + if (!file.type.match(/image/)) { + error({target: {error: {name: 'NotImage'}}}); + } else if (file.size > maxUploadBytes) { + error({target: {error: {name: 'Size'}}}); + } else { + $scope.$apply(function(scope) { + $scope.upload.status = 5; + }); + var reader = new FileReader(); + reader.readAsDataURL(file); + + reader.onprogress = progress; + reader.onload = load; + reader.onerror = error; + } + }; + }]; var link = function($scope, $element) { @@ -259,7 +258,6 @@ define(['jquery', 'underscore', 'text!partials/buddypictureupload.html'], functi return { restrict: 'E', - transclude: true, replace: false, template: template, controller: controller, diff --git a/static/partials/buddypictureupload.html b/static/partials/buddypictureupload.html index e289d497..43b78ca3 100644 --- a/static/partials/buddypictureupload.html +++ b/static/partials/buddypictureupload.html @@ -16,9 +16,11 @@
-
{{error.current}}
-

{{text.initial}}

-

{{text.again}}

+
{{_('The file couldn\'t be read.')}}
+
{{_('The file is not an image.')}}
+
{{_('The file is too large. Max upload size is %d Mb', maxUploadMb)}}
+

{{_('Please choose a picture to upload, max %d Mb', maxUploadMb)}}

+

{{_('Upload a different picture')}}


From 3ec4201aeecf42a02a9540f93c0a6180431993d0 Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Wed, 20 Aug 2014 17:34:53 +0200 Subject: [PATCH 14/15] Add styles. --- static/css/main.min.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/css/main.min.css b/static/css/main.min.css index 3146d3a3..1b49527b 100644 --- a/static/css/main.min.css +++ b/static/css/main.min.css @@ -36,4 +36,4 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - *//*! HiDPI v2.0.1 | MIT License | git.io/hidpi */.toast-title{font-weight:bold}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#ffffff}.toast-message a:hover{color:#cccccc;text-decoration:none}.toast-close-button{position:relative;right:-0.3em;top:-0.3em;float:right;font-size:20px;font-weight:bold;color:#ffffff;-webkit-text-shadow:0 1px 0 #ffffff;text-shadow:0 1px 0 #ffffff;opacity:0.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}.toast-close-button:hover,.toast-close-button:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}button.toast-close-button{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;border-radius:3px 3px 3px 3px;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999999;color:#ffffff;opacity:0.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>:hover{-webkit-box-shadow:0 0 12px #000000;box-shadow:0 0 12px #000000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important}#toast-container>.toast-error{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important}#toast-container>.toast-success{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important}#toast-container>.toast-warning{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important}#toast-container.toast-top-full-width>div,#toast-container.toast-bottom-full-width>div{width:96%;margin:auto}.toast{background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-warning{background-color:#f89406}@media all and (max-width: 239px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container .toast-close-button{right:-0.2em;top:-0.2em}}@media all and (min-width: 240px) and (max-width: 479px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container .toast-close-button{right:-0.2em;top:-0.2em}}@media all and (min-width: 480px) and (max-width: 767px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}}.dialog-header-error{background-color:#d2322d}.dialog-header-wait{background-color:#428bca}.dialog-header-notify{background-color:#eee}.dialog-header-confirm{background-color:#eee}.dialog-header-error span,.dialog-header-error h4,.dialog-header-wait span,.dialog-header-wait h4{color:#fff}.modal-content{overflow:hidden}.modal-backdrop.in{opacity:0.2}html,body{-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#e5e5e5;height:100%}body{margin:0;max-height:100%;max-width:100%;overflow:hidden;padding:0}a{cursor:pointer}#background{background:url("../img/bg-tiles.jpg");bottom:0;left:0;position:fixed;right:0;top:0;z-index:0}@media (-webkit-min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx){#background{background-image:url("../img/bg-tiles_x2.jpg");-webkit-background-size:198px 200px;background-size:198px 200px}}.help-block{color:#737373}.dialog-header-notify,.dialog-header-confirm{background-color:#eee}.desktopnotify-icon{background-image:url("../img/logo-48x48.png")}#loader{background:url("../img/logo.svg") no-repeat center;-webkit-background-size:contain;background-size:contain;bottom:15%;left:15%;max-width:200px;max-height:150px;margin:auto;opacity:1;pointer-events:none;position:fixed;right:15%;top:15%;z-index:20000;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.5s;transition-duration:.5s}#loader.done{opacity:0}#loader>div{color:#ddd;display:block;font-size:2em;left:0;margin:0 auto;right:0;position:absolute;bottom:0px;margin-bottom:-40px;text-align:center;text-shadow:0 0 5px black}#loader .loader-message{font-size:0.5em}.mainview{bottom:0;display:none;left:150px;position:absolute;right:0;top:51px}@media (max-width: 700px){.mainview{left:0px}}.withChat .mainview,.withBuddylist .mainview{right:260px}.withBuddylist.withChat .mainview{right:520px}#page{bottom:0;left:0;position:absolute;right:0;top:51px}.welcome{color:#aaa;font-size:1.1em;margin-top:80px;text-shadow:0 0 5px black;max-width:600px;min-height:160px;padding-left:160px;padding-right:0px;position:relative}@media (max-width: 700px){.welcome{padding-left:0px;margin:0 10px}}.welcome h1{text-align:center;white-space:nowrap}@media (max-width: 700px){.welcome h1{white-space:normal}}.welcome .welcome-container{max-width:450px;margin:0 auto}.welcome .welcome-logo{position:absolute;left:0px;top:0px;bottom:0px;width:140px;background:url("../img/logo.svg") no-repeat left;-webkit-background-size:contain;background-size:contain}@media (max-width: 700px){.welcome .welcome-logo{position:relative;margin:0 auto;height:70px;width:70px;margin-top:30px}}.welcome .welcome-input{position:relative}.welcome .welcome-input input{padding-right:105px}.welcome .welcome-input-buttons{text-shadow:none;position:absolute;top:6px;right:8px}.welcome .welcome-input-buttons a{padding-right:.5em;color:black}[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none !important}.nicescroll::-webkit-scrollbar{background-color:#e5e5e5;border:solid transparent;height:8px;width:8px}.nicescroll::-webkit-scrollbar:hover{background-color:#e5e5e5;border-left:1px solid rgba(0,0,0,0.12);border-right:1px solid rgba(0,0,0,0.12)}.nicescroll::-webkit-scrollbar-thumb{background:rgba(0,0,0,0.2)}.nicescroll::-webkit-scrollbar-thumb:active{background:rgba(0,0,0,0.4)}.fadetogglecontainer>div{position:absolute;width:100%}.animate-show.ng-hide-add{opacity:1;display:block !important;-webkit-transition:all linear 0.5s;transition:all linear 0.5s}.animate-show.ng-hide-add.ng-hide-add-active{opacity:0}.animate-show.ng-hide-remove{opacity:0;display:block !important;-webkit-transition:all linear 0.5s;transition:all linear 0.5s}.animate-show.ng-hide-remove.ng-hide-remove-active{opacity:1}.overlaybar{background:rgba(0,0,0,0.2);color:#e7e7e7;min-height:36px;padding:3px 8px 0 30px;position:absolute;text-shadow:0 0 5px black;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.overlaybar:hover{background:rgba(0,0,0,0.5)}.overlaybar .btn{text-shadow:none}.overlaybar .btn-link{text-shadow:0 0 5px black}.overlaybar .form-group>*{float:left;padding-top:0}.overlaybar input[type="radio"],.overlaybar input[type="checkbox"]{margin-top:2px}.overlaybar label{padding-top:6px !important}.overlaybar.notvisible{background:transparent;pointer-events:none}.overlaybar.notvisible:hover{background:transparent}.overlaybar.notvisible .overlaybar-content{display:none}.overlaybar.notvisible .overlaybar-overlay{display:block}.overlaybar .overlaybar-button{color:#e7e7e7;display:block;font-size:20px;top:0px;left:3px;opacity:.7;padding:4px 6px;position:absolute;pointer-events:auto;vertical-align:middle;z-index:15}.overlaybar .overlaybar-content{display:inline-block;margin-left:.5em;margin-bottom:0;max-width:60%}.overlaybar .overlaybar-content>*{padding-right:.5em}.overlaybar .overlaybar-content .input-group{max-width:160px}.overlaybar .overlaybar-overlay{display:none;margin-left:.5em;opacity:.7;padding-top:2px;text-align:left}#rightslide{bottom:0;left:0;pointer-events:none;position:absolute;right:-260px;top:51px;-webkit-transition:right 200ms ease-in-out;transition:right 200ms ease-in-out;z-index:5}.withBuddylist #rightslide{right:0}#rightslide .rightslidepane{height:100%;position:relative;width:100%}.bar{background:#f8f8f8;color:#262626;font:bold 1em/50px "Helvetica Neue",Helvetica,Arial,sans-serif;text-align:center;touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:60}.bar .left{padding:5px 5px 5px 15px}.bar .left .logo{background:url("../img/logo-small.png") no-repeat;-webkit-background-size:100%;background-size:100%;display:inline-block;color:black;height:32px;width:90px;font:normal 11px/11px "Helvetica Neue",Helvetica,Arial,sans-serif;text-align:left;vertical-align:middle}.bar .left .logo span{font-style:italic;left:38px;position:relative;top:26px}.bar .left .logo span a{color:#222}@media (max-width: 700px){.bar .left .logo{background:url("../img/logo.svg") no-repeat center;width:46px;height:46px}.bar .left .logo span{display:none}}@media (max-width: 700px){.bar .left{padding:2px 5px 0px 11px}}.bar .middle{position:absolute;left:0px;right:60px;top:0px;pointer-events:none;text-align:center}.bar .middle>span{display:inline-block;background:#f8f8f8;min-height:50px;pointer-events:auto}.bar .middle .userpicture{border-radius:2px;display:inline-block;width:46px;height:46px;margin:-1px .5em 0 .5em}@media (max-width: 700px){.bar .middle .userpicture{display:none}}@media (max-width: 700px){.bar .middle .status-connected,.bar .middle .status-conference,.bar .middle .status-connecting,.bar .middle .status-closed,.bar .middle .status-reconnecting,.bar .middle .status-error,.bar .middle .status-ringing{max-width:100%;left:0;position:absolute;right:0}}.bar .right{padding-right:4px;margin-top:-1px}.bar .right .badge{background-color:#84b819;border:1px solid white;font-size:.4em;position:absolute;right:0;top:2px}.bar .right .btn{background:#e9e9e9;border-color:#e2e2e2;color:#333;height:42px;font:24px/40px "Helvetica Neue",Helvetica,Arial,sans-serif;margin-left:-2px;padding:0;text-align:center;width:42px;position:relative}.bar .right .btn:focus{border:none;outline:none;-webkit-box-shadow:0;box-shadow:0}.bar .right .btn:hover{background-color:transparent;border-color:#e7e7e7;color:#666}.bar .right .btn.active{background-color:transparent;border-color:#e7e7e7;color:#666}.bar .right .btn.active.amutebtn{background-color:#db4f39;border-color:#db4f39;color:white}.bar .right .btn.active.aenablebtn{background-color:#84b819;border-color:#84b819;color:white}@-webkit-keyframes shakeityeah{0%{-webkit-transform:translate(2px, 1px) rotate(0deg);transform:translate(2px, 1px) rotate(0deg)}2%{-webkit-transform:translate(-1px, -2px) rotate(-1deg);transform:translate(-1px, -2px) rotate(-1deg)}4%{-webkit-transform:translate(-3px, 0px) rotate(1deg);transform:translate(-3px, 0px) rotate(1deg)}8%{-webkit-transform:translate(0px, 2px) rotate(0deg);transform:translate(0px, 2px) rotate(0deg)}10%{-webkit-transform:translate(1px, -1px) rotate(1deg);transform:translate(1px, -1px) rotate(1deg)}12%{-webkit-transform:translate(-1px, 2px) rotate(-1deg);transform:translate(-1px, 2px) rotate(-1deg)}14%{-webkit-transform:translate(-3px, 1px) rotate(0deg);transform:translate(-3px, 1px) rotate(0deg)}16%{-webkit-transform:translate(2px, 1px) rotate(-1deg);transform:translate(2px, 1px) rotate(-1deg)}18%{-webkit-transform:translate(-1px, -1px) rotate(1deg);transform:translate(-1px, -1px) rotate(1deg)}20%{-webkit-transform:translate(2px, 2px) rotate(0deg);transform:translate(2px, 2px) rotate(0deg)}22%{-webkit-transform:translate(1px, -2px) rotate(-1deg);transform:translate(1px, -2px) rotate(-1deg)}24%{-webkit-transform:translate(0px, 0px) rotate(0deg);transform:translate(0px, 0px) rotate(0deg)}}@keyframes shakeityeah{0%{-webkit-transform:translate(2px, 1px) rotate(0deg);transform:translate(2px, 1px) rotate(0deg)}2%{-webkit-transform:translate(-1px, -2px) rotate(-1deg);transform:translate(-1px, -2px) rotate(-1deg)}4%{-webkit-transform:translate(-3px, 0px) rotate(1deg);transform:translate(-3px, 0px) rotate(1deg)}8%{-webkit-transform:translate(0px, 2px) rotate(0deg);transform:translate(0px, 2px) rotate(0deg)}10%{-webkit-transform:translate(1px, -1px) rotate(1deg);transform:translate(1px, -1px) rotate(1deg)}12%{-webkit-transform:translate(-1px, 2px) rotate(-1deg);transform:translate(-1px, 2px) rotate(-1deg)}14%{-webkit-transform:translate(-3px, 1px) rotate(0deg);transform:translate(-3px, 1px) rotate(0deg)}16%{-webkit-transform:translate(2px, 1px) rotate(-1deg);transform:translate(2px, 1px) rotate(-1deg)}18%{-webkit-transform:translate(-1px, -1px) rotate(1deg);transform:translate(-1px, -1px) rotate(1deg)}20%{-webkit-transform:translate(2px, 2px) rotate(0deg);transform:translate(2px, 2px) rotate(0deg)}22%{-webkit-transform:translate(1px, -2px) rotate(-1deg);transform:translate(1px, -2px) rotate(-1deg)}24%{-webkit-transform:translate(0px, 0px) rotate(0deg);transform:translate(0px, 0px) rotate(0deg)}}.btn-shakeityeah{-webkit-animation-name:shakeityeah;animation-name:shakeityeah;-webkit-animation-duration:4.0s;animation-duration:4.0s;-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}#buddylist{bottom:0;position:absolute;right:0;top:0;width:285px;z-index:50}#buddylist:before{background:#f8f8f8;border-left:1px solid #e7e7e7;border-top:1px solid #e7e7e7;border-bottom:1px solid #e7e7e7;border-top-left-radius:6px;border-bottom-left-radius:6px;bottom:0;color:rgba(0,0,0,0.3);content:"\f100";cursor:pointer;display:none;font-family:FontAwesome;font-size:1.8em;height:55px;left:0;line-height:55px;margin:auto;pointer-events:auto;position:absolute;text-align:center;top:0;width:26px;z-index:1;padding-right:4px}.withBuddylist #buddylist:before{content:"\f101";padding-right:0px}.withBuddylistAutoHide #buddylist:before{display:block}.buddylist{background:#f8f8f8;border-left:1px solid #e7e7e7;bottom:0;left:25px;overflow-x:hidden;overflow-y:auto;pointer-events:auto;position:absolute;right:0;top:0}.buddylist.loading .buddylistloading{display:block}.buddylist.empty .buddylistempty{display:block}.buddylist .buddycontainer{pointer-events:auto;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.buddylist .buddylistloading,.buddylist .buddylistempty{bottom:0;color:#b3b3b3;display:none;font-size:1.4em;height:2em;left:0;margin:auto;padding:.4em;position:absolute;right:0;text-align:center;top:0}.buddy{background:#fff;border-bottom:1px solid #e7e7e7;cursor:pointer;display:block;font-size:13px;min-height:66px;overflow:hidden;position:relative;text-align:left;width:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}.buddy:hover{background:rgba(255,255,255,0.5)}.buddy.withSubline .buddy1,.buddy.contact .buddy1{top:15px}.buddy.withSubline .buddy2,.buddy.contact .buddy2{display:block}.buddy.hovered .buddyactions{right:0}.buddy .fa.contact:before{content:"\f006"}.buddy.contact .fa.contact:before{content:"\f005"}.buddy .buddyPicture{background:#84b819;border-radius:2px;float:left;height:46px;margin:10px;overflow:hidden;position:relative;text-align:center;width:46px}.buddy .buddyPicture .fa{color:#009534;line-height:46px;font-size:3em}.buddy .buddyPicture img{bottom:0;display:block;left:0;position:absolute;right:0;top:0;max-height:100%;max-width:100%}.buddy .buddyPictureSmall{margin:0px;margin-left:0px;height:30px;width:30px;margin-right:0px}.buddy .buddyPictureSmall .fa{line-height:30px;font-size:2em}.buddy .buddy1{color:#262626;font-weight:bold;font-size:14px;height:28px;left:65px;position:absolute;overflow:hidden;right:4px;text-overflow:ellipsis;top:24px;white-space:nowrap}.buddy .buddy2{color:rgba(0,0,0,0.5);left:65px;overflow:hidden;position:absolute;right:0px;top:33px;white-space:nowrap;display:none}.buddy .buddy3{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:left;vertical-align:middle;display:inline-block;width:120px;padding:0px 6px}.buddy .buddyactions{background:rgba(255,255,255,0.5);height:66px;line-height:66px;position:absolute;right:-125px;padding:0 10px;text-align:right;top:0px;-webkit-transition-property:right;transition-property:right;-webkit-transition-duration:.3s;transition-duration:.3s;white-space:nowrap;z-index:5}.buddy .buddyactions .btn{width:42px;height:40px;padding:0px;text-align:center;vertical-align:middle;line-height:40px;font-size:1.6em}.buddy .buddysessions{margin-top:56px;max-height:0px;margin-bottom:10px;-webkit-transition-property:max-height;transition-property:max-height;-webkit-transition-duration:.5s;transition-duration:.5s;-webkit-transition-delay:.1s;transition-delay:.1s}.buddy .buddysessions ul{padding-top:10px;margin:0 14px;padding-left:0px;border-left:1px dotted #e7e7e7;border-right:1px dotted #e7e7e7}.buddy .buddysessions ul li{margin-bottom:2px;margin-left:0px;list-style-type:none}.buddy .buddysessions ul li .btn-group{visibility:hidden}.buddy .buddysessions ul li:hover .btn-group{visibility:visible}.buddy .buddysessions .currentsession .buddy3{font-weight:bold}.buddy.hovered .buddysessions{max-height:999px}.buddyPictureCapture .picture{display:block;margin-bottom:5px}.buddyPictureCapture .videoPicture{margin-bottom:4px}.buddyPictureCapture .videoPicture .videoPictureVideo{background-color:black;overflow:hidden;position:relative}.buddyPictureCapture .videoPicture video{object-fit:cover}.buddyPictureCapture .videoPictureVideo{width:200px;height:200px}.buddyPictureCapture .videoPictureVideo .videoPrev,.buddyPictureCapture .videoPictureVideo video,.buddyPictureCapture .videoPictureVideo .preview{width:100%;height:100%}.buddyPictureCapture .videoFlash{position:absolute;left:0px;right:0px;top:0px;bottom:0px;background-color:white;border:1px dotted #e7e7e7;visibility:hidden;z-index:5}.buddyPictureCapture .videoFlash.flash{visibility:visible}.buddyPictureCapture .preview{left:0;position:absolute;top:0}.buddyPictureCapture .preview.previewPicture{position:relative}.buddyPictureCapture .btn-takePicture,.buddyPictureCapture .btn-retakePicture{left:0px;right:0px;position:absolute;top:50%;margin:0 auto;max-width:40%}.buddyPictureCapture .btn-retakePicture{visibility:hidden}.buddyPictureCapture .videoPictureVideo:hover .btn-retakePicture{visibility:visible}.buddyPictureCapture .countdownPicture{color:#f8f8f8;font-size:45px;left:0px;right:0px;position:absolute;top:75px;margin:0 auto;text-align:center;text-shadow:0 0 5px black;opacity:0.8}#settings{border-left:1px solid #e7e7e7;background:#fff;bottom:0;padding-right:20px;position:fixed;right:-520px;top:51px;-webkit-transition:right 200ms ease-in-out;transition:right 200ms ease-in-out;width:520px;z-index:50}#settings.show{right:0}@media only screen and (max-width: 630px){#settings.show{background:#fff;left:0;width:auto}}@media only screen and (max-width: 630px){#settings.show .form-actions{bottom:0;height:60px;left:0;margin-bottom:0;padding:6px 0 6px 120px;position:fixed;right:0}}.settings{background:#fff;bottom:0;left:0;overflow-x:hidden;overflow-y:auto;padding:10px;position:absolute;right:0;top:0}.settings .version{color:#ccc;font-size:10px;position:absolute;right:10px;top:10px}@media only screen and (max-width: 630px){.settings .form-horizontal .controls{margin-left:110px}}@media only screen and (max-width: 630px){.settings .form-horizontal .control-label{width:100px;word-wrap:break-word}}@media only screen and (max-width: 630px){.settings{padding-bottom:10px}}settings-advanced{padding-top:15px;display:block}#chat{pointer-events:none;position:absolute;bottom:0px;right:260px;top:0px;width:260px;min-width:260px;z-index:45;opacity:0;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.3s ease-in-out}.withChat #chat{opacity:1}.withChat.withChatMaximized #chat{left:0;width:auto}.withChat .chat{pointer-events:auto}.chatcontainer{background:#e7e7e7;bottom:0px;left:0px;right:0px;top:0px;overflow:hidden;position:absolute}.showchatlist .chatpane{right:100%}.showchatlist .chatlist{left:0}.chatlist{background:#e7e7e7;bottom:0;left:100%;position:absolute;top:0;width:100%}.chatlist .list-group{margin-top:-1px;margin-bottom:-1px;max-height:100%;overflow-x:hidden;overflow-y:auto}.chatlist .list-group-item{border-right:none;border-left:none;border-radius:0;padding-right:70px;position:relative;min-height:51px;line-height:26px}.chatlist .list-group-item.newmessage{-webkit-animation:newmessage 1s ease -0.3s infinite;animation:newmessage 1s ease -0.3s infinite}.chatlist .list-group-item.disabled{color:#aaa}.chatlist .list-group-item:hover button{display:inline}.chatlist .list-group-item .fa-lg{display:inline-block;text-align:center;width:18px}.chatlist .list-group-item .badge{background:#84b819;border:1px solid white;position:absolute;right:50px;top:14px}.chatlist .list-group-item button{display:none;position:absolute;right:10px}.chatpane{-webkit-backface-visibility:hidden;backface-visibility:hidden;bottom:0;position:absolute;right:0;top:0;width:100%}.chat{background:#e7e7e7;display:none;bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}.chat.active.visible{display:block}.chatmenu{position:absolute;top:36px;left:0px;right:0px;height:36px;padding:2px 4px}@media (max-height: 210px){.chatmenu{display:none}}.chatbody{border-left:1px solid #e7e7e7;bottom:-1px;left:0;position:absolute;right:0;top:74px}@media (max-height: 210px){.chatbody{border-top:1px solid #e7e7e7;top:0px}}.chatheader{background:rgba(255,255,255,0.9);border-bottom:1px solid #e7e7e7;border-left:1px solid #e7e7e7;height:36px;left:0;line-height:34px;padding:0 4px 0 8px;position:absolute;right:0;top:0}.chatheader .chatstatusicon{cursor:pointer;display:block;font-size:1.4em;height:36px;left:0;position:absolute;text-align:center;top:0;width:36px}.chatheader .chatheadertitle{display:inline;padding-left:28px}.chatheader .ctrl{color:rgba(0,0,0,0.3);position:absolute;right:1px;top:0}.chatheader .ctrl .fa{cursor:pointer;padding:6px}.chatheader span{display:inline-block;max-width:60%;overflow:hidden;pointer-events:none;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}@media (max-height: 210px){.chatheader{display:none}}.chat .outputbox{bottom:75px;left:0;position:absolute;right:0;top:0}@media (max-height: 210px){.chat .outputbox{bottom:45px}}.chat .output{height:100%;overflow-x:hidden;overflow-y:auto;padding:0.4em 0}.chat .output>i{clear:both;color:#aaa;display:block;font-size:.8em;padding:6px 0;text-align:center}.chat .output>i.p2p{font-weight:bold;padding:6px 0}.chat.with_pictures .message.is_self{padding-right:54px}.chat.with_pictures .message.is_self .timestamp{right:58px}.chat.with_pictures .message.is_remote{padding-left:58px}.chat .message{background:#fff;border:1px solid #e5e5ef;border-radius:6px;clear:both;display:block;margin:0 4px 2px 20px;padding:8px;position:relative;word-wrap:break-word}.chat .message ul{list-style-type:none;margin:0;padding-left:0}.chat .message li{line-height:1.1em;margin:4px 0;padding-left:1.2em;position:relative}.chat .message li:before{color:#ccc;content:'\f075';font-family:FontAwesome;left:0;position:absolute;text-align:center;width:12px}.chat .message .timestamp{color:#aaa;font-size:.8em;position:absolute;right:8px;text-align:right;top:8px}.chat .message .timestamp-space{width:40px;height:10px;float:right}.chat .message strong{display:block;padding-bottom:2px;margin-right:40px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.chat .message.is_self li:before{color:#ccc;-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.chat .message li.unread:before{content:"\f0eb";color:#fe9a2e}.chat .message li.sending:before{content:"\f0ec";color:#ccc}.chat .message li.sent:before{content:"\f003";color:#5882fa}.chat .message li.delivered:before{content:"\f019";color:#5882fa}.chat .message li.received:before{content:"\f06e";color:#84b819}.chat .message li.read:before{content:"\f00c";color:#ccc}.chat .message.is_self .buddyPicture{left:auto;right:4px}.chat .message .buddyPicture{background:#84b819;border-radius:2px;height:46px;left:4px;overflow:hidden;position:absolute;text-align:center;top:4px;width:46px}.chat .message .buddyPicture .fa{color:#009534;line-height:46px}.chat .message .buddyPicture img{display:block;bottom:0;left:0;right:0;position:absolute;top:0;max-height:100%;max-width:100%}.chat .message:before,.chat .message:after{border-style:solid;content:"";display:block;position:absolute;width:0}.chat .message.is_remote{background:#fff}.chat .message.is_remote:before{border-width:10px 17px 10px 0;border-color:transparent #fff;bottom:auto;left:-16px;top:4px}.chat .message.is_remote:after{border-width:9px 15px 9px 0;border-color:transparent #fff;bottom:auto;left:-15px;top:5px}.chat .message.is_self{background:#fff;margin-right:20px;margin-left:4px;padding-right:0}.chat .message.is_self:before{border-width:10px 0 10px 17px;border-color:transparent #fff;bottom:auto;right:-16px;top:4px}.chat .message.is_self:after{border-width:9px 0 9px 15px;border-color:transparent #fff;bottom:auto;right:-15px;top:5px}.chat .chatbodybottom{background:#e7e7e7;bottom:1px;left:0;margin:0 auto;position:absolute;right:0}@media (max-height: 210px){.chat .chatbodybottom{height:auto}}.chat .typinghint{padding:0 6px 0 6px;white-space:nowrap;overflow:hidden;font-size:.8em;color:#aaa;height:14px}@media (max-height: 210px){.chat .typinghint{display:none}}.chat .inputbox{position:relative}.chat .inputbox .btn{position:absolute;right:6px;top:1px;padding:.5em 1em;display:none}.chat .inputbox>div{border-top:1px solid #e7e7e7}@media (max-height: 210px){.chat .inputbox{height:auto}}.chat .input{border-radius:0;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;display:block;height:54px;max-height:54px;margin:0;resize:none;width:100%}.chat .input:active,.chat .input:focus{border-color:#66afe9}@media (max-height: 210px){.chat .input{max-height:2.5em}}@-webkit-keyframes newmessage{0%{background-color:#84b819}50%{background-color:#f8f8f8}100%{background-color:#84b819}}@keyframes newmessage{0%{background-color:#84b819}50%{background-color:#f8f8f8}100%{background-color:#84b819}}.chat.newmessage .chatheadertitle:after{content:"***";position:absolute;right:32px;top:2px}.chat.newmessage .chatheader{-webkit-animation:newmessage 1s ease -0.3s infinite;animation:newmessage 1s ease -0.3s infinite}#help{bottom:10px;color:#aaa;font-size:1.1em;left:0;margin:0 auto;position:absolute;right:0;text-shadow:0 0 5px black;-webkit-transition:right 200ms ease-in-out;transition:right 200ms ease-in-out;top:80px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:350px}.withChat #help,.withBuddylist #help{right:260px}.withChat.withBuddylist #help,.withSettings #help{right:520px}#help>div{margin:0 10px}#help .help-subline{color:#888;padding:20px 0}@media only screen and (max-width: 400px){#help{display:none}}@media only screen and (min-width: 400px) and (max-width: 1020px){#help{font-size:1em;width:250px}}#help .btn{text-shadow:none}#audiolevel{left:0;margin:0 auto;position:fixed;right:0;top:43px;width:400px;z-index:6}#audiolevel .audio-level{background:#84b819;background:gradient(linear, left top, left bottom, color-stop(0%, #84b819), color-stop(50%, #a1d54f), color-stop(51%, #80c217), color-stop(100%, #7cbc0a));background:-webkit-gradient(linear, left top, left bottom, from(#84b819), color-stop(50%, #a1d54f), color-stop(51%, #80c217), to(#7cbc0a));background:-webkit-linear-gradient(top, #84b819 0%, #a1d54f 50%, #80c217 51%, #7cbc0a 100%);background:linear-gradient(to bottom, #84b819 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%);border-radius:0 0 2px 2px;height:4px;left:0;margin:0 auto;position:absolute;right:0;-webkit-transition:width .05s ease-in-out;transition:width .05s ease-in-out;width:0}.file-info{background:#fff;border:1px solid #ddd;border-radius:4px;padding:1em;position:relative;text-align:center;max-width:170px}.file-info>div{position:relative;z-index:3}.file-info .file-info-bg{bottom:0;left:41px;right:0;overflow:hidden;position:absolute;top:-17px;z-index:2}.file-info .file-info-bg .fa{color:#eee;font-size:20em}.file-info .actions{left:50%;margin-left:10px;position:absolute;text-align:left;top:14px}.is_remote .file-info{background:#fff;border:1px solid #ddd}.is_remote .file-info .file-info-bg .fa{color:#eee;font-size:20em}.file-info-name{font-size:1.1em;margin:.2em 0;min-width:140px;padding:0 .2em}.file-info-size{font-size:.8em;height:20px;position:relative}.file-info-size>span{display:block;left:0;margin:0 auto;padding:3px;position:absolute;text-shadow:1px 1px 1px white;top:0px;right:0;z-index:5}.file-info-size>div{bottom:0;-webkit-box-shadow:none !important;box-shadow:none !important;left:0;position:absolute;top:0;width:0;z-index:0}.file-info-size>div.progress-bar{opacity:.5}.file-info-size>div.progress-bar.download{opacity:1;z-index:1}.file-info-speed{bottom:8px;font-size:.8em;left:0;position:absolute;right:0;text-align:center}.file-info.uploader .file-info-speed{bottom:6px}.file-info.uploader .actions{margin-left:30px;opacity:0}.file-info.uploader .anim{margin-left:0}.file-info.uploader .hovercontrol:hover .anim{margin-left:-50px}.file-info.uploader .hovercontrol:hover .actions{margin-left:0;opacity:1}.file-info.uploader .hovercontrol>div{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.file-info.downloader .anim{margin-left:-40px}.file-info.downloader .file-info-size{margin-bottom:10px}.file-info.downloading .file-info-size{border-color:#ddd}#audiovideo{border-top:1px solid #e7e7e7;bottom:0;left:0;position:absolute;right:0;top:51px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#audiovideo.fullscreen{background:black !important;bottom:0 !important;left:0 !important;top:0 !important;right:0 !important}#audiovideo.fullscreen .remoteVideo .peerActions{display:none}@media only screen and (max-width: 590px){#audiovideo{right:0}}@media only screen and (max-width: 630px){.mainScreenshare #audiovideo,.mainPresentation #audiovideo{display:none}}.withChat #audiovideo,.withBuddylist #audiovideo{right:260px}.withBuddylist.withChat #audiovideo{right:520px}.audiovideo{bottom:0;left:0;position:absolute;top:0;right:0}.audiovideo.active{-webkit-perspective:1000;perspective:1000}.audiovideo.active:hover .overlayActions{opacity:.3}.audiovideo.active .overlayActions:hover{opacity:.6}.audiovideo.active .audiovideoBase{-webkit-transform:rotateY(180deg);-ms-transform:rotateY(180deg);transform:rotateY(180deg)}.audiovideo .audiovideoBase{position:relative;width:100%;height:100%;-webkit-transition-property:-webkit-transform;transition-property:transform;-webkit-transition-duration:2s;transition-duration:2s;-webkit-transform:rotateY(0deg);-ms-transform:rotateY(0deg);transform:rotateY(0deg);z-index:2}.audiovideo .localContainer{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1);z-index:2}.audiovideo video{object-fit:contain}.audiovideo .remoteContainer{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;-webkit-transform:rotateY(180deg);-ms-transform:rotateY(180deg);transform:rotateY(180deg);z-index:2}.audiovideo .miniContainer{bottom:2px;max-height:18%;opacity:0;position:absolute;right:2px;-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1);-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.5s;transition-duration:.5s}.audiovideo .miniContainer.visible{opacity:1}.audiovideo .miniVideo{display:block;max-height:100%;max-width:100%}.audiovideo .localVideo{background:rgba(0,0,0,0.4);display:block;max-height:100%;opacity:0;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:2s;transition-duration:2s;width:100%}.audiovideo .remoteVideos{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:2s;transition-duration:2s}.audiovideo .remoteVideos video{display:block;height:100%;width:100%}.audiovideo .remoteVideo{background:rgba(0,0,0,0.4);display:inline-block;max-height:100%;max-width:100%;overflow:hidden;position:relative;vertical-align:bottom;visibility:hidden;width:100%}.audiovideo .remoteVideo.withvideo{visibility:visible}.audiovideo .remoteVideo.onlyaudio{background:#666;visibility:visible}.audiovideo .remoteVideo .onlyaudio{color:rgba(255,255,255,0.3);display:none;font-size:80px;left:0;margin-top:-40px;pointer-events:auto;position:absolute;right:0;text-align:center;top:45%}.audiovideo .remoteVideo.onlyaudio video{visibility:hidden}.audiovideo .remoteVideo.onlyaudio .onlyaudio{display:block}.audiovideo .remoteVideo .peerActions{bottom:5%;left:40px;opacity:0;pointer-events:auto;position:absolute;right:40px;text-align:center;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.2s;transition-duration:.2s;z-index:10}.audiovideo .remoteVideo .peerActions:hover{opacity:.5}.audiovideo .remoteVideo .peerActions i{font-size:3vw}.audiovideo .remoteVideo .peerLabel{bottom:4%;color:white;left:4%;font-size:2.5vw;max-width:30%;opacity:.7;overflow:hidden;padding:4px;position:absolute;text-overflow:ellipsis;text-shadow:0 0 4px black;white-space:nowrap;z-index:8}.audiovideo .overlayActions{background:rgba(0,0,0,0.9);bottom:0;height:70px;left:0;margin:auto 0;opacity:0;padding:3px 0;position:absolute;top:0;width:40px;z-index:5}.audiovideo .overlayActions button{color:#ccc;cursor:pointer;display:block;outline:0;text-shadow:0 0 5px black;width:40px}.remoteVideo.talking .peerLabel{color:#84b819}.remoteVideo .peerLabel{-webkit-transition:color 500ms ease-out;transition:color 500ms ease-out}.remoteVideo .overlayLogo{background:url(../img/logo-overlay.png) no-repeat center;-webkit-background-size:100%;background-size:100%;height:20%;max-height:40px;max-width:111px;opacity:.5;pointer-events:none;position:absolute;right:4%;top:4%;width:20%;z-index:2}.miniContainer.talking video{border:1px solid #84b819}.miniContainer video{border:1px solid transparent}.renderer-smally{width:150px;background:#f8f8f8;border-right:1px solid #e7e7e7}.renderer-smally .remoteVideos{padding-bottom:85px}.renderer-smally .remoteVideo .peerLabel{font-size:.9em;font-weight:bold}.renderer-smally .remoteVideo .peerActions i{font-size:1em}.renderer-smally .miniContainer{bottom:0;height:85px;left:0;max-height:none;right:0}.renderer-conferencekiosk .remoteVideos{background:rgba(0,0,0,0.4);bottom:2px;min-height:108px;pointer-events:auto;text-align:center;top:auto;white-space:nowrap}.renderer-conferencekiosk .remoteVideos>div{cursor:pointer;height:108px;width:192px}.renderer-conferencekiosk .remoteVideos .overlayLogo{display:none}.renderer-conferencekiosk .remoteVideos .peerLabel,.renderer-conferencekiosk .remoteVideos .peerActions i{font-size:1.1em}.renderer-conferencekiosk .remoteVideos .peerLabel{background:rgba(0,0,0,0.9)}.renderer-conferencekiosk .miniContainer{height:108px;max-height:none;width:192px}.renderer-conferencekiosk .bigVideo{bottom:112px;left:0;margin:auto;opacity:0;position:absolute;right:0;top:2px;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:2s;transition-duration:2s}.renderer-conferencekiosk .bigVideo video{width:100%;height:100%}.screenshare{bottom:0;left:0;position:absolute;right:0;top:0}.mainScreenshare #screenshare{display:block}.screensharepane{background:black;bottom:0;left:0;overflow:auto;position:absolute;right:0;top:0}.screensharepane .remotescreen{position:relative}.screensharepane video{max-height:99%;width:100%}.remotesize .screensharepane video{max-height:none;width:auto}.screenshare .overlaybar{bottom:0;left:0;right:0}#roombar{left:0;min-width:260px;position:absolute;right:0;top:51px;z-index:4}#roombar .roombar{left:0;position:absolute;right:0;top:0}.fa.email{color:#aaa}.fa.facebook{color:#45619d}.fa.google{color:#dd4b39}.fa.twitter{color:#00aced}.fa.xing{color:#fff}.contactsmanager .head{margin-bottom:10px}.contactsmanager .desc{font-size:20px;font-weight:normal;text-align:baseline}.contactsmanager .addbtn{font-size:14px}.contactsmanager .addbtn .fa-users{font-size:22px}.contactsmanager .addbtn .fa-plus{font-size:15px}.contactsmanager .editpicture{vertical-align:middle;float:left;margin-right:20px}.contactsmanager .uploadbtn{margin-top:7px}.contactsmanager .editlist{max-height:250px;overflow-y:auto}.contactsmanager .table{margin-bottom:0px}.contactsmanager .table tr:first-child td{border-top:none}.contactsmanager .table .picture{border-bottom:0;cursor:auto;min-height:46px}.contactsmanager .table .name{width:70%;text-align:left;vertical-align:middle}.contactsmanager .table .action{text-align:center;vertical-align:middle}.search:before{position:absolute;font-family:"fontAwesome";content:"\f002";font-size:14px;opacity:.4;top:6px;left:22px}.search ~ input{padding-left:25px}.presentation{bottom:0;left:0;position:absolute;right:0;top:0}.presentationpane .welcome{padding:0}.presentationpane .welcome h1{white-space:normal}.presentationpane .welcome div{text-align:center}.presentationpane .welcome button{margin-top:30px}.presentationpane .welcome .progress span{text-shadow:none}.presentationpane .welcome .progress .download-info{position:absolute;left:0;width:100%;color:#333;text-shadow:1px 1px 1px white}.mainPresentation #presentation{display:block}.presentationpane{bottom:0;left:0;overflow:auto;position:absolute;right:0;top:0}.presentationpane .canvasContainer{width:100%;height:100%}.presentationpane canvas{position:relative;display:block;margin:0 auto}.presentationpane .odfcanvas{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.presentationpane .odfcanvas body{background-color:transparent}.presentationpane .odfcanvas document{display:block}.presentationpane .odfcontainer{display:none;padding:0;margin:0}.presentationpane .odfcontainer.showonepage{overflow:hidden;text-align:center}.presentation .overlaybar{bottom:0;left:0;right:0;text-align:center}.presentation .overlaybar .overlaybar-content{max-width:100%}.presentation .overlaybar a.overlaybar-button{position:absolute;font-size:20px;padding:4px 6px;top:0px;line-height:28px}.overlaybar-content .pagecontrol{height:30px}.presentation .overlaybar a.btn-prev{left:40px}.presentation .overlaybar a.btn-next{right:0px;left:auto}.pageinfo input{display:inline;width:70px}.presentation .thumbnail{text-shadow:none;color:#333;margin-top:20px;width:160px;height:122px;display:inline-block;margin-left:20px;position:relative;vertical-align:middle}.presentation .thumbnail.presentable{cursor:pointer}.presentation .thumbnail:first-child{margin-left:0}.presentation .thumbnail .caption{padding-bottom:0;text-overflow:ellipsis;overflow:hidden}.presentation .thumbnail .caption .size{font-size:10px}.presentation .thumbnail .caption .progress{position:relative}.presentation .thumbnail .caption .download-info{position:absolute;left:0;right:0;top:0;bottom:0;line-height:20px;text-shadow:1px 1px 1px white;color:#333}.presentation .thumbnail .active{font-size:10em;color:#84b819;opacity:0.7;position:absolute;left:0;right:0;top:0;bottom:0;text-align:center}.presentation .thumbnail .notavailable{display:none;font-size:10em;color:#d2322d;opacity:0.25;position:absolute;left:0;right:0;top:0;bottom:0;text-align:center}.presentation .thumbnail:hover .notavailable{display:block}.presentation .thumbnail .presentation-action{position:absolute;top:1px;display:none}.presentation .thumbnail .download{left:1px}.presentation .thumbnail .delete{right:1px}.presentation .thumbnail:hover .presentation-action{display:block}.presentation .thumbnail .filetype{font-size:5em}.presentations{height:156px;overflow-x:auto;overflow-y:hidden;white-space:nowrap;margin-right:10px;margin-left:-25px}.youtubevideo{position:absolute;left:0;right:0;bottom:0;top:0}.youtubevideopane{bottom:0;left:0;overflow:auto;position:absolute;right:0;top:0}#youtubecontainer{position:relative}#youtubeplayerinfo{position:absolute;left:0;right:0;bottom:10%;opacity:0;pointer-events:auto;text-align:center;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.2s;transition-duration:.2s;z-index:10}#youtubeplayerinfo:hover{opacity:.8}#youtubeplayerinfo div{background-color:#f9f2f4;border-radius:10px;padding:20px 40px;display:inline-block;font-size:2em}.youtubevideo .click-container{position:absolute;left:0;top:0;bottom:0;right:0;z-index:5}.youtubevideo .welcome{max-width:700px}.youtubevideo .welcome h1{margin-top:10px}.youtubevideo .welcome .welcome-container{max-width:700px}.youtubevideo .welcome .welcome-logo{font-size:10em;background:transparent}.mainYoutubevideo #youtubevideo{display:block}.youtubevideo .overlaybar{bottom:0;left:0;right:0}.youtubevideo .overlaybar-content{width:100%;max-width:100%}.youtubevideo .overlaybar-input{position:relative;width:100%;padding-right:15px}.youtubevideo .overlaybar-content form .overlaybar-buttons{position:absolute;right:23px;top:6px}.modal{overflow-y:auto} + *//*! HiDPI v2.0.1 | MIT License | git.io/hidpi */.toast-title{font-weight:bold}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#ffffff}.toast-message a:hover{color:#cccccc;text-decoration:none}.toast-close-button{position:relative;right:-0.3em;top:-0.3em;float:right;font-size:20px;font-weight:bold;color:#ffffff;-webkit-text-shadow:0 1px 0 #ffffff;text-shadow:0 1px 0 #ffffff;opacity:0.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}.toast-close-button:hover,.toast-close-button:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}button.toast-close-button{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;border-radius:3px 3px 3px 3px;background-position:15px center;background-repeat:no-repeat;-webkit-box-shadow:0 0 12px #999999;box-shadow:0 0 12px #999999;color:#ffffff;opacity:0.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>:hover{-webkit-box-shadow:0 0 12px #000000;box-shadow:0 0 12px #000000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important}#toast-container>.toast-error{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important}#toast-container>.toast-success{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important}#toast-container>.toast-warning{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important}#toast-container.toast-top-full-width>div,#toast-container.toast-bottom-full-width>div{width:96%;margin:auto}.toast{background-color:#030303}.toast-success{background-color:#51a351}.toast-error{background-color:#bd362f}.toast-info{background-color:#2f96b4}.toast-warning{background-color:#f89406}@media all and (max-width: 239px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container .toast-close-button{right:-0.2em;top:-0.2em}}@media all and (min-width: 240px) and (max-width: 479px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container .toast-close-button{right:-0.2em;top:-0.2em}}@media all and (min-width: 480px) and (max-width: 767px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}}.dialog-header-error{background-color:#d2322d}.dialog-header-wait{background-color:#428bca}.dialog-header-notify{background-color:#eee}.dialog-header-confirm{background-color:#eee}.dialog-header-error span,.dialog-header-error h4,.dialog-header-wait span,.dialog-header-wait h4{color:#fff}.modal-content{overflow:hidden}.modal-backdrop.in{opacity:0.2}html,body{-webkit-background-clip:padding-box;background-clip:padding-box;background-color:#e5e5e5;height:100%}body{margin:0;max-height:100%;max-width:100%;overflow:hidden;padding:0}a{cursor:pointer}#background{background:url("../img/bg-tiles.jpg");bottom:0;left:0;position:fixed;right:0;top:0;z-index:0}@media (-webkit-min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx){#background{background-image:url("../img/bg-tiles_x2.jpg");-webkit-background-size:198px 200px;background-size:198px 200px}}.help-block{color:#737373}.dialog-header-notify,.dialog-header-confirm{background-color:#eee}.desktopnotify-icon{background-image:url("../img/logo-48x48.png")}#loader{background:url("../img/logo.svg") no-repeat center;-webkit-background-size:contain;background-size:contain;bottom:15%;left:15%;max-width:200px;max-height:150px;margin:auto;opacity:1;pointer-events:none;position:fixed;right:15%;top:15%;z-index:20000;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.5s;transition-duration:.5s}#loader.done{opacity:0}#loader>div{color:#ddd;display:block;font-size:2em;left:0;margin:0 auto;right:0;position:absolute;bottom:0px;margin-bottom:-40px;text-align:center;text-shadow:0 0 5px black}#loader .loader-message{font-size:0.5em}.mainview{bottom:0;display:none;left:150px;position:absolute;right:0;top:51px}@media (max-width: 700px){.mainview{left:0px}}.withChat .mainview,.withBuddylist .mainview{right:260px}.withBuddylist.withChat .mainview{right:520px}#page{bottom:0;left:0;position:absolute;right:0;top:51px}.welcome{color:#aaa;font-size:1.1em;margin-top:80px;text-shadow:0 0 5px black;max-width:600px;min-height:160px;padding-left:160px;padding-right:0px;position:relative}@media (max-width: 700px){.welcome{padding-left:0px;margin:0 10px}}.welcome h1{text-align:center;white-space:nowrap}@media (max-width: 700px){.welcome h1{white-space:normal}}.welcome .welcome-container{max-width:450px;margin:0 auto}.welcome .welcome-logo{position:absolute;left:0px;top:0px;bottom:0px;width:140px;background:url("../img/logo.svg") no-repeat left;-webkit-background-size:contain;background-size:contain}@media (max-width: 700px){.welcome .welcome-logo{position:relative;margin:0 auto;height:70px;width:70px;margin-top:30px}}.welcome .welcome-input{position:relative}.welcome .welcome-input input{padding-right:105px}.welcome .welcome-input-buttons{text-shadow:none;position:absolute;top:6px;right:8px}.welcome .welcome-input-buttons a{padding-right:.5em;color:black}[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none !important}.nicescroll::-webkit-scrollbar{background-color:#e5e5e5;border:solid transparent;height:8px;width:8px}.nicescroll::-webkit-scrollbar:hover{background-color:#e5e5e5;border-left:1px solid rgba(0,0,0,0.12);border-right:1px solid rgba(0,0,0,0.12)}.nicescroll::-webkit-scrollbar-thumb{background:rgba(0,0,0,0.2)}.nicescroll::-webkit-scrollbar-thumb:active{background:rgba(0,0,0,0.4)}.fadetogglecontainer>div{position:absolute;width:100%}.animate-show.ng-hide-add{opacity:1;display:block !important;-webkit-transition:all linear 0.5s;transition:all linear 0.5s}.animate-show.ng-hide-add.ng-hide-add-active{opacity:0}.animate-show.ng-hide-remove{opacity:0;display:block !important;-webkit-transition:all linear 0.5s;transition:all linear 0.5s}.animate-show.ng-hide-remove.ng-hide-remove-active{opacity:1}.overlaybar{background:rgba(0,0,0,0.2);color:#e7e7e7;min-height:36px;padding:3px 8px 0 30px;position:absolute;text-shadow:0 0 5px black;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle}.overlaybar:hover{background:rgba(0,0,0,0.5)}.overlaybar .btn{text-shadow:none}.overlaybar .btn-link{text-shadow:0 0 5px black}.overlaybar .form-group>*{float:left;padding-top:0}.overlaybar input[type="radio"],.overlaybar input[type="checkbox"]{margin-top:2px}.overlaybar label{padding-top:6px !important}.overlaybar.notvisible{background:transparent;pointer-events:none}.overlaybar.notvisible:hover{background:transparent}.overlaybar.notvisible .overlaybar-content{display:none}.overlaybar.notvisible .overlaybar-overlay{display:block}.overlaybar .overlaybar-button{color:#e7e7e7;display:block;font-size:20px;top:0px;left:3px;opacity:.7;padding:4px 6px;position:absolute;pointer-events:auto;vertical-align:middle;z-index:15}.overlaybar .overlaybar-content{display:inline-block;margin-left:.5em;margin-bottom:0;max-width:60%}.overlaybar .overlaybar-content>*{padding-right:.5em}.overlaybar .overlaybar-content .input-group{max-width:160px}.overlaybar .overlaybar-overlay{display:none;margin-left:.5em;opacity:.7;padding-top:2px;text-align:left}#rightslide{bottom:0;left:0;pointer-events:none;position:absolute;right:-260px;top:51px;-webkit-transition:right 200ms ease-in-out;transition:right 200ms ease-in-out;z-index:5}.withBuddylist #rightslide{right:0}#rightslide .rightslidepane{height:100%;position:relative;width:100%}.bar{background:#f8f8f8;color:#262626;font:bold 1em/50px "Helvetica Neue",Helvetica,Arial,sans-serif;text-align:center;touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:60}.bar .left{padding:5px 5px 5px 15px}.bar .left .logo{background:url("../img/logo-small.png") no-repeat;-webkit-background-size:100%;background-size:100%;display:inline-block;color:black;height:32px;width:90px;font:normal 11px/11px "Helvetica Neue",Helvetica,Arial,sans-serif;text-align:left;vertical-align:middle}.bar .left .logo span{font-style:italic;left:38px;position:relative;top:26px}.bar .left .logo span a{color:#222}@media (max-width: 700px){.bar .left .logo{background:url("../img/logo.svg") no-repeat center;width:46px;height:46px}.bar .left .logo span{display:none}}@media (max-width: 700px){.bar .left{padding:2px 5px 0px 11px}}.bar .middle{position:absolute;left:0px;right:60px;top:0px;pointer-events:none;text-align:center}.bar .middle>span{display:inline-block;background:#f8f8f8;min-height:50px;pointer-events:auto}.bar .middle .userpicture{border-radius:2px;display:inline-block;width:46px;height:46px;margin:-1px .5em 0 .5em}@media (max-width: 700px){.bar .middle .userpicture{display:none}}@media (max-width: 700px){.bar .middle .status-connected,.bar .middle .status-conference,.bar .middle .status-connecting,.bar .middle .status-closed,.bar .middle .status-reconnecting,.bar .middle .status-error,.bar .middle .status-ringing{max-width:100%;left:0;position:absolute;right:0}}.bar .right{padding-right:4px;margin-top:-1px}.bar .right .badge{background-color:#84b819;border:1px solid white;font-size:.4em;position:absolute;right:0;top:2px}.bar .right .btn{background:#e9e9e9;border-color:#e2e2e2;color:#333;height:42px;font:24px/40px "Helvetica Neue",Helvetica,Arial,sans-serif;margin-left:-2px;padding:0;text-align:center;width:42px;position:relative}.bar .right .btn:focus{border:none;outline:none;-webkit-box-shadow:0;box-shadow:0}.bar .right .btn:hover{background-color:transparent;border-color:#e7e7e7;color:#666}.bar .right .btn.active{background-color:transparent;border-color:#e7e7e7;color:#666}.bar .right .btn.active.amutebtn{background-color:#db4f39;border-color:#db4f39;color:white}.bar .right .btn.active.aenablebtn{background-color:#84b819;border-color:#84b819;color:white}@-webkit-keyframes shakeityeah{0%{-webkit-transform:translate(2px, 1px) rotate(0deg);transform:translate(2px, 1px) rotate(0deg)}2%{-webkit-transform:translate(-1px, -2px) rotate(-1deg);transform:translate(-1px, -2px) rotate(-1deg)}4%{-webkit-transform:translate(-3px, 0px) rotate(1deg);transform:translate(-3px, 0px) rotate(1deg)}8%{-webkit-transform:translate(0px, 2px) rotate(0deg);transform:translate(0px, 2px) rotate(0deg)}10%{-webkit-transform:translate(1px, -1px) rotate(1deg);transform:translate(1px, -1px) rotate(1deg)}12%{-webkit-transform:translate(-1px, 2px) rotate(-1deg);transform:translate(-1px, 2px) rotate(-1deg)}14%{-webkit-transform:translate(-3px, 1px) rotate(0deg);transform:translate(-3px, 1px) rotate(0deg)}16%{-webkit-transform:translate(2px, 1px) rotate(-1deg);transform:translate(2px, 1px) rotate(-1deg)}18%{-webkit-transform:translate(-1px, -1px) rotate(1deg);transform:translate(-1px, -1px) rotate(1deg)}20%{-webkit-transform:translate(2px, 2px) rotate(0deg);transform:translate(2px, 2px) rotate(0deg)}22%{-webkit-transform:translate(1px, -2px) rotate(-1deg);transform:translate(1px, -2px) rotate(-1deg)}24%{-webkit-transform:translate(0px, 0px) rotate(0deg);transform:translate(0px, 0px) rotate(0deg)}}@keyframes shakeityeah{0%{-webkit-transform:translate(2px, 1px) rotate(0deg);transform:translate(2px, 1px) rotate(0deg)}2%{-webkit-transform:translate(-1px, -2px) rotate(-1deg);transform:translate(-1px, -2px) rotate(-1deg)}4%{-webkit-transform:translate(-3px, 0px) rotate(1deg);transform:translate(-3px, 0px) rotate(1deg)}8%{-webkit-transform:translate(0px, 2px) rotate(0deg);transform:translate(0px, 2px) rotate(0deg)}10%{-webkit-transform:translate(1px, -1px) rotate(1deg);transform:translate(1px, -1px) rotate(1deg)}12%{-webkit-transform:translate(-1px, 2px) rotate(-1deg);transform:translate(-1px, 2px) rotate(-1deg)}14%{-webkit-transform:translate(-3px, 1px) rotate(0deg);transform:translate(-3px, 1px) rotate(0deg)}16%{-webkit-transform:translate(2px, 1px) rotate(-1deg);transform:translate(2px, 1px) rotate(-1deg)}18%{-webkit-transform:translate(-1px, -1px) rotate(1deg);transform:translate(-1px, -1px) rotate(1deg)}20%{-webkit-transform:translate(2px, 2px) rotate(0deg);transform:translate(2px, 2px) rotate(0deg)}22%{-webkit-transform:translate(1px, -2px) rotate(-1deg);transform:translate(1px, -2px) rotate(-1deg)}24%{-webkit-transform:translate(0px, 0px) rotate(0deg);transform:translate(0px, 0px) rotate(0deg)}}.btn-shakeityeah{-webkit-animation-name:shakeityeah;animation-name:shakeityeah;-webkit-animation-duration:4.0s;animation-duration:4.0s;-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;animation-timing-function:linear}#buddylist{bottom:0;position:absolute;right:0;top:0;width:285px;z-index:50}#buddylist:before{background:#f8f8f8;border-left:1px solid #e7e7e7;border-top:1px solid #e7e7e7;border-bottom:1px solid #e7e7e7;border-top-left-radius:6px;border-bottom-left-radius:6px;bottom:0;color:rgba(0,0,0,0.3);content:"\f100";cursor:pointer;display:none;font-family:FontAwesome;font-size:1.8em;height:55px;left:0;line-height:55px;margin:auto;pointer-events:auto;position:absolute;text-align:center;top:0;width:26px;z-index:1;padding-right:4px}.withBuddylist #buddylist:before{content:"\f101";padding-right:0px}.withBuddylistAutoHide #buddylist:before{display:block}.buddylist{background:#f8f8f8;border-left:1px solid #e7e7e7;bottom:0;left:25px;overflow-x:hidden;overflow-y:auto;pointer-events:auto;position:absolute;right:0;top:0}.buddylist.loading .buddylistloading{display:block}.buddylist.empty .buddylistempty{display:block}.buddylist .buddycontainer{pointer-events:auto;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.buddylist .buddylistloading,.buddylist .buddylistempty{bottom:0;color:#b3b3b3;display:none;font-size:1.4em;height:2em;left:0;margin:auto;padding:.4em;position:absolute;right:0;text-align:center;top:0}.buddy{background:#fff;border-bottom:1px solid #e7e7e7;cursor:pointer;display:block;font-size:13px;min-height:66px;overflow:hidden;position:relative;text-align:left;width:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}.buddy:hover{background:rgba(255,255,255,0.5)}.buddy.withSubline .buddy1,.buddy.contact .buddy1{top:15px}.buddy.withSubline .buddy2,.buddy.contact .buddy2{display:block}.buddy.hovered .buddyactions{right:0}.buddy .fa.contact:before{content:"\f006"}.buddy.contact .fa.contact:before{content:"\f005"}.buddy .buddyPicture{background:#84b819;border-radius:2px;float:left;height:46px;margin:10px;overflow:hidden;position:relative;text-align:center;width:46px}.buddy .buddyPicture .fa{color:#009534;line-height:46px;font-size:3em}.buddy .buddyPicture img{bottom:0;display:block;left:0;position:absolute;right:0;top:0;max-height:100%;max-width:100%}.buddy .buddyPictureSmall{margin:0px;margin-left:0px;height:30px;width:30px;margin-right:0px}.buddy .buddyPictureSmall .fa{line-height:30px;font-size:2em}.buddy .buddy1{color:#262626;font-weight:bold;font-size:14px;height:28px;left:65px;position:absolute;overflow:hidden;right:4px;text-overflow:ellipsis;top:24px;white-space:nowrap}.buddy .buddy2{color:rgba(0,0,0,0.5);left:65px;overflow:hidden;position:absolute;right:0px;top:33px;white-space:nowrap;display:none}.buddy .buddy3{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:left;vertical-align:middle;display:inline-block;width:120px;padding:0px 6px}.buddy .buddyactions{background:rgba(255,255,255,0.5);height:66px;line-height:66px;position:absolute;right:-125px;padding:0 10px;text-align:right;top:0px;-webkit-transition-property:right;transition-property:right;-webkit-transition-duration:.3s;transition-duration:.3s;white-space:nowrap;z-index:5}.buddy .buddyactions .btn{width:42px;height:40px;padding:0px;text-align:center;vertical-align:middle;line-height:40px;font-size:1.6em}.buddy .buddysessions{margin-top:56px;max-height:0px;margin-bottom:10px;-webkit-transition-property:max-height;transition-property:max-height;-webkit-transition-duration:.5s;transition-duration:.5s;-webkit-transition-delay:.1s;transition-delay:.1s}.buddy .buddysessions ul{padding-top:10px;margin:0 14px;padding-left:0px;border-left:1px dotted #e7e7e7;border-right:1px dotted #e7e7e7}.buddy .buddysessions ul li{margin-bottom:2px;margin-left:0px;list-style-type:none}.buddy .buddysessions ul li .btn-group{visibility:hidden}.buddy .buddysessions ul li:hover .btn-group{visibility:visible}.buddy .buddysessions .currentsession .buddy3{font-weight:bold}.buddy.hovered .buddysessions{max-height:999px}.buddyPictureCapture .picture{display:block;margin-bottom:5px}.buddyPictureCapture .videoPicture{margin-bottom:4px}.buddyPictureCapture .videoPicture .videoPictureVideo{background-color:black;overflow:hidden;position:relative}.buddyPictureCapture .videoPicture video{object-fit:cover}.buddyPictureCapture .videoPictureVideo{width:200px;height:200px}.buddyPictureCapture .videoPictureVideo .videoPrev,.buddyPictureCapture .videoPictureVideo video,.buddyPictureCapture .videoPictureVideo .preview{width:100%;height:100%}.buddyPictureCapture .videoFlash{position:absolute;left:0px;right:0px;top:0px;bottom:0px;background-color:white;border:1px dotted #e7e7e7;visibility:hidden;z-index:5}.buddyPictureCapture .videoFlash.flash{visibility:visible}.buddyPictureCapture .preview{left:0;position:absolute;top:0}.buddyPictureCapture .preview.previewPicture{position:relative}.buddyPictureCapture .btn-takePicture,.buddyPictureCapture .btn-retakePicture{left:0px;right:0px;position:absolute;top:50%;margin:0 auto;max-width:40%}.buddyPictureCapture .btn-retakePicture{visibility:hidden}.buddyPictureCapture .videoPictureVideo:hover .btn-retakePicture{visibility:visible}.buddyPictureCapture .countdownPicture{color:#f8f8f8;font-size:45px;left:0px;right:0px;position:absolute;top:75px;margin:0 auto;text-align:center;text-shadow:0 0 5px black;opacity:0.8}.buddyPictureUpload{position:relative}.buddyPictureUpload .showUploadPicture{border:1px solid #EEEEEE;height:200px;line-height:200px;margin-bottom:10px;overflow:hidden;text-align:center;width:200px;background-color:black}.buddyPictureUpload .preview{position:relative;top:0px;left:0px}.buddyPictureUpload .imageUtilites{line-height:30px;position:absolute;visibility:hidden;width:200px;z-index:1}.buddyPictureUpload .imageUtilites .fa{cursor:pointer;color:#f8f8f8;text-shadow:0 0 5px black;opacity:0.8;font-size:40px;width:50px;height:50px}.buddyPictureUpload .showUploadPicture:hover .imageUtilites{visibility:visible}.buddyPictureUpload .moveHorizontal{top:-4px;position:relative}.buddyPictureUpload .moveVertical{position:absolute;left:158px}.buddyPictureUpload .resize{position:relative;top:108px}#settings{border-left:1px solid #e7e7e7;background:#fff;bottom:0;padding-right:20px;position:fixed;right:-520px;top:51px;-webkit-transition:right 200ms ease-in-out;transition:right 200ms ease-in-out;width:520px;z-index:50}#settings.show{right:0}@media only screen and (max-width: 630px){#settings.show{background:#fff;left:0;width:auto}}@media only screen and (max-width: 630px){#settings.show .form-actions{bottom:0;height:60px;left:0;margin-bottom:0;padding:6px 0 6px 120px;position:fixed;right:0}}.settings{background:#fff;bottom:0;left:0;overflow-x:hidden;overflow-y:auto;padding:10px;position:absolute;right:0;top:0}.settings .version{color:#ccc;font-size:10px;position:absolute;right:10px;top:10px}@media only screen and (max-width: 630px){.settings .form-horizontal .controls{margin-left:110px}}@media only screen and (max-width: 630px){.settings .form-horizontal .control-label{width:100px;word-wrap:break-word}}@media only screen and (max-width: 630px){.settings{padding-bottom:10px}}settings-advanced{padding-top:15px;display:block}#chat{pointer-events:none;position:absolute;bottom:0px;right:260px;top:0px;width:260px;min-width:260px;z-index:45;opacity:0;-webkit-transition:opacity 0.3s ease-in-out;transition:opacity 0.3s ease-in-out}.withChat #chat{opacity:1}.withChat.withChatMaximized #chat{left:0;width:auto}.withChat .chat{pointer-events:auto}.chatcontainer{background:#e7e7e7;bottom:0px;left:0px;right:0px;top:0px;overflow:hidden;position:absolute}.showchatlist .chatpane{right:100%}.showchatlist .chatlist{left:0}.chatlist{background:#e7e7e7;bottom:0;left:100%;position:absolute;top:0;width:100%}.chatlist .list-group{margin-top:-1px;margin-bottom:-1px;max-height:100%;overflow-x:hidden;overflow-y:auto}.chatlist .list-group-item{border-right:none;border-left:none;border-radius:0;padding-right:70px;position:relative;min-height:51px;line-height:26px}.chatlist .list-group-item.newmessage{-webkit-animation:newmessage 1s ease -0.3s infinite;animation:newmessage 1s ease -0.3s infinite}.chatlist .list-group-item.disabled{color:#aaa}.chatlist .list-group-item:hover button{display:inline}.chatlist .list-group-item .fa-lg{display:inline-block;text-align:center;width:18px}.chatlist .list-group-item .badge{background:#84b819;border:1px solid white;position:absolute;right:50px;top:14px}.chatlist .list-group-item button{display:none;position:absolute;right:10px}.chatpane{-webkit-backface-visibility:hidden;backface-visibility:hidden;bottom:0;position:absolute;right:0;top:0;width:100%}.chat{background:#e7e7e7;display:none;bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}.chat.active.visible{display:block}.chatmenu{position:absolute;top:36px;left:0px;right:0px;height:36px;padding:2px 4px}@media (max-height: 210px){.chatmenu{display:none}}.chatbody{border-left:1px solid #e7e7e7;bottom:-1px;left:0;position:absolute;right:0;top:74px}@media (max-height: 210px){.chatbody{border-top:1px solid #e7e7e7;top:0px}}.chatheader{background:rgba(255,255,255,0.9);border-bottom:1px solid #e7e7e7;border-left:1px solid #e7e7e7;height:36px;left:0;line-height:34px;padding:0 4px 0 8px;position:absolute;right:0;top:0}.chatheader .chatstatusicon{cursor:pointer;display:block;font-size:1.4em;height:36px;left:0;position:absolute;text-align:center;top:0;width:36px}.chatheader .chatheadertitle{display:inline;padding-left:28px}.chatheader .ctrl{color:rgba(0,0,0,0.3);position:absolute;right:1px;top:0}.chatheader .ctrl .fa{cursor:pointer;padding:6px}.chatheader span{display:inline-block;max-width:60%;overflow:hidden;pointer-events:none;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}@media (max-height: 210px){.chatheader{display:none}}.chat .outputbox{bottom:75px;left:0;position:absolute;right:0;top:0}@media (max-height: 210px){.chat .outputbox{bottom:45px}}.chat .output{height:100%;overflow-x:hidden;overflow-y:auto;padding:0.4em 0}.chat .output>i{clear:both;color:#aaa;display:block;font-size:.8em;padding:6px 0;text-align:center}.chat .output>i.p2p{font-weight:bold;padding:6px 0}.chat.with_pictures .message.is_self{padding-right:54px}.chat.with_pictures .message.is_self .timestamp{right:58px}.chat.with_pictures .message.is_remote{padding-left:58px}.chat .message{background:#fff;border:1px solid #e5e5ef;border-radius:6px;clear:both;display:block;margin:0 4px 2px 20px;padding:8px;position:relative;word-wrap:break-word}.chat .message ul{list-style-type:none;margin:0;padding-left:0}.chat .message li{line-height:1.1em;margin:4px 0;padding-left:1.2em;position:relative}.chat .message li:before{color:#ccc;content:'\f075';font-family:FontAwesome;left:0;position:absolute;text-align:center;width:12px}.chat .message .timestamp{color:#aaa;font-size:.8em;position:absolute;right:8px;text-align:right;top:8px}.chat .message .timestamp-space{width:40px;height:10px;float:right}.chat .message strong{display:block;padding-bottom:2px;margin-right:40px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.chat .message.is_self li:before{color:#ccc;-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.chat .message li.unread:before{content:"\f0eb";color:#fe9a2e}.chat .message li.sending:before{content:"\f0ec";color:#ccc}.chat .message li.sent:before{content:"\f003";color:#5882fa}.chat .message li.delivered:before{content:"\f019";color:#5882fa}.chat .message li.received:before{content:"\f06e";color:#84b819}.chat .message li.read:before{content:"\f00c";color:#ccc}.chat .message.is_self .buddyPicture{left:auto;right:4px}.chat .message .buddyPicture{background:#84b819;border-radius:2px;height:46px;left:4px;overflow:hidden;position:absolute;text-align:center;top:4px;width:46px}.chat .message .buddyPicture .fa{color:#009534;line-height:46px}.chat .message .buddyPicture img{display:block;bottom:0;left:0;right:0;position:absolute;top:0;max-height:100%;max-width:100%}.chat .message:before,.chat .message:after{border-style:solid;content:"";display:block;position:absolute;width:0}.chat .message.is_remote{background:#fff}.chat .message.is_remote:before{border-width:10px 17px 10px 0;border-color:transparent #fff;bottom:auto;left:-16px;top:4px}.chat .message.is_remote:after{border-width:9px 15px 9px 0;border-color:transparent #fff;bottom:auto;left:-15px;top:5px}.chat .message.is_self{background:#fff;margin-right:20px;margin-left:4px;padding-right:0}.chat .message.is_self:before{border-width:10px 0 10px 17px;border-color:transparent #fff;bottom:auto;right:-16px;top:4px}.chat .message.is_self:after{border-width:9px 0 9px 15px;border-color:transparent #fff;bottom:auto;right:-15px;top:5px}.chat .chatbodybottom{background:#e7e7e7;bottom:1px;left:0;margin:0 auto;position:absolute;right:0}@media (max-height: 210px){.chat .chatbodybottom{height:auto}}.chat .typinghint{padding:0 6px 0 6px;white-space:nowrap;overflow:hidden;font-size:.8em;color:#aaa;height:14px}@media (max-height: 210px){.chat .typinghint{display:none}}.chat .inputbox{position:relative}.chat .inputbox .btn{position:absolute;right:6px;top:1px;padding:.5em 1em;display:none}.chat .inputbox>div{border-top:1px solid #e7e7e7}@media (max-height: 210px){.chat .inputbox{height:auto}}.chat .input{border-radius:0;border-color:transparent;-webkit-box-shadow:none;box-shadow:none;display:block;height:54px;max-height:54px;margin:0;resize:none;width:100%}.chat .input:active,.chat .input:focus{border-color:#66afe9}@media (max-height: 210px){.chat .input{max-height:2.5em}}@-webkit-keyframes newmessage{0%{background-color:#84b819}50%{background-color:#f8f8f8}100%{background-color:#84b819}}@keyframes newmessage{0%{background-color:#84b819}50%{background-color:#f8f8f8}100%{background-color:#84b819}}.chat.newmessage .chatheadertitle:after{content:"***";position:absolute;right:32px;top:2px}.chat.newmessage .chatheader{-webkit-animation:newmessage 1s ease -0.3s infinite;animation:newmessage 1s ease -0.3s infinite}#help{bottom:10px;color:#aaa;font-size:1.1em;left:0;margin:0 auto;position:absolute;right:0;text-shadow:0 0 5px black;-webkit-transition:right 200ms ease-in-out;transition:right 200ms ease-in-out;top:80px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:350px}.withChat #help,.withBuddylist #help{right:260px}.withChat.withBuddylist #help,.withSettings #help{right:520px}#help>div{margin:0 10px}#help .help-subline{color:#888;padding:20px 0}@media only screen and (max-width: 400px){#help{display:none}}@media only screen and (min-width: 400px) and (max-width: 1020px){#help{font-size:1em;width:250px}}#help .btn{text-shadow:none}#audiolevel{left:0;margin:0 auto;position:fixed;right:0;top:43px;width:400px;z-index:6}#audiolevel .audio-level{background:#84b819;background:gradient(linear, left top, left bottom, color-stop(0%, #84b819), color-stop(50%, #a1d54f), color-stop(51%, #80c217), color-stop(100%, #7cbc0a));background:-webkit-gradient(linear, left top, left bottom, from(#84b819), color-stop(50%, #a1d54f), color-stop(51%, #80c217), to(#7cbc0a));background:-webkit-linear-gradient(top, #84b819 0%, #a1d54f 50%, #80c217 51%, #7cbc0a 100%);background:linear-gradient(to bottom, #84b819 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%);border-radius:0 0 2px 2px;height:4px;left:0;margin:0 auto;position:absolute;right:0;-webkit-transition:width .05s ease-in-out;transition:width .05s ease-in-out;width:0}.file-info{background:#fff;border:1px solid #ddd;border-radius:4px;padding:1em;position:relative;text-align:center;max-width:170px}.file-info>div{position:relative;z-index:3}.file-info .file-info-bg{bottom:0;left:41px;right:0;overflow:hidden;position:absolute;top:-17px;z-index:2}.file-info .file-info-bg .fa{color:#eee;font-size:20em}.file-info .actions{left:50%;margin-left:10px;position:absolute;text-align:left;top:14px}.is_remote .file-info{background:#fff;border:1px solid #ddd}.is_remote .file-info .file-info-bg .fa{color:#eee;font-size:20em}.file-info-name{font-size:1.1em;margin:.2em 0;min-width:140px;padding:0 .2em}.file-info-size{font-size:.8em;height:20px;position:relative}.file-info-size>span{display:block;left:0;margin:0 auto;padding:3px;position:absolute;text-shadow:1px 1px 1px white;top:0px;right:0;z-index:5}.file-info-size>div{bottom:0;-webkit-box-shadow:none !important;box-shadow:none !important;left:0;position:absolute;top:0;width:0;z-index:0}.file-info-size>div.progress-bar{opacity:.5}.file-info-size>div.progress-bar.download{opacity:1;z-index:1}.file-info-speed{bottom:8px;font-size:.8em;left:0;position:absolute;right:0;text-align:center}.file-info.uploader .file-info-speed{bottom:6px}.file-info.uploader .actions{margin-left:30px;opacity:0}.file-info.uploader .anim{margin-left:0}.file-info.uploader .hovercontrol:hover .anim{margin-left:-50px}.file-info.uploader .hovercontrol:hover .actions{margin-left:0;opacity:1}.file-info.uploader .hovercontrol>div{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.file-info.downloader .anim{margin-left:-40px}.file-info.downloader .file-info-size{margin-bottom:10px}.file-info.downloading .file-info-size{border-color:#ddd}#audiovideo{border-top:1px solid #e7e7e7;bottom:0;left:0;position:absolute;right:0;top:51px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#audiovideo.fullscreen{background:black !important;bottom:0 !important;left:0 !important;top:0 !important;right:0 !important}#audiovideo.fullscreen .remoteVideo .peerActions{display:none}@media only screen and (max-width: 590px){#audiovideo{right:0}}@media only screen and (max-width: 630px){.mainScreenshare #audiovideo,.mainPresentation #audiovideo{display:none}}.withChat #audiovideo,.withBuddylist #audiovideo{right:260px}.withBuddylist.withChat #audiovideo{right:520px}.audiovideo{bottom:0;left:0;position:absolute;top:0;right:0}.audiovideo.active{-webkit-perspective:1000;perspective:1000}.audiovideo.active:hover .overlayActions{opacity:.3}.audiovideo.active .overlayActions:hover{opacity:.6}.audiovideo.active .audiovideoBase{-webkit-transform:rotateY(180deg);-ms-transform:rotateY(180deg);transform:rotateY(180deg)}.audiovideo .audiovideoBase{position:relative;width:100%;height:100%;-webkit-transition-property:-webkit-transform;transition-property:transform;-webkit-transition-duration:2s;transition-duration:2s;-webkit-transform:rotateY(0deg);-ms-transform:rotateY(0deg);transform:rotateY(0deg);z-index:2}.audiovideo .localContainer{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1);z-index:2}.audiovideo video{object-fit:contain}.audiovideo .remoteContainer{bottom:0;left:0;pointer-events:none;position:absolute;right:0;top:0;-webkit-transform:rotateY(180deg);-ms-transform:rotateY(180deg);transform:rotateY(180deg);z-index:2}.audiovideo .miniContainer{bottom:2px;max-height:18%;opacity:0;position:absolute;right:2px;-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1);-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.5s;transition-duration:.5s}.audiovideo .miniContainer.visible{opacity:1}.audiovideo .miniVideo{display:block;max-height:100%;max-width:100%}.audiovideo .localVideo{background:rgba(0,0,0,0.4);display:block;max-height:100%;opacity:0;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:2s;transition-duration:2s;width:100%}.audiovideo .remoteVideos{bottom:0;left:0;opacity:0;position:absolute;right:0;top:0;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:2s;transition-duration:2s}.audiovideo .remoteVideos video{display:block;height:100%;width:100%}.audiovideo .remoteVideo{background:rgba(0,0,0,0.4);display:inline-block;max-height:100%;max-width:100%;overflow:hidden;position:relative;vertical-align:bottom;visibility:hidden;width:100%}.audiovideo .remoteVideo.withvideo{visibility:visible}.audiovideo .remoteVideo.onlyaudio{background:#666;visibility:visible}.audiovideo .remoteVideo .onlyaudio{color:rgba(255,255,255,0.3);display:none;font-size:80px;left:0;margin-top:-40px;pointer-events:auto;position:absolute;right:0;text-align:center;top:45%}.audiovideo .remoteVideo.onlyaudio video{visibility:hidden}.audiovideo .remoteVideo.onlyaudio .onlyaudio{display:block}.audiovideo .remoteVideo .peerActions{bottom:5%;left:40px;opacity:0;pointer-events:auto;position:absolute;right:40px;text-align:center;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.2s;transition-duration:.2s;z-index:10}.audiovideo .remoteVideo .peerActions:hover{opacity:.5}.audiovideo .remoteVideo .peerActions i{font-size:3vw}.audiovideo .remoteVideo .peerLabel{bottom:4%;color:white;left:4%;font-size:2.5vw;max-width:30%;opacity:.7;overflow:hidden;padding:4px;position:absolute;text-overflow:ellipsis;text-shadow:0 0 4px black;white-space:nowrap;z-index:8}.audiovideo .overlayActions{background:rgba(0,0,0,0.9);bottom:0;height:70px;left:0;margin:auto 0;opacity:0;padding:3px 0;position:absolute;top:0;width:40px;z-index:5}.audiovideo .overlayActions button{color:#ccc;cursor:pointer;display:block;outline:0;text-shadow:0 0 5px black;width:40px}.remoteVideo.talking .peerLabel{color:#84b819}.remoteVideo .peerLabel{-webkit-transition:color 500ms ease-out;transition:color 500ms ease-out}.remoteVideo .overlayLogo{background:url(../img/logo-overlay.png) no-repeat center;-webkit-background-size:100%;background-size:100%;height:20%;max-height:40px;max-width:111px;opacity:.5;pointer-events:none;position:absolute;right:4%;top:4%;width:20%;z-index:2}.miniContainer.talking video{border:1px solid #84b819}.miniContainer video{border:1px solid transparent}.renderer-smally{width:150px;background:#f8f8f8;border-right:1px solid #e7e7e7}.renderer-smally .remoteVideos{padding-bottom:85px}.renderer-smally .remoteVideo .peerLabel{font-size:.9em;font-weight:bold}.renderer-smally .remoteVideo .peerActions i{font-size:1em}.renderer-smally .miniContainer{bottom:0;height:85px;left:0;max-height:none;right:0}.renderer-conferencekiosk .remoteVideos{background:rgba(0,0,0,0.4);bottom:2px;min-height:108px;pointer-events:auto;text-align:center;top:auto;white-space:nowrap}.renderer-conferencekiosk .remoteVideos>div{cursor:pointer;height:108px;width:192px}.renderer-conferencekiosk .remoteVideos .overlayLogo{display:none}.renderer-conferencekiosk .remoteVideos .peerLabel,.renderer-conferencekiosk .remoteVideos .peerActions i{font-size:1.1em}.renderer-conferencekiosk .remoteVideos .peerLabel{background:rgba(0,0,0,0.9)}.renderer-conferencekiosk .miniContainer{height:108px;max-height:none;width:192px}.renderer-conferencekiosk .bigVideo{bottom:112px;left:0;margin:auto;opacity:0;position:absolute;right:0;top:2px;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:2s;transition-duration:2s}.renderer-conferencekiosk .bigVideo video{width:100%;height:100%}.screenshare{bottom:0;left:0;position:absolute;right:0;top:0}.mainScreenshare #screenshare{display:block}.screensharepane{background:black;bottom:0;left:0;overflow:auto;position:absolute;right:0;top:0}.screensharepane .remotescreen{position:relative}.screensharepane video{max-height:99%;width:100%}.remotesize .screensharepane video{max-height:none;width:auto}.screenshare .overlaybar{bottom:0;left:0;right:0}#roombar{left:0;min-width:260px;position:absolute;right:0;top:51px;z-index:4}#roombar .roombar{left:0;position:absolute;right:0;top:0}.fa.email{color:#aaa}.fa.facebook{color:#45619d}.fa.google{color:#dd4b39}.fa.twitter{color:#00aced}.fa.xing{color:#fff}.contactsmanager .head{margin-bottom:10px}.contactsmanager .desc{font-size:20px;font-weight:normal;text-align:baseline}.contactsmanager .addbtn{font-size:14px}.contactsmanager .addbtn .fa-users{font-size:22px}.contactsmanager .addbtn .fa-plus{font-size:15px}.contactsmanager .editpicture{vertical-align:middle;float:left;margin-right:20px}.contactsmanager .uploadbtn{margin-top:7px}.contactsmanager .editlist{max-height:250px;overflow-y:auto}.contactsmanager .table{margin-bottom:0px}.contactsmanager .table tr:first-child td{border-top:none}.contactsmanager .table .picture{border-bottom:0;cursor:auto;min-height:46px}.contactsmanager .table .name{width:70%;text-align:left;vertical-align:middle}.contactsmanager .table .action{text-align:center;vertical-align:middle}.search:before{position:absolute;font-family:"fontAwesome";content:"\f002";font-size:14px;opacity:.4;top:6px;left:22px}.search ~ input{padding-left:25px}.presentation{bottom:0;left:0;position:absolute;right:0;top:0}.presentationpane .welcome{padding:0}.presentationpane .welcome h1{white-space:normal}.presentationpane .welcome div{text-align:center}.presentationpane .welcome button{margin-top:30px}.presentationpane .welcome .progress span{text-shadow:none}.presentationpane .welcome .progress .download-info{position:absolute;left:0;width:100%;color:#333;text-shadow:1px 1px 1px white}.mainPresentation #presentation{display:block}.presentationpane{bottom:0;left:0;overflow:auto;position:absolute;right:0;top:0}.presentationpane .canvasContainer{width:100%;height:100%}.presentationpane canvas{position:relative;display:block;margin:0 auto}.presentationpane .odfcanvas{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.presentationpane .odfcanvas body{background-color:transparent}.presentationpane .odfcanvas document{display:block}.presentationpane .odfcontainer{display:none;padding:0;margin:0}.presentationpane .odfcontainer.showonepage{overflow:hidden;text-align:center}.presentation .overlaybar{bottom:0;left:0;right:0;text-align:center}.presentation .overlaybar .overlaybar-content{max-width:100%}.presentation .overlaybar a.overlaybar-button{position:absolute;font-size:20px;padding:4px 6px;top:0px;line-height:28px}.overlaybar-content .pagecontrol{height:30px}.presentation .overlaybar a.btn-prev{left:40px}.presentation .overlaybar a.btn-next{right:0px;left:auto}.pageinfo input{display:inline;width:70px}.presentation .thumbnail{text-shadow:none;color:#333;margin-top:20px;width:160px;height:122px;display:inline-block;margin-left:20px;position:relative;vertical-align:middle}.presentation .thumbnail.presentable{cursor:pointer}.presentation .thumbnail:first-child{margin-left:0}.presentation .thumbnail .caption{padding-bottom:0;text-overflow:ellipsis;overflow:hidden}.presentation .thumbnail .caption .size{font-size:10px}.presentation .thumbnail .caption .progress{position:relative}.presentation .thumbnail .caption .download-info{position:absolute;left:0;right:0;top:0;bottom:0;line-height:20px;text-shadow:1px 1px 1px white;color:#333}.presentation .thumbnail .active{font-size:10em;color:#84b819;opacity:0.7;position:absolute;left:0;right:0;top:0;bottom:0;text-align:center}.presentation .thumbnail .notavailable{display:none;font-size:10em;color:#d2322d;opacity:0.25;position:absolute;left:0;right:0;top:0;bottom:0;text-align:center}.presentation .thumbnail:hover .notavailable{display:block}.presentation .thumbnail .presentation-action{position:absolute;top:1px;display:none}.presentation .thumbnail .download{left:1px}.presentation .thumbnail .delete{right:1px}.presentation .thumbnail:hover .presentation-action{display:block}.presentation .thumbnail .filetype{font-size:5em}.presentations{height:156px;overflow-x:auto;overflow-y:hidden;white-space:nowrap;margin-right:10px;margin-left:-25px}.youtubevideo{position:absolute;left:0;right:0;bottom:0;top:0}.youtubevideopane{bottom:0;left:0;overflow:auto;position:absolute;right:0;top:0}#youtubecontainer{position:relative}#youtubeplayerinfo{position:absolute;left:0;right:0;bottom:10%;opacity:0;pointer-events:auto;text-align:center;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-duration:.2s;transition-duration:.2s;z-index:10}#youtubeplayerinfo:hover{opacity:.8}#youtubeplayerinfo div{background-color:#f9f2f4;border-radius:10px;padding:20px 40px;display:inline-block;font-size:2em}.youtubevideo .click-container{position:absolute;left:0;top:0;bottom:0;right:0;z-index:5}.youtubevideo .welcome{max-width:700px}.youtubevideo .welcome h1{margin-top:10px}.youtubevideo .welcome .welcome-container{max-width:700px}.youtubevideo .welcome .welcome-logo{font-size:10em;background:transparent}.mainYoutubevideo #youtubevideo{display:block}.youtubevideo .overlaybar{bottom:0;left:0;right:0}.youtubevideo .overlaybar-content{width:100%;max-width:100%}.youtubevideo .overlaybar-input{position:relative;width:100%;padding-right:15px}.youtubevideo .overlaybar-content form .overlaybar-buttons{position:absolute;right:23px;top:6px}.modal{overflow-y:auto} From 09e9066b6ce9d05c04b516253c690410fbf9400f Mon Sep 17 00:00:00 2001 From: Evan Theurer Date: Mon, 25 Aug 2014 10:57:53 +0200 Subject: [PATCH 15/15] Fix spacing. --- static/js/directives/directives.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/js/directives/directives.js b/static/js/directives/directives.js index fae2b192..de5d0458 100644 --- a/static/js/directives/directives.js +++ b/static/js/directives/directives.js @@ -42,7 +42,7 @@ define([ 'directives/pdfcanvas', 'directives/odfcanvas', 'directives/presentation', - 'directives/youtubevideo',], function(_, onEnter, onEscape, statusMessage, buddyList, buddyPictureCapture, buddyPictureUpload,settings, chat, audioVideo, usability, audioLevel, fileInfo, screenshare, roomBar, socialShare, page, contactRequest, defaultDialog, pdfcanvas, odfcanvas, presentation, youtubevideo) { + 'directives/youtubevideo',], function(_, onEnter, onEscape, statusMessage, buddyList, buddyPictureCapture, buddyPictureUpload, settings, chat, audioVideo, usability, audioLevel, fileInfo, screenshare, roomBar, socialShare, page, contactRequest, defaultDialog, pdfcanvas, odfcanvas, presentation, youtubevideo) { var directives = { onEnter: onEnter,