diff --git a/css/videolayout_default.css b/css/videolayout_default.css index 0fdde1424..4767ec059 100644 --- a/css/videolayout_default.css +++ b/css/videolayout_default.css @@ -519,4 +519,7 @@ margin-left: auto; background: rgba(0,0,0,.3); color: rgba(255,255,255,.5); +} + +.hidden { } \ No newline at end of file diff --git a/modules/UI/recording/Recording.js b/modules/UI/recording/Recording.js index fdf92f073..53e9ac949 100644 --- a/modules/UI/recording/Recording.js +++ b/modules/UI/recording/Recording.js @@ -228,7 +228,8 @@ var Recording = { // everyone. if (config.iAmRecorder) { VideoLayout.enableDeviceAvailabilityIcons( - APP.conference.localId, true); + APP.conference.localId, false); + VideoLayout.setLocalVideoVisible(false); Feedback.enableFeedback(false); Toolbar.enable(false); BottomToolbar.enable(false); diff --git a/modules/UI/util/UIUtil.js b/modules/UI/util/UIUtil.js index 0e37b5b11..18c78e717 100644 --- a/modules/UI/util/UIUtil.js +++ b/modules/UI/util/UIUtil.js @@ -199,6 +199,15 @@ () => {selector.css({opacity: 0});} ); } + }, + + /** + * Parses the given cssValue as an Integer. If the value is not a number + * we return 0 instead of NaN. + * @param cssValue the string value we obtain when querying css properties + */ + parseCssInt(cssValue) { + return parseInt(cssValue) || 0; } }; diff --git a/modules/UI/videolayout/FilmStrip.js b/modules/UI/videolayout/FilmStrip.js index 7bdb9245b..27c3b4875 100644 --- a/modules/UI/videolayout/FilmStrip.js +++ b/modules/UI/videolayout/FilmStrip.js @@ -85,20 +85,32 @@ const FilmStrip = { */ let videoAreaAvailableWidth = UIUtil.getAvailableVideoWidth(isSideBarVisible) - - parseInt(this.filmStrip.css('right'), 10) - - parseInt(this.filmStrip.css('paddingLeft'), 10) - - parseInt(this.filmStrip.css('paddingRight'), 10) - - parseInt(this.filmStrip.css('borderLeftWidth'), 10) - - parseInt(this.filmStrip.css('borderRightWidth'), 10) - 5; + - UIUtil.parseCssInt(this.filmStrip.css('right'), 10) + - UIUtil.parseCssInt(this.filmStrip.css('paddingLeft'), 10) + - UIUtil.parseCssInt(this.filmStrip.css('paddingRight'), 10) + - UIUtil.parseCssInt(this.filmStrip.css('borderLeftWidth'), 10) + - UIUtil.parseCssInt(this.filmStrip.css('borderRightWidth'), 10) + - 5; - let availableWidth = Math.floor( + let availableWidth = videoAreaAvailableWidth; + + // If the number of videos is 0 or undefined we don't need to calculate + // further. + if (numvids) + availableWidth = Math.floor( (videoAreaAvailableWidth - numvids * ( - parseInt(localVideoContainer.css('borderLeftWidth'), 10) - + parseInt(localVideoContainer.css('borderRightWidth'), 10) - + parseInt(localVideoContainer.css('paddingLeft'), 10) - + parseInt(localVideoContainer.css('paddingRight'), 10) - + parseInt(localVideoContainer.css('marginLeft'), 10) - + parseInt(localVideoContainer.css('marginRight'), 10))) + UIUtil.parseCssInt( + localVideoContainer.css('borderLeftWidth'), 10) + + UIUtil.parseCssInt( + localVideoContainer.css('borderRightWidth'), 10) + + UIUtil.parseCssInt( + localVideoContainer.css('paddingLeft'), 10) + + UIUtil.parseCssInt( + localVideoContainer.css('paddingRight'), 10) + + UIUtil.parseCssInt( + localVideoContainer.css('marginLeft'), 10) + + UIUtil.parseCssInt( + localVideoContainer.css('marginRight'), 10))) / numvids); let maxHeight @@ -155,7 +167,12 @@ const FilmStrip = { selector += ':visible'; } - return this.filmStrip.children(selector); + // Exclude the local video container if it has been hidden. + if ($("#localVideoContainer").hasClass("hidden")) + return this.filmStrip.children(selector) + .not("#localVideoContainer"); + else + return this.filmStrip.children(selector); } }; diff --git a/modules/UI/videolayout/LocalVideo.js b/modules/UI/videolayout/LocalVideo.js index 09eeaa7f2..09b10184e 100644 --- a/modules/UI/videolayout/LocalVideo.js +++ b/modules/UI/videolayout/LocalVideo.js @@ -1,4 +1,4 @@ -/* global $, interfaceConfig, APP, JitsiMeetJS */ +/* global $, config, interfaceConfig, APP, JitsiMeetJS */ import ConnectionIndicator from "./ConnectionIndicator"; import UIUtil from "../util/UIUtil"; import UIEvents from "../../../service/UI/UIEvents"; @@ -200,4 +200,26 @@ LocalVideo.prototype.changeVideo = function (stream) { stream.on(TrackEvents.LOCAL_TRACK_STOPPED, endedHandler); }; +/** + * Shows or hides the local video container. + * @param {boolean} true to make the local video container visible, false + * otherwise + */ +LocalVideo.prototype.setVisible = function(visible) { + + // We toggle the hidden class as an indication to other interested parties + // that this container has been hidden on purpose. + $("#localVideoContainer").toggleClass("hidden"); + + // We still show/hide it as we need to overwrite the style property if we + // want our action to take effect. Toggling the display property through + // the above css class didn't succeed in overwriting the style. + if (visible) { + $("#localVideoContainer").show(); + } + else { + $("#localVideoContainer").hide(); + } +}; + export default LocalVideo; diff --git a/modules/UI/videolayout/VideoLayout.js b/modules/UI/videolayout/VideoLayout.js index 4058de5aa..3bb02ca9d 100644 --- a/modules/UI/videolayout/VideoLayout.js +++ b/modules/UI/videolayout/VideoLayout.js @@ -215,6 +215,14 @@ var VideoLayout = { video.enableDeviceAvailabilityIcons(enable); }, + /** + * Shows/hides local video. + * @param {boolean} true to make the local video visible, false - otherwise + */ + setLocalVideoVisible(visible) { + localVideoThumbnail.setVisible(visible); + }, + /** * Checks if removed video is currently displayed and tries to display * another one instead.