fix(filmstrip) Make dominant speaker visible at all times (#11874)

* fix(filmstrip) Make dominant speaker visible at all times.

* squash: address review comments.
This commit is contained in:
Jaya Allamsetty 2022-07-20 15:51:47 -04:00 committed by GitHub
parent 5dbb17bc81
commit c727b603af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 12 deletions

View File

@ -46,6 +46,59 @@ const AVATAR_CHECKER_FUNCTIONS = [
];
/* eslint-enable arrow-body-style, no-unused-vars */
/**
* Returns the list of active speakers that should be moved to the top of the sorted list of participants so that the
* dominant speaker is visible always on the vertical filmstrip in stage layout.
*
* @param {Function | Object} stateful - The (whole) redux state, or redux's {@code getState} function to be used to
* retrieve the state.
* @returns {Array<string>}
*/
export function getActiveSpeakersToBeDisplayed(stateful: Object | Function) {
const state = toState(stateful);
const {
fakeParticipants,
sortedRemoteScreenshares,
sortedRemoteVirtualScreenshareParticipants,
speakersList
} = state['features/base/participants'];
const { visibleRemoteParticipants } = state['features/filmstrip'];
// Do not re-sort the active speakers if all of them are currently visible.
if (typeof visibleRemoteParticipants === 'undefined' || speakersList.size <= visibleRemoteParticipants.size) {
return speakersList;
}
const activeSpeakers = new Map(speakersList);
let availableSlotsForActiveSpeakers = visibleRemoteParticipants.size;
// Remove screenshares from the count.
if (getMultipleVideoSupportFeatureFlag(state)) {
if (sortedRemoteVirtualScreenshareParticipants) {
availableSlotsForActiveSpeakers -= sortedRemoteVirtualScreenshareParticipants.size * 2;
for (const screenshare of Array.from(sortedRemoteVirtualScreenshareParticipants.keys())) {
const ownerId = getVirtualScreenshareParticipantOwnerId(screenshare);
activeSpeakers.delete(ownerId);
}
}
} else if (sortedRemoteScreenshares) {
availableSlotsForActiveSpeakers -= sortedRemoteScreenshares.size;
for (const id of Array.from(sortedRemoteScreenshares.keys())) {
activeSpeakers.delete(id);
}
}
// Remove shared video from the count.
if (fakeParticipants) {
availableSlotsForActiveSpeakers -= fakeParticipants.size;
}
const truncatedSpeakersList = Array.from(activeSpeakers).slice(0, availableSlotsForActiveSpeakers);
truncatedSpeakersList.sort((a, b) => a[1].localeCompare(b[1]));
return new Map(truncatedSpeakersList);
}
/**
* Resolves the first loadable avatar URL for a participant.
*

View File

@ -1,7 +1,7 @@
// @flow
import { getSourceNameSignalingFeatureFlag } from '../base/config';
import { getVirtualScreenshareParticipantOwnerId } from '../base/participants';
import { getMultipleVideoSupportFeatureFlag } from '../base/config';
import { getActiveSpeakersToBeDisplayed, getVirtualScreenshareParticipantOwnerId } from '../base/participants';
import { setRemoteParticipants } from './actions';
import { isFilmstripScrollVisible } from './functions';
@ -34,42 +34,36 @@ export function updateRemoteParticipants(store: Object, participantId: ?number)
const {
fakeParticipants,
sortedRemoteParticipants,
sortedRemoteScreenshares,
speakersList
sortedRemoteScreenshares
} = state['features/base/participants'];
const remoteParticipants = new Map(sortedRemoteParticipants);
const screenShares = new Map(sortedRemoteScreenshares);
const screenShareParticipants = sortedRemoteVirtualScreenshareParticipants
? [ ...sortedRemoteVirtualScreenshareParticipants.keys() ] : [];
const sharedVideos = fakeParticipants ? Array.from(fakeParticipants.keys()) : [];
const speakers = new Map(speakersList);
const speakers = getActiveSpeakersToBeDisplayed(state);
if (getSourceNameSignalingFeatureFlag(state)) {
if (getMultipleVideoSupportFeatureFlag(state)) {
for (const screenshare of screenShareParticipants) {
const ownerId = getVirtualScreenshareParticipantOwnerId(screenshare);
remoteParticipants.delete(ownerId);
remoteParticipants.delete(screenshare);
speakers.delete(ownerId);
speakers.delete(screenshare);
}
} else {
for (const screenshare of screenShares.keys()) {
remoteParticipants.delete(screenshare);
speakers.delete(screenshare);
}
}
for (const sharedVideo of sharedVideos) {
remoteParticipants.delete(sharedVideo);
speakers.delete(sharedVideo);
}
for (const speaker of speakers.keys()) {
remoteParticipants.delete(speaker);
}
if (getSourceNameSignalingFeatureFlag(state)) {
if (getMultipleVideoSupportFeatureFlag(state)) {
// Always update the order of the thumnails.
const participantsWithScreenShare = screenShareParticipants.reduce((acc, screenshare) => {
const ownerId = getVirtualScreenshareParticipantOwnerId(screenshare);