fix(follow-me) Make follow me work with stage filmstrip (#11306)
On follow me enabled all participants will see the participants pinned by the moderator Fix pinned indicator to work when stage filmstrip is disabled Fix add participant on dominant speaker change: if the participant was already pinned keep it as pinned Don’t add local participant on stage (on automatic selection)
This commit is contained in:
parent
ed9b85f287
commit
d7c8164b74
|
@ -5,7 +5,9 @@ import React from 'react';
|
|||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { IconPinParticipant } from '../../../base/icons';
|
||||
import { getParticipantById } from '../../../base/participants';
|
||||
import { BaseIndicator } from '../../../base/react';
|
||||
import { getPinnedActiveParticipants, isStageFilmstripEnabled } from '../../functions.web';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link PinnedIndicator}.
|
||||
|
@ -52,11 +54,12 @@ const PinnedIndicator = ({
|
|||
participantId,
|
||||
tooltipPosition
|
||||
}: Props) => {
|
||||
const isPinned = useSelector(state => state['features/filmstrip'].activeParticipants)
|
||||
.find(p => p.id === participantId && p.pinned);
|
||||
const stageFilmstrip = useSelector(isStageFilmstripEnabled);
|
||||
const pinned = useSelector(state => getParticipantById(state, participantId))?.pinned;
|
||||
const isPinned = useSelector(getPinnedActiveParticipants).find(p => p.participantId === participantId);
|
||||
const styles = useStyles();
|
||||
|
||||
if (!isPinned) {
|
||||
if ((stageFilmstrip && !isPinned) || (!stageFilmstrip && !pinned)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -670,6 +670,18 @@ export function getActiveParticipantsIds(state) {
|
|||
return activeParticipants.map(p => p.participantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids of the active participants.
|
||||
*
|
||||
* @param {Object} state - Redux state.
|
||||
* @returns {Array<string>}
|
||||
*/
|
||||
export function getPinnedActiveParticipants(state) {
|
||||
const { activeParticipants } = state['features/filmstrip'];
|
||||
|
||||
return activeParticipants.filter(p => p.pinned);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether or not the stage filmstrip should be displayed.
|
||||
*
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
updateRemoteParticipantsOnLeave
|
||||
} from './functions';
|
||||
import './subscriber';
|
||||
import { getActiveParticipantsIds, isStageFilmstripEnabled } from './functions.web';
|
||||
import { getActiveParticipantsIds, getPinnedActiveParticipants, isStageFilmstripEnabled } from './functions.web';
|
||||
|
||||
/**
|
||||
* Map of timers.
|
||||
|
@ -187,9 +187,16 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
const state = store.getState();
|
||||
const stageFilmstrip = isStageFilmstripEnabled(state);
|
||||
const currentLayout = getCurrentLayout(state);
|
||||
const local = getLocalParticipant(state);
|
||||
|
||||
if (id === local.id) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (stageFilmstrip && currentLayout === LAYOUTS.VERTICAL_FILMSTRIP_VIEW) {
|
||||
store.dispatch(addStageParticipant(id));
|
||||
const isPinned = getPinnedActiveParticipants(state).some(p => p.participantId === id);
|
||||
|
||||
store.dispatch(addStageParticipant(id, Boolean(isPinned)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
import { CONFERENCE_WILL_JOIN } from '../base/conference/actionTypes';
|
||||
import {
|
||||
getParticipantById,
|
||||
|
@ -9,6 +11,7 @@ import {
|
|||
} from '../base/participants';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { setFilmstripVisible } from '../filmstrip';
|
||||
import { addStageParticipant } from '../filmstrip/actions.web';
|
||||
import { setTileView } from '../video-layout';
|
||||
|
||||
import {
|
||||
|
@ -178,6 +181,14 @@ function _onFollowMeCommand(attributes = {}, id, store) {
|
|||
} else if (typeof idOfParticipantToPin === 'undefined' && pinnedParticipant) {
|
||||
store.dispatch(pinParticipant(null));
|
||||
}
|
||||
|
||||
if (attributes.pinnedStageParticipants !== undefined) {
|
||||
const stageParticipants = JSON.parse(attributes.pinnedStageParticipants);
|
||||
|
||||
if (!_.isEqual(stageParticipants, oldState.pinnedStageParticipants)) {
|
||||
stageParticipants.forEach(p => store.dispatch(addStageParticipant(p.participantId, true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
isLocalParticipantModerator
|
||||
} from '../base/participants';
|
||||
import { StateListenerRegistry } from '../base/redux';
|
||||
import { getPinnedActiveParticipants, isStageFilmstripEnabled } from '../filmstrip/functions.web';
|
||||
import { shouldDisplayTileView } from '../video-layout/functions';
|
||||
|
||||
import { FOLLOW_ME_COMMAND } from './constants';
|
||||
|
@ -51,6 +52,16 @@ StateListenerRegistry.register(
|
|||
/* selector */ state => state['features/filmstrip'].visible,
|
||||
/* listener */ _sendFollowMeCommand);
|
||||
|
||||
/**
|
||||
* Subscribes to changes to the stage filmstrip participants.
|
||||
*/
|
||||
StateListenerRegistry.register(
|
||||
/* selector */ getPinnedActiveParticipants,
|
||||
/* listener */ _sendFollowMeCommand,
|
||||
{
|
||||
deepEquals: true
|
||||
});
|
||||
|
||||
/**
|
||||
* Subscribes to changes to the tile view setting in the user interface of the
|
||||
* local participant.
|
||||
|
@ -68,10 +79,12 @@ StateListenerRegistry.register(
|
|||
*/
|
||||
function _getFollowMeState(state) {
|
||||
const pinnedParticipant = getPinnedParticipant(state);
|
||||
const stageFilmstrip = isStageFilmstripEnabled(state);
|
||||
|
||||
return {
|
||||
filmstripVisible: state['features/filmstrip'].visible,
|
||||
nextOnStage: pinnedParticipant && pinnedParticipant.id,
|
||||
nextOnStage: stageFilmstrip ? undefined : pinnedParticipant && pinnedParticipant.id,
|
||||
pinnedStageParticipants: stageFilmstrip ? JSON.stringify(getPinnedActiveParticipants(state)) : undefined,
|
||||
sharedDocumentVisible: state['features/etherpad'].editing,
|
||||
tileViewEnabled: shouldDisplayTileView(state)
|
||||
};
|
||||
|
|
|
@ -98,10 +98,11 @@ StateListenerRegistry.register(
|
|||
* Updates the receiver constraints when the stage participants change.
|
||||
*/
|
||||
StateListenerRegistry.register(
|
||||
state => getActiveParticipantsIds(state).sort()
|
||||
.join(),
|
||||
state => getActiveParticipantsIds(state).sort(),
|
||||
(_, store) => {
|
||||
_updateReceiverVideoConstraints(store);
|
||||
}, {
|
||||
deepEquals: true
|
||||
}
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue