diff --git a/css/_filmstrip.scss b/css/_filmstrip.scss
new file mode 100644
index 000000000..fbcee68fd
--- /dev/null
+++ b/css/_filmstrip.scss
@@ -0,0 +1,120 @@
+%align-right {
+ @include flex();
+ flex-direction: row-reverse;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+}
+
+.filmstrip {
+ position: absolute;
+ bottom: 0;
+ right: 0;
+ padding: 10px 5px;
+ @extend %align-right;
+
+ &__toolbar {
+ @include flex();
+ flex-direction: column-reverse;
+ flex-wrap: nowrap;
+ position: relative;
+ z-index: 1; // Set z-index to make element visible
+ width: 17px;
+
+ button {
+ font-size: 14px;
+ line-height: 1.2;
+ text-align: center;
+ background: transparent;
+ opacity: 0.7;
+ height: auto;
+ width: 100%;
+ padding: 0;
+ margin: 0;
+ border: none;
+ outline: none;
+
+ -webkit-appearance: none;
+
+ &:hover {
+ opacity: 1;
+ }
+
+ i {
+ cursor: pointer;
+ }
+ }
+ }
+
+ &__videos {
+ @extend %align-right;
+ position:relative;
+ height:196px;
+ padding: 0;
+ bottom: 0;
+ width:auto;
+ border: 2px solid transparent;
+ z-index: 5;
+ transition: bottom 2s;
+ overflow: visible !important;
+ font-size: 0pt; /*!!!Removes the gap between the local video container and the remote videos.*/
+
+ &.hidden {
+ bottom: -196px;
+ }
+
+ .videocontainer {
+ display: none;
+ position: relative;
+ background-size: contain;
+ border: 2px solid transparent;
+ border-radius:1px;
+ margin: 0 $thumbnailVideoMargin;
+
+ &.videoContainerFocused, &:hover {
+ cursor: hand;
+ }
+
+ /**
+ * Focused video thumbnail.
+ */
+ &.videoContainerFocused {
+ transition-duration: 0.5s;
+ -webkit-transition-duration: 0.5s;
+ -webkit-animation-name: greyPulse;
+ -webkit-animation-duration: 2s;
+ -webkit-animation-iteration-count: 1;
+ border: 2px solid $videoThumbnailSelected !important;
+ box-shadow: inset 0 0 3px $videoThumbnailSelected,
+ 0 0 3px $videoThumbnailSelected !important;
+ }
+
+ .remotevideomenu {
+ display: none;
+ }
+
+ /**
+ * Hovered video thumbnail.
+ */
+ &:hover {
+ cursor: hand;
+ border: 2px solid $videoThumbnailHovered;
+ box-shadow: inset 0 0 3px $videoThumbnailHovered,
+ 0 0 3px $videoThumbnailHovered;
+
+ .remotevideomenu {
+ display: inline-block;
+ }
+ }
+
+ /* With TemasysWebRTC plugin element is used
+ instead of */
+ & > video,
+ & > object {
+ cursor: hand;
+ border-radius:1px;
+ object-fit: cover;
+ overflow: hidden;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/css/_toastr.scss b/css/_toastr.scss
index 655665a22..f72fcabca 100644
--- a/css/_toastr.scss
+++ b/css/_toastr.scss
@@ -93,7 +93,7 @@
#toast-container.notification-bottom-right {
bottom: 135px;
- right: 13px;
+ right: 28px;
}
#toast-container * {
diff --git a/css/_videolayout_default.scss b/css/_videolayout_default.scss
index 6715a98b5..326e2a2c5 100644
--- a/css/_videolayout_default.scss
+++ b/css/_videolayout_default.scss
@@ -12,34 +12,6 @@
overflow: hidden;
}
-#remoteVideos {
- display: -webkit-box;
- display: -moz-box;
- display: -ms-flexbox;
- display: -webkit-flex;
- display: flex;
- flex-direction: row-reverse;
- flex-wrap: nowrap;
- justify-content: flex-start;
-
- position:absolute;
- text-align:right;
- height:196px;
- padding: 10px 10px 17px 5px;
- bottom: 0;
- right: 0;
- width:auto;
- border: 2px solid transparent;
- z-index: 5;
- transition: bottom 2s;
- overflow: visible !important;
- font-size: 0pt; /*!!!Removes the gap between the local video container and the remote videos.*/
-}
-
-#remotevideos.hidden {
- bottom: -196px;
-}
-
.videocontainer {
position: relative;
text-align: center;
@@ -52,15 +24,6 @@
}
}
-#remoteVideos .videocontainer {
- display: none;
- position: relative;
- background-size: contain;
- border: 2px solid transparent;
- border-radius:1px;
- margin: 0 $thumbnailVideoMargin;
-}
-
/**
* The toolbar of the video thumbnail.
*/
@@ -96,60 +59,10 @@
z-index: 2;
}
-#remoteVideos .videocontainer.videoContainerFocused,
-#remoteVideos .videocontainer:hover {
- cursor: hand;
-}
-/**
- * Focused video thumbnail.
- */
-#remoteVideos .videocontainer.videoContainerFocused {
- transition-duration: 0.5s;
- -webkit-transition-duration: 0.5s;
- -webkit-animation-name: greyPulse;
- -webkit-animation-duration: 2s;
- -webkit-animation-iteration-count: 1;
- border: 2px solid $videoThumbnailSelected !important;
- box-shadow: inset 0 0 3px $videoThumbnailSelected,
- 0 0 3px $videoThumbnailSelected !important;
-}
-
-/**
- * Hovered video thumbnail.
- */
-#remoteVideos .videocontainer {
- .remotevideomenu {
- display: none;
- }
-
- /**
- * Show/hide items for hover event here
- */
- &:hover {
- cursor: hand;
- border: 2px solid $videoThumbnailHovered;
- box-shadow: inset 0 0 3px $videoThumbnailHovered,
- 0 0 3px $videoThumbnailHovered;
- .remotevideomenu {
- display: inline-block;
- }
- }
-}
-
#localVideoWrapper {
display:inline-block;
}
-/* With TemasysWebRTC plugin element is used
- instead of */
-#remoteVideos .videocontainer>video,
-#remoteVideos .videocontainer>object {
- cursor: hand;
- border-radius:1px;
- object-fit: cover;
- overflow: hidden;
-}
-
.flipVideoX {
transform: scale(-1, 1);
-moz-transform: scale(-1, 1);
@@ -618,39 +531,4 @@
.moveToCorner + .moveToCorner {
right: 80px;
-}
-
-.filmstripToolbar {
- width: 20px;
- position: absolute;
- right: 4px;
- bottom: 20px;
- z-index: 6;
-
- button {
- font-size: 14px;
- line-height: 1.2;
- text-align: center;
- background: transparent;
- opacity: 0.7;
- height: auto;
- width: 100%;
- padding: 0;
- margin: 0 1px;
- border: none;
-
- -webkit-appearance: none;
-
- &:hover {
- opacity: 1;
- }
-
- i {
- cursor: pointer;
- }
- }
-}
-
-.filmstripToolbar + #remoteVideos {
- padding-right: 24px;
}
\ No newline at end of file
diff --git a/css/main.scss b/css/main.scss
index cb8e25ab3..3d2af62be 100644
--- a/css/main.scss
+++ b/css/main.scss
@@ -63,5 +63,6 @@
@import 'aui-components/dropdown';
@import '404';
@import 'policy';
+@import 'filmstrip';
/* Modules END */
diff --git a/index.html b/index.html
index c29a4087e..a5d9063be 100644
--- a/index.html
+++ b/index.html
@@ -166,21 +166,23 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
diff --git a/modules/UI/videolayout/FilmStrip.js b/modules/UI/videolayout/FilmStrip.js
index fe75db12c..d33f5a854 100644
--- a/modules/UI/videolayout/FilmStrip.js
+++ b/modules/UI/videolayout/FilmStrip.js
@@ -10,48 +10,72 @@ const FilmStrip = {
* emit/fire {UIEvents} (such as {UIEvents.TOGGLED_FILM_STRIP}).
*/
init (eventEmitter) {
+ this.iconMenuDownClassName = 'icon-menu-down';
+ this.iconMenuUpClassName = 'icon-menu-up';
this.filmStrip = $('#remoteVideos');
this.eventEmitter = eventEmitter;
- this.filmStripIsVisible = true;
- this.renderFilmstripToolbar();
- this.activateHideButton();
+ this._initFilmStripToolbar();
+ this.registerListeners();
+ },
+
+ /**
+ * Initializes the filmstrip toolbar
+ */
+ _initFilmStripToolbar() {
+ let toolbar = this._generateFilmStripToolbar();
+ let container = document.querySelector('.filmstrip');
+
+ UIUtil.prependChild(container, toolbar);
+
+ let iconSelector = '#hideVideoToolbar i';
+ this.toggleFilmStripIcon = document.querySelector(iconSelector);
+ },
+
+ /**
+ * Generates HTML layout for filmstrip toolbar
+ * @returns {HTMLElement}
+ * @private
+ */
+ _generateFilmStripToolbar() {
+ let container = document.createElement('div');
+ let isVisible = this.isFilmStripVisible();
+ container.className = 'filmstrip__toolbar';
+
+ container.innerHTML = `
+
+ `;
+
+ return container;
},
/**
* Attach 'click' listener to "hide filmstrip" button
*/
- activateHideButton () {
- $('#videospace').on('click', '#hideVideoToolbar', () => {
- var icon = document.querySelector('#hideVideoToolbar i');
-
- this.filmStripIsVisible = !this.filmStripIsVisible;
- this.toggleFilmStrip(this.filmStripIsVisible);
-
- icon.classList.remove(
- this.filmStripIsVisible ? 'icon-menu-up' : 'icon-menu-down');
- icon.classList.add(
- this.filmStripIsVisible ? 'icon-menu-down' : 'icon-menu-up');
- });
+ registerListeners() {
+ let toggleFilmstripMethod = this.toggleFilmStrip.bind(this);
+ let selector = '#hideVideoToolbar';
+ $('#videospace').on('click', selector, toggleFilmstripMethod);
},
/**
- * Shows toolbar on the right of the filmstrip
+ * Changes classes of icon for showing down state
*/
- renderFilmstripToolbar () {
- // create toolbar
- var container = document.createElement('div');
- container.className = 'filmstripToolbar';
+ showMenuDownIcon() {
+ let icon = this.toggleFilmStripIcon;
+ icon.classList.add(this.iconMenuDownClassName);
+ icon.classList.remove(this.iconMenuUpClassName);
+ },
- container.innerHTML = `
-
- `;
-
- // show toolbar
- document.querySelector('#videospace')
- .insertBefore(container, document.querySelector('#remoteVideos'));
+ /**
+ * Changes classes of icon for showing up state
+ */
+ showMenuUpIcon() {
+ let icon = this.toggleFilmStripIcon;
+ icon.classList.add(this.iconMenuUpClassName);
+ icon.classList.remove(this.iconMenuDownClassName);
},
/**
@@ -62,14 +86,22 @@ const FilmStrip = {
* (i.e. toggled); otherwise, the visibility will be set to the specified
* value.
*/
- toggleFilmStrip (visible) {
- if (typeof visible === 'boolean'
- && this.isFilmStripVisible() == visible) {
+ toggleFilmStrip(visible) {
+ let isVisibleDefined = typeof visible === 'boolean';
+ if (!isVisibleDefined) {
+ visible = this.isFilmStripVisible();
+ } else if (this.isFilmStripVisible() === visible) {
return;
}
this.filmStrip.toggleClass("hidden");
+ if (!visible) {
+ this.showMenuDownIcon();
+ } else {
+ this.showMenuUpIcon();
+ }
+
// Emit/fire UIEvents.TOGGLED_FILM_STRIP.
var eventEmitter = this.eventEmitter;
if (eventEmitter) {
@@ -79,18 +111,26 @@ const FilmStrip = {
}
},
- isFilmStripVisible () {
+ /**
+ * Shows if filmstrip is visible
+ * @returns {boolean}
+ */
+ isFilmStripVisible() {
return !this.filmStrip.hasClass('hidden');
},
- setupFilmStripOnly () {
+ setupFilmStripOnly() {
this.filmStrip.css({
padding: "0px 0px 18px 0px",
right: 0
});
},
- getFilmStripHeight () {
+ /**
+ * Returns the height of filmstrip
+ * @returns {number} height
+ */
+ getFilmStripHeight() {
if (this.isFilmStripVisible()) {
return this.filmStrip.outerHeight();
} else {
@@ -98,12 +138,20 @@ const FilmStrip = {
}
},
- getFilmStripWidth () {
+ /**
+ * Returns the width of filmstip
+ * @returns {number} width
+ */
+ getFilmStripWidth() {
return this.filmStrip.innerWidth()
- parseInt(this.filmStrip.css('paddingLeft'), 10)
- parseInt(this.filmStrip.css('paddingRight'), 10);
},
+ /**
+ * Calculates the size for thumbnails: local and remote one
+ * @returns {*|{localVideo, remoteVideo}}
+ */
calculateThumbnailSize() {
let availableSizes = this.calculateAvailableSize();
let width = availableSizes.availableWidth;
@@ -115,7 +163,7 @@ const FilmStrip = {
/**
* Normalizes local and remote thumbnail ratios
*/
- normalizeThumbnailRatio () {
+ normalizeThumbnailRatio() {
let remoteHeightRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_HEIGHT;
let remoteWidthRatio = interfaceConfig.REMOTE_THUMBNAIL_RATIO_WIDTH;
@@ -146,6 +194,11 @@ const FilmStrip = {
return { localRatio, remoteRatio };
},
+ /**
+ * Calculates available size for one thumbnail according to
+ * the current window size
+ * @returns {{availableWidth: number, availableHeight: number}}
+ */
calculateAvailableSize() {
let availableHeight = interfaceConfig.FILM_STRIP_MAX_HEIGHT;
let thumbs = this.getThumbs(true);
@@ -221,6 +274,13 @@ const FilmStrip = {
return { availableWidth, availableHeight };
},
+ /**
+ * Takes the available size for thumbnail and calculates
+ * final size of thumbnails
+ * @param availableWidth
+ * @param availableHeight
+ * @returns {{localVideo, remoteVideo}}
+ */
calculateThumbnailSizeFromAvailable(availableWidth, availableHeight) {
let { localRatio, remoteRatio } = this.normalizeThumbnailRatio();
let { remoteThumbs } = this.getThumbs(true);
@@ -251,7 +311,15 @@ const FilmStrip = {
};
},
- resizeThumbnails (local, remote,
+ /**
+ * Resizes thumbnails
+ * @param local
+ * @param remote
+ * @param animate
+ * @param forceUpdate
+ * @returns {Promise}
+ */
+ resizeThumbnails(local, remote,
animate = false, forceUpdate = false) {
return new Promise(resolve => {
@@ -289,7 +357,12 @@ const FilmStrip = {
});
},
- getThumbs (only_visible = false) {
+ /**
+ * Returns thumbnails of the filmstrip
+ * @param only_visible
+ * @returns {object} thumbnails
+ */
+ getThumbs(only_visible = false) {
let selector = 'span';
if (only_visible) {
selector += ':visible';