virtuacoplenny afd2aea79c ref(large-video): combine selectParticipant logic from web (#3266)
* ref(large-video): combine selectParticipant logic from web

Currently native/middleware/redux has its own logic for selecting a participant
on the bridge. To have the logic web respect that logic, a few changes are
needed.
- Web no longer has its own call to selectParticipant.
- To keep in line with web logic selectParticipant action should act even when
  there is no track. This makes it so that when a participant does get a track
  that the bridge will send high quality. The bridge can already handle when the
  selected participant does not have a video track.
- The timing of web is such that on joining an existing conference, a
  participant joins and the participant's tracks get updated and then the
  conference is joined. The result is selectParticipant does not get fired
  because it no-ops when there is no conference. To avoid having to make
  uncertain changes (to be lazy), update the selected participant on conference
  join as well.

* squash: update comment, pass message to error handler
2018-07-20 13:19:26 -05:00

77 lines
2.3 KiB
JavaScript

// @flow
import { CONFERENCE_JOINED } from '../base/conference';
import {
DOMINANT_SPEAKER_CHANGED,
PARTICIPANT_JOINED,
PARTICIPANT_LEFT,
PIN_PARTICIPANT,
getLocalParticipant
} from '../base/participants';
import { MiddlewareRegistry } from '../base/redux';
import {
getTrackByJitsiTrack,
TRACK_ADDED,
TRACK_REMOVED,
TRACK_UPDATED
} from '../base/tracks';
import { selectParticipant, selectParticipantInLargeVideo } from './actions';
/**
* Middleware that catches actions related to participants and tracks and
* dispatches an action to select a participant depicted by LargeVideo.
*
* @param {Store} store - Redux store.
* @returns {Function}
*/
MiddlewareRegistry.register(store => next => action => {
const result = next(action);
switch (action.type) {
case DOMINANT_SPEAKER_CHANGED: {
const localParticipant = getLocalParticipant(store.getState());
if (localParticipant && localParticipant.id !== action.participant.id) {
store.dispatch(selectParticipantInLargeVideo());
}
break;
}
case PARTICIPANT_JOINED:
case PARTICIPANT_LEFT:
case PIN_PARTICIPANT:
case TRACK_ADDED:
case TRACK_REMOVED:
store.dispatch(selectParticipantInLargeVideo());
break;
case CONFERENCE_JOINED:
// Ensure a participant is selected on conference join. This addresses
// the case where video tracks were received before CONFERENCE_JOINED
// fired; without the conference selection may not happen.
store.dispatch(selectParticipant());
break;
case TRACK_UPDATED:
// In order to minimize re-calculations, we need to select participant
// only if the videoType of the current participant rendered in
// LargeVideo has changed.
if ('videoType' in action.track) {
const state = store.getState();
const track
= getTrackByJitsiTrack(
state['features/base/tracks'],
action.track.jitsiTrack);
const participantId = state['features/large-video'].participantId;
(track.participantId === participantId)
&& store.dispatch(selectParticipant());
}
break;
}
return result;
});