diff --git a/modules/UI/videolayout/LargeVideoManager.js b/modules/UI/videolayout/LargeVideoManager.js index 42581a675..26ee4faf6 100644 --- a/modules/UI/videolayout/LargeVideoManager.js +++ b/modules/UI/videolayout/LargeVideoManager.js @@ -59,26 +59,38 @@ export default class LargeVideoManager { e => this.onHoverOut(e) ); - // TODO Use the onresize event when temasys video objects support it. - /** - * The interval for checking if the displayed video resolution is or is - * not high-definition. - * - * @private - * @type {timeoutId} - */ - this._updateVideoResolutionInterval = window.setInterval( - () => this._updateVideoResolutionStatus(), - VIDEO_RESOLUTION_POLL_INTERVAL); + // Bind event handler so it is only bound once for every instance. + this._updateVideoResolutionStatus + = this._updateVideoResolutionStatus.bind(this); + + this.videoContainer.addResizeListener( + this._updateVideoResolutionStatus); + + if (!JitsiMeetJS.util.RTCUIHelper.isResizeEventSupported()) { + /** + * An interval for polling if the displayed video resolution is or + * is not high-definition. For browsers that do not support video + * resize events, polling is the fallback. + * + * @private + * @type {timeoutId} + */ + this._updateVideoResolutionInterval = window.setInterval( + this._updateVideoResolutionStatus, + VIDEO_RESOLUTION_POLL_INTERVAL); + } } /** - * Stops any polling intervals on the instance. + * Stops any polling intervals on the instance and and removes any + * listeners registered on child components. * * @returns {void} */ destroy() { window.clearInterval(this._updateVideoResolutionInterval); + this.videoContainer.removeResizeListener( + this._updateVideoResolutionStatus); } onHoverIn (e) { diff --git a/modules/UI/videolayout/VideoContainer.js b/modules/UI/videolayout/VideoContainer.js index 1c00986c9..25ae512e3 100644 --- a/modules/UI/videolayout/VideoContainer.js +++ b/modules/UI/videolayout/VideoContainer.js @@ -216,6 +216,28 @@ export class VideoContainer extends LargeContainer { // copied between new elements //this.$video.on('play', onPlay); this.$video[0].onplay = onPlayCallback; + + /** + * A Set of functions to invoke when the video element resizes. + * + * @private + */ + this._resizeListeners = new Set(); + + // As of May 16, 2017, temasys does not support resize events. + this.$video[0].onresize = this._onResize.bind(this); + } + + /** + * Adds a function to the known subscribers of video element resize + * events. + * + * @param {Function} callback - The subscriber to notify when the video + * element resizes. + * @returns {void} + */ + addResizeListener(callback) { + this._resizeListeners.add(callback); } /** @@ -344,6 +366,18 @@ export class VideoContainer extends LargeContainer { }); } + /** + * Removes a function from the known subscribers of video element resize + * events. + * + * @param {Function} callback - The callback to remove from known + * subscribers of video resize events. + * @returns {void} + */ + removeResizeListener(callback) { + this._resizeListeners.delete(callback); + } + /** * Update video stream. * @param {JitsiTrack?} stream new stream @@ -502,4 +536,14 @@ export class VideoContainer extends LargeContainer { (this.videoType === VIDEO_CONTAINER_TYPE && !isAvatar) ? "#000" : interfaceConfig.DEFAULT_BACKGROUND); } + + /** + * Callback invoked when the video element changes dimensions. + * + * @private + * @returns {void} + */ + _onResize() { + this._resizeListeners.forEach(callback => callback()); + } }