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
|
// check the roles for the new user and reflect them
|
||||||
APP.UI.updateUserRole(user);
|
APP.UI.updateUserRole(user);
|
||||||
|
|
||||||
|
updateRemoteThumbnailsVisibility();
|
||||||
});
|
});
|
||||||
room.on(ConferenceEvents.USER_LEFT, (id, user) => {
|
room.on(ConferenceEvents.USER_LEFT, (id, user) => {
|
||||||
APP.store.dispatch(participantLeft(id, user));
|
APP.store.dispatch(participantLeft(id, user));
|
||||||
|
@ -1293,6 +1295,8 @@ export default {
|
||||||
APP.API.notifyUserLeft(id);
|
APP.API.notifyUserLeft(id);
|
||||||
APP.UI.removeUser(id, user.getDisplayName());
|
APP.UI.removeUser(id, user.getDisplayName());
|
||||||
APP.UI.onSharedVideoStop(id);
|
APP.UI.onSharedVideoStop(id);
|
||||||
|
|
||||||
|
updateRemoteThumbnailsVisibility();
|
||||||
});
|
});
|
||||||
|
|
||||||
room.on(ConferenceEvents.USER_STATUS_CHANGED, (id, status) => {
|
room.on(ConferenceEvents.USER_STATUS_CHANGED, (id, status) => {
|
||||||
|
@ -1475,6 +1479,8 @@ export default {
|
||||||
reportError(e);
|
reportError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRemoteThumbnailsVisibility();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1811,6 +1817,8 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRemoteThumbnailsVisibility();
|
||||||
});
|
});
|
||||||
room.addCommandListener(
|
room.addCommandListener(
|
||||||
this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {
|
this.commands.defaults.SHARED_VIDEO, ({value, attributes}, id) => {
|
||||||
|
@ -1826,6 +1834,21 @@ export default {
|
||||||
APP.UI.onSharedVideoUpdate(id, value, attributes);
|
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.
|
* Adds any room listener.
|
||||||
|
|
|
@ -57,6 +57,9 @@ var config = { // eslint-disable-line no-unused-vars
|
||||||
webrtcIceTcpDisable: false,
|
webrtcIceTcpDisable: false,
|
||||||
|
|
||||||
openSctp: true, // Toggle to enable/disable SCTP channels
|
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,
|
disableStats: false,
|
||||||
disableAudioLevels: false,
|
disableAudioLevels: false,
|
||||||
channelLastN: -1, // The default value of the channel attribute last-n.
|
channelLastN: -1, // The default value of the channel attribute last-n.
|
||||||
|
|
|
@ -138,4 +138,13 @@
|
||||||
margin-bottom: auto;
|
margin-bottom: auto;
|
||||||
padding-right: $defaultToolbarSize;
|
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);
|
SideContainerToggler.init(eventEmitter);
|
||||||
Filmstrip.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);
|
VideoLayout.init(eventEmitter);
|
||||||
if (!interfaceConfig.filmStripOnly) {
|
if (!interfaceConfig.filmStripOnly) {
|
||||||
VideoLayout.initLargeVideo();
|
VideoLayout.initLargeVideo();
|
||||||
|
@ -1146,6 +1150,15 @@ UI.getLargeVideo = function () {
|
||||||
return VideoLayout.getLargeVideo();
|
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.
|
* Shows dialog with a link to FF extension.
|
||||||
*/
|
*/
|
||||||
|
@ -1396,6 +1409,23 @@ UI.isRingOverlayVisible = () => RingOverlay.isVisible();
|
||||||
*/
|
*/
|
||||||
UI.onUserFeaturesChanged = user => VideoLayout.onUserFeaturesChanged(user);
|
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([
|
const UIListeners = new Map([
|
||||||
[
|
[
|
||||||
UIEvents.ETHERPAD_CLICKED,
|
UIEvents.ETHERPAD_CLICKED,
|
||||||
|
|
|
@ -456,6 +456,9 @@ export default class SharedVideoManager {
|
||||||
// revert to original behavior (prevents pausing
|
// revert to original behavior (prevents pausing
|
||||||
// for participants not sharing the video to pause it)
|
// for participants not sharing the video to pause it)
|
||||||
$("#sharedVideo").css("pointer-events","auto");
|
$("#sharedVideo").css("pointer-events","auto");
|
||||||
|
|
||||||
|
this.emitter.emit(
|
||||||
|
UIEvents.UPDATE_SHARED_VIDEO, null, 'removed');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.url = null;
|
this.url = null;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $, APP, JitsiMeetJS, interfaceConfig */
|
/* global $, APP, config, JitsiMeetJS, interfaceConfig */
|
||||||
|
|
||||||
import UIEvents from "../../../service/UI/UIEvents";
|
import UIEvents from "../../../service/UI/UIEvents";
|
||||||
import UIUtil from "../util/UIUtil";
|
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.
|
* Initializes the filmstrip toolbar.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1133,6 +1133,15 @@ var VideoLayout = {
|
||||||
*/
|
*/
|
||||||
getLargeVideoWrapper() {
|
getLargeVideoWrapper() {
|
||||||
return this.getCurrentlyOnLargeContainer().$wrapper;
|
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