Up until now we relied on implicit loading of middlewares and reducers, through having imports in each feature's index.js. This leads to many complex import cycles which result in (sometimes) hard to fix bugs in addition to (often) breaking mobile because a web-only feature gets imported on mobile too, thanks to the implicit loading. This PR changes that to make the process explicit. Both middlewares and reducers are imported in a single place, the app entrypoint. They have been divided into 3 categories: any, web and native, which represent each of the platforms respectively. Ideally no feature should have an index.js exporting actions, action types and components, but that's a larger ordeal, so this is just the first step in getting there. In order to both set example and avoid large cycles the app feature has been refactored to not have an idex.js itself.
78 lines
2.3 KiB
JavaScript
78 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';
|
|
|
|
import './subscriber';
|
|
|
|
/**
|
|
* 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;
|
|
});
|