Merge pull request #575 from jitsi/fix-follow-me-exception

Fixes exception in follow-me when we receive an update for a video th…
This commit is contained in:
damencho 2016-04-01 08:38:06 -05:00
commit af2809258c
2 changed files with 69 additions and 11 deletions

View File

@ -25,6 +25,15 @@ import FilmStrip from './UI/videolayout/FilmStrip';
*/ */
const _COMMAND = "follow-me"; const _COMMAND = "follow-me";
/**
* The timeout after which a follow-me command that has been received will be
* ignored if not consumed.
*
* @type {number} in seconds
* @private
*/
const _FOLLOW_ME_RECEIVED_TIMEOUT = 30;
/** /**
* Represents the set of {FollowMe}-related states (properties and their * Represents the set of {FollowMe}-related states (properties and their
* respective values) which are to be followed by a participant. {FollowMe} * respective values) which are to be followed by a participant. {FollowMe}
@ -112,6 +121,7 @@ class FollowMe {
constructor (conference, UI) { constructor (conference, UI) {
this._conference = conference; this._conference = conference;
this._UI = UI; this._UI = UI;
this.nextOnStageTimer = 0;
// The states of the local participant which are to be followed (by the // The states of the local participant which are to be followed (by the
// remote participants when the local participant is in her right to // remote participants when the local participant is in her right to
@ -265,6 +275,7 @@ class FollowMe {
// issued by a defined commander. // issued by a defined commander.
if (typeof id === 'undefined') if (typeof id === 'undefined')
return; return;
// The Command(s) API will send us our own commands and we don't want // The Command(s) API will send us our own commands and we don't want
// to act upon them. // to act upon them.
if (this._conference.isLocalId(id)) if (this._conference.isLocalId(id))
@ -297,22 +308,24 @@ class FollowMe {
// writing whether calling UI.toggleFilmStrip() is acceptable (from // writing whether calling UI.toggleFilmStrip() is acceptable (from
// a design standpoint) either. // a design standpoint) either.
if (filmStripVisible !== FilmStrip.isFilmStripVisible()) if (filmStripVisible !== FilmStrip.isFilmStripVisible())
this._UI.eventEmitter.emit( this._UI.eventEmitter.emit(UIEvents.TOGGLE_FILM_STRIP);
UIEvents.TOGGLE_FILM_STRIP,
filmStripVisible);
} }
} }
_onNextOnStage(id) { _onNextOnStage(id) {
var clickId = null; var clickId = null;
if(typeof id !== 'undefined' && !VideoLayout.isPinned(id)) var pin;
if(typeof id !== 'undefined' && !VideoLayout.isPinned(id)) {
clickId = id; clickId = id;
else if (typeof id == 'undefined' && VideoLayout.getPinnedId()) pin = true;
}
else if (typeof id == 'undefined' && VideoLayout.getPinnedId()) {
clickId = VideoLayout.getPinnedId(); clickId = VideoLayout.getPinnedId();
pin = false;
}
if (clickId) if (clickId)
VideoLayout.handleVideoThumbClicked(clickId); this._pinVideoThumbnailById(clickId, pin);
} }
_onSharedDocumentVisible(sharedDocumentVisible) { _onSharedDocumentVisible(sharedDocumentVisible) {
@ -328,6 +341,41 @@ class FollowMe {
this._UI.getSharedDocumentManager().toggleEtherpad(); this._UI.getSharedDocumentManager().toggleEtherpad();
} }
} }
/**
* Pins / unpins the video thumbnail given by clickId.
*
* @param clickId the identifier of the video thumbnail to pin or unpin
* @param pin {true} to pin, {false} to unpin
* @private
*/
_pinVideoThumbnailById(clickId, pin) {
var self = this;
var smallVideo = VideoLayout.getSmallVideo(clickId);
// If the SmallVideo for the given clickId exists we proceed with the
// pin/unpin.
if (smallVideo) {
this.nextOnStageTimer = 0;
clearTimeout(this.nextOnStageTimout);
if (pin && !VideoLayout.isPinned(clickId)
|| !pin && VideoLayout.isPinned(clickId))
VideoLayout.handleVideoThumbClicked(clickId);
}
// If there's no SmallVideo object for the given id, lets wait and see
// if it's going to be created in the next 30sec.
else {
this.nextOnStageTimout = setTimeout(function () {
if (self.nextOnStageTimer > _FOLLOW_ME_RECEIVED_TIMEOUT) {
self.nextOnStageTimer = 0;
return;
}
this.nextOnStageTimer++;
self._pinVideoThumbnailById(clickId, pin);
}, 1000);
}
}
} }
export default FollowMe; export default FollowMe;

View File

@ -315,11 +315,21 @@ SmallVideo.prototype.selectVideoElement = function () {
return $(RTCUIHelper.findVideoElement($('#' + this.videoSpanId)[0])); return $(RTCUIHelper.findVideoElement($('#' + this.videoSpanId)[0]));
}; };
/**
* Enables / disables the css responsible for focusing/pinning a video
* thumbnail.
*
* @param isFocused indicates if the thumbnail should be focused/pinned or not
*/
SmallVideo.prototype.focus = function(isFocused) { SmallVideo.prototype.focus = function(isFocused) {
if(!isFocused) { var focusedCssClass = "videoContainerFocused";
this.container.classList.remove("videoContainerFocused"); var isFocusClassEnabled = $(this.container).hasClass(focusedCssClass);
} else {
this.container.classList.add("videoContainerFocused"); if (!isFocused && isFocusClassEnabled) {
$(this.container).removeClass(focusedCssClass);
}
else if (isFocused && !isFocusClassEnabled) {
$(this.container).addClass(focusedCssClass);
} }
}; };