113 lines
3.3 KiB
JavaScript
113 lines
3.3 KiB
JavaScript
import {
|
|
getLocalParticipant,
|
|
getParticipantById,
|
|
PIN_PARTICIPANT
|
|
} from '../participants';
|
|
import { MiddlewareRegistry } from '../redux';
|
|
import {
|
|
TRACK_ADDED,
|
|
TRACK_REMOVED
|
|
} from '../tracks';
|
|
|
|
import {
|
|
_addLocalTracksToConference,
|
|
_handleParticipantError,
|
|
_removeLocalTracksFromConference
|
|
} from './functions';
|
|
|
|
/**
|
|
* This middleware intercepts TRACK_ADDED and TRACK_REMOVED actions to sync
|
|
* conference's local tracks with local tracks in state. Also captures
|
|
* PIN_PARTICIPANT action to pin participant in conference.
|
|
*
|
|
* @param {Store} store - Redux store.
|
|
* @returns {Function}
|
|
*/
|
|
MiddlewareRegistry.register(store => next => action => {
|
|
switch (action.type) {
|
|
case PIN_PARTICIPANT:
|
|
pinParticipant(store, action.participant.id);
|
|
break;
|
|
|
|
case TRACK_ADDED:
|
|
case TRACK_REMOVED: {
|
|
const track = action.track;
|
|
|
|
if (track && track.local) {
|
|
return syncConferenceLocalTracksWithState(store, action)
|
|
.then(() => next(action));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return next(action);
|
|
});
|
|
|
|
/**
|
|
* Pins remote participant in conference, ignores local participant.
|
|
*
|
|
* @param {Store} store - Redux store.
|
|
* @param {string|null} id - Participant id or null if no one is currently
|
|
* pinned.
|
|
* @returns {void}
|
|
*/
|
|
function pinParticipant(store, id) {
|
|
const state = store.getState();
|
|
const participants = state['features/base/participants'];
|
|
const participantById = getParticipantById(participants, id);
|
|
let pin;
|
|
|
|
// The following condition prevents signaling to pin local participant. The
|
|
// logic is:
|
|
// - If we have an ID, we check if the participant identified by that ID is
|
|
// local.
|
|
// - If we don't have an ID (i.e. no participant identified by an ID), we
|
|
// check for local participant. If she's currently pinned, then this
|
|
// action will unpin her and that's why we won't signal here too.
|
|
if (participantById) {
|
|
pin = !participantById.local;
|
|
} else {
|
|
const localParticipant = getLocalParticipant(participants);
|
|
|
|
pin = !localParticipant || !localParticipant.pinned;
|
|
}
|
|
if (pin) {
|
|
const conference = state['features/base/conference'].jitsiConference;
|
|
|
|
try {
|
|
conference.pinParticipant(id);
|
|
} catch (err) {
|
|
_handleParticipantError(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Syncs local tracks from state with local tracks in JitsiConference instance.
|
|
*
|
|
* @param {Store} store - Redux store.
|
|
* @param {Object} action - Action object.
|
|
* @returns {Promise}
|
|
*/
|
|
function syncConferenceLocalTracksWithState(store, action) {
|
|
const conferenceState = store.getState()['features/base/conference'];
|
|
const conference = conferenceState.jitsiConference;
|
|
const leavingConference = conferenceState.leavingJitsiConference;
|
|
let promise;
|
|
|
|
// XXX The conference in state might be already in 'leaving' state, that's
|
|
// why we should not add/remove local tracks to such conference.
|
|
if (conference && conference !== leavingConference) {
|
|
const track = action.track.jitsiTrack;
|
|
|
|
if (action.type === TRACK_ADDED) {
|
|
promise = _addLocalTracksToConference(conference, [ track ]);
|
|
} else {
|
|
promise = _removeLocalTracksFromConference(conference, [ track ]);
|
|
}
|
|
}
|
|
|
|
return promise || Promise.resolve();
|
|
}
|