diff --git a/conference.js b/conference.js index ba2f98668..ed346eca2 100644 --- a/conference.js +++ b/conference.js @@ -681,6 +681,16 @@ export default { return this._room && this._room.getConnectionState(); }, + /** + * Checks whether or not our connection is currently in interrupted and + * reconnect attempts are in progress. + * + * @returns {boolean} true if the connection is in interrupted state or + * false otherwise. + */ + isConnectionInterrupted () { + return connectionIsInterrupted; + }, getMyUserId () { return this._room && this._room.myUserId(); diff --git a/modules/UI/shared_video/SharedVideo.js b/modules/UI/shared_video/SharedVideo.js index f873de0a5..92e153190 100644 --- a/modules/UI/shared_video/SharedVideo.js +++ b/modules/UI/shared_video/SharedVideo.js @@ -567,10 +567,6 @@ class SharedVideoContainer extends LargeContainer { this.player = player; } - get $video () { - return this.$iframe; - } - show () { let self = this; return new Promise(resolve => { diff --git a/modules/UI/videolayout/LargeVideoManager.js b/modules/UI/videolayout/LargeVideoManager.js index 8c145e77e..e0934ee74 100644 --- a/modules/UI/videolayout/LargeVideoManager.js +++ b/modules/UI/videolayout/LargeVideoManager.js @@ -81,6 +81,27 @@ export default class LargeVideoManager { container.onHoverOut(e); } + /** + * Called when the media connection has been interrupted. + */ + onVideoInterrupted () { + this.enableVideoProblemFilter(true); + let reconnectingKey = "connection.RECONNECTING"; + $('#videoConnectionMessage') + .attr("data-i18n", reconnectingKey) + .text(APP.translation.translateString(reconnectingKey)); + // Show the message only if the video is currently being displayed + this.showVideoConnectionMessage(this.state === VIDEO_CONTAINER_TYPE); + } + + /** + * Called when the media connection has been restored. + */ + onVideoRestored () { + this.enableVideoProblemFilter(false); + this.showVideoConnectionMessage(false); + } + get id () { let container = this.getContainer(this.state); return container.id; @@ -213,8 +234,7 @@ export default class LargeVideoManager { * @param enable true to enable, false to disable */ enableVideoProblemFilter (enable) { - let container = this.getContainer(this.state); - container.$video.toggleClass("videoProblemFilter", enable); + this.videoContainer.enableVideoProblemFilter(enable); } /** @@ -232,6 +252,24 @@ export default class LargeVideoManager { $('.watermark').css('visibility', show ? 'visible' : 'hidden'); } + /** + * Shows/hides the "video connection message". + * @param {boolean|null} show(optional) tells whether the message is to be + * displayed or not. If missing the condition will be based on the value + * obtained from {@link APP.conference.isConnectionInterrupted}. + */ + showVideoConnectionMessage (show) { + if (typeof show !== 'boolean') { + show = APP.conference.isConnectionInterrupted(); + } + + if (show) { + $('#videoConnectionMessage').css({display: "block"}); + } else { + $('#videoConnectionMessage').css({display: "none"}); + } + } + /** * Add container of specified type. * @param {string} type container type @@ -285,8 +323,12 @@ export default class LargeVideoManager { } let oldContainer = this.containers[this.state]; + // FIXME when video is being replaced with other content we need to hide + // companion icons/messages. It would be best if the container would + // be taking care of it by itself, but that is a bigger refactoring if (this.state === VIDEO_CONTAINER_TYPE) { this.showWatermark(false); + this.showVideoConnectionMessage(false); } oldContainer.hide(); @@ -295,7 +337,12 @@ export default class LargeVideoManager { return container.show().then(() => { if (type === VIDEO_CONTAINER_TYPE) { + // FIXME when video appears on top of other content we need to + // show companion icons/messages. It would be best if + // the container would be taking care of it by itself, but that + // is a bigger refactoring this.showWatermark(true); + this.showVideoConnectionMessage(/* fetch the current state */); } }); } diff --git a/modules/UI/videolayout/VideoContainer.js b/modules/UI/videolayout/VideoContainer.js index 99cef5e70..2043344c2 100644 --- a/modules/UI/videolayout/VideoContainer.js +++ b/modules/UI/videolayout/VideoContainer.js @@ -184,6 +184,17 @@ export class VideoContainer extends LargeContainer { this.$video[0].onplay = onPlay; } + /** + * Enables a filter on the video which indicates that there are some + * problems with the media connection. + * + * @param {boolean} enable true if the filter is to be enabled or + * false otherwise. + */ + enableVideoProblemFilter (enable) { + this.$video.toggleClass("videoProblemFilter", enable); + } + /** * Get size of video element. * @returns {{width, height}} diff --git a/modules/UI/videolayout/VideoLayout.js b/modules/UI/videolayout/VideoLayout.js index cbb229293..0b3b68375 100644 --- a/modules/UI/videolayout/VideoLayout.js +++ b/modules/UI/videolayout/VideoLayout.js @@ -951,28 +951,18 @@ var VideoLayout = { * Indicates that the video has been interrupted. */ onVideoInterrupted () { - this.enableVideoProblemFilter(true); - let reconnectingKey = "connection.RECONNECTING"; - $('#videoConnectionMessage') - .attr("data-i18n", reconnectingKey) - .text(APP.translation.translateString(reconnectingKey)) - .css({display: "block"}); + if (largeVideo) { + largeVideo.onVideoInterrupted(); + } }, /** * Indicates that the video has been restored. */ onVideoRestored () { - this.enableVideoProblemFilter(false); - $('#videoConnectionMessage').css({display: "none"}); - }, - - enableVideoProblemFilter (enable) { - if (!largeVideo) { - return; + if (largeVideo) { + largeVideo.onVideoRestored(); } - - largeVideo.enableVideoProblemFilter(enable); }, isLargeVideoVisible () {