feat(1-on-1): Initial implementation
- Expose an api on Filmstrip to hide the remote videos container, which does so by adding a class - Modify listeners for user join, leave, share video to call the api - Hide the container when there is 1 or fewer remote participants - Always show the container if self view is in focus - Show the container if the number of remote thumbnails does not match the count of remote participants, such as the case of sharing a video
This commit is contained in:
parent
aabe641047
commit
2333249b05
|
@ -1286,6 +1286,8 @@ export default {
|
|||
|
||||
// check the roles for the new user and reflect them
|
||||
APP.UI.updateUserRole(user);
|
||||
|
||||
updateRemoteThumbnailsVisibility();
|
||||
});
|
||||
room.on(ConferenceEvents.USER_LEFT, (id, user) => {
|
||||
APP.store.dispatch(participantLeft(id, user));
|
||||
|
@ -1293,6 +1295,8 @@ export default {
|
|||
APP.API.notifyUserLeft(id);
|
||||
APP.UI.removeUser(id, user.getDisplayName());
|
||||
APP.UI.onSharedVideoStop(id);
|
||||
|
||||
updateRemoteThumbnailsVisibility();
|
||||
});
|
||||
|
||||
room.on(ConferenceEvents.USER_STATUS_CHANGED, (id, status) => {
|
||||
|
@ -1475,6 +1479,8 @@ export default {
|
|||
reportError(e);
|
||||
}
|
||||
}
|
||||
|
||||
updateRemoteThumbnailsVisibility();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1811,6 +1817,8 @@ export default {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateRemoteThumbnailsVisibility();
|
||||
});
|
||||
room.addCommandListener(
|
||||
this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {
|
||||
|
@ -1826,6 +1834,21 @@ export default {
|
|||
APP.UI.onSharedVideoUpdate(id, value, attributes);
|
||||
}
|
||||
});
|
||||
|
||||
function updateRemoteThumbnailsVisibility() {
|
||||
const localUserId = APP.conference.getMyUserId();
|
||||
const remoteParticipantsCount = room.getParticipantCount() - 1;
|
||||
|
||||
// Get the remote thumbnail count for cases where there are
|
||||
// non-participants displaying video, such as with video sharing.
|
||||
const remoteVideosCount = APP.UI.getRemoteVideosCount();
|
||||
|
||||
const shouldShowRemoteThumbnails = APP.UI.isPinned(localUserId)
|
||||
|| remoteVideosCount > 1
|
||||
|| remoteParticipantsCount !== remoteVideosCount;
|
||||
|
||||
APP.UI.setRemoteThumbnailsVisibility(shouldShowRemoteThumbnails);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Adds any room listener.
|
||||
|
|
|
@ -57,6 +57,9 @@ var config = { // eslint-disable-line no-unused-vars
|
|||
webrtcIceTcpDisable: false,
|
||||
|
||||
openSctp: true, // Toggle to enable/disable SCTP channels
|
||||
|
||||
// Disable hiding of remote thumbnails when in a 1-on-1 conference call.
|
||||
disable1On1Mode: false,
|
||||
disableStats: false,
|
||||
disableAudioLevels: false,
|
||||
channelLastN: -1, // The default value of the channel attribute last-n.
|
||||
|
|
|
@ -138,4 +138,13 @@
|
|||
margin-bottom: auto;
|
||||
padding-right: $defaultToolbarSize;
|
||||
}
|
||||
|
||||
.remote-videos-container {
|
||||
transition: opacity 1s;
|
||||
|
||||
&.hide-videos {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -309,6 +309,10 @@ UI.start = function () {
|
|||
SideContainerToggler.init(eventEmitter);
|
||||
Filmstrip.init(eventEmitter);
|
||||
|
||||
// By default start with remote videos hidden and rely on other logic to
|
||||
// make them visible.
|
||||
UI.setRemoteThumbnailsVisibility(false);
|
||||
|
||||
VideoLayout.init(eventEmitter);
|
||||
if (!interfaceConfig.filmStripOnly) {
|
||||
VideoLayout.initLargeVideo();
|
||||
|
@ -1146,6 +1150,15 @@ UI.getLargeVideo = function () {
|
|||
return VideoLayout.getLargeVideo();
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether or not the passed in user id is currently pinned to the large
|
||||
* video.
|
||||
*
|
||||
* @param {string} userId - The id of the user to check is pinned or not.
|
||||
* @returns {boolean} True if the user is currently pinned to the large video.
|
||||
*/
|
||||
UI.isPinned = userId => VideoLayout.getPinnedId() === userId;
|
||||
|
||||
/**
|
||||
* Shows dialog with a link to FF extension.
|
||||
*/
|
||||
|
@ -1396,6 +1409,23 @@ UI.isRingOverlayVisible = () => RingOverlay.isVisible();
|
|||
*/
|
||||
UI.onUserFeaturesChanged = user => VideoLayout.onUserFeaturesChanged(user);
|
||||
|
||||
/**
|
||||
* Returns the number of known remote videos.
|
||||
*
|
||||
* @returns {number} The number of remote videos.
|
||||
*/
|
||||
UI.getRemoteVideosCount = () => VideoLayout.getRemoteVideosCount();
|
||||
|
||||
/**
|
||||
* Makes remote thumbnail videos visible or not visible.
|
||||
*
|
||||
* @param {boolean} shouldHide - True if remote thumbnails should be hidden,
|
||||
* false f they should be visible.
|
||||
* @returns {void}
|
||||
*/
|
||||
UI.setRemoteThumbnailsVisibility
|
||||
= shouldHide => Filmstrip.setRemoteVideoVisibility(shouldHide);
|
||||
|
||||
const UIListeners = new Map([
|
||||
[
|
||||
UIEvents.ETHERPAD_CLICKED,
|
||||
|
|
|
@ -456,6 +456,9 @@ export default class SharedVideoManager {
|
|||
// revert to original behavior (prevents pausing
|
||||
// for participants not sharing the video to pause it)
|
||||
$("#sharedVideo").css("pointer-events","auto");
|
||||
|
||||
this.emitter.emit(
|
||||
UIEvents.UPDATE_SHARED_VIDEO, null, 'removed');
|
||||
});
|
||||
|
||||
this.url = null;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* global $, APP, JitsiMeetJS, interfaceConfig */
|
||||
/* global $, APP, config, JitsiMeetJS, interfaceConfig */
|
||||
|
||||
import UIEvents from "../../../service/UI/UIEvents";
|
||||
import UIUtil from "../util/UIUtil";
|
||||
|
@ -25,6 +25,27 @@ const Filmstrip = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a class on the remote videos container for CSS to adjust visibility
|
||||
* of the remote videos. Will no-op if config.debug is truthy, as should be
|
||||
* the case with torture tests.
|
||||
*
|
||||
* @param {boolean} shouldHide - True if remote videos should be hidden,
|
||||
* false if they should be visible.
|
||||
* @returns {void}
|
||||
*/
|
||||
setRemoteVideoVisibility(shouldShow) {
|
||||
// FIXME Checking config.debug is a grand hack to avoid fixing the
|
||||
// torture tests after the 1-on-1 UI was implemented, which hides remote
|
||||
// videos on 1-on-1 calls. If this check is to be kept, at least create
|
||||
// new torture tests to verify 1-on-1 mode.
|
||||
if (config.debug || config.disable1On1Mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.filmstripRemoteVideos.toggleClass('hide-videos', !shouldShow);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initializes the filmstrip toolbar.
|
||||
*/
|
||||
|
|
|
@ -1133,6 +1133,15 @@ var VideoLayout = {
|
|||
*/
|
||||
getLargeVideoWrapper() {
|
||||
return this.getCurrentlyOnLargeContainer().$wrapper;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the number of remove video ids.
|
||||
*
|
||||
* @returns {number} The number of remote videos.
|
||||
*/
|
||||
getRemoteVideosCount() {
|
||||
return Object.keys(remoteVideos).length;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue