123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- // @flow
-
- import UIEvents from '../../../../service/UI/UIEvents';
-
- import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../../app';
- import {
- CONFERENCE_JOINED,
- CONFERENCE_LEFT
- } from '../conference';
- import { MiddlewareRegistry } from '../redux';
- import { playSound, registerSound, unregisterSound } from '../sounds';
-
- import {
- localParticipantIdChanged,
- participantUpdated
- } from './actions';
- import {
- DOMINANT_SPEAKER_CHANGED,
- KICK_PARTICIPANT,
- MUTE_REMOTE_PARTICIPANT,
- PARTICIPANT_DISPLAY_NAME_CHANGED,
- PARTICIPANT_JOINED,
- PARTICIPANT_LEFT,
- PARTICIPANT_UPDATED
- } from './actionTypes';
- import {
- LOCAL_PARTICIPANT_DEFAULT_ID,
- PARTICIPANT_JOINED_SOUND_ID,
- PARTICIPANT_LEFT_SOUND_ID
- } from './constants';
- import {
- getAvatarURLByParticipantId,
- getLocalParticipant,
- getParticipantById,
- getParticipantCount
- } from './functions';
- import {
- PARTICIPANT_JOINED_SRC,
- PARTICIPANT_LEFT_SRC
- } from './sounds';
-
- declare var APP: Object;
-
- /**
- * Middleware that captures CONFERENCE_JOINED and CONFERENCE_LEFT actions and
- * updates respectively ID of local participant.
- *
- * @param {Store} store - Redux store.
- * @returns {Function}
- */
- MiddlewareRegistry.register(store => next => action => {
- const { conference } = store.getState()['features/base/conference'];
-
- if (action.type === PARTICIPANT_JOINED
- || action.type === PARTICIPANT_LEFT) {
- _maybePlaySounds(store, action);
- }
-
- switch (action.type) {
- case APP_WILL_MOUNT:
- _registerSounds(store);
- break;
- case APP_WILL_UNMOUNT:
- _unregisterSounds(store);
- break;
- case CONFERENCE_JOINED:
- store.dispatch(localParticipantIdChanged(action.conference.myUserId()));
- break;
-
- case CONFERENCE_LEFT:
- store.dispatch(localParticipantIdChanged(LOCAL_PARTICIPANT_DEFAULT_ID));
- break;
-
- case DOMINANT_SPEAKER_CHANGED: {
- // Ensure the raised hand state is cleared for the dominant speaker.
- const participant = getLocalParticipant(store.getState());
-
- if (participant) {
- const local = participant.id === action.participant.id;
-
- store.dispatch(participantUpdated({
- id: action.participant.id,
- local,
- raisedHand: false
- }));
- }
-
- if (typeof APP === 'object') {
- APP.UI.markDominantSpeaker(action.participant.id);
- }
-
- break;
- }
-
- case KICK_PARTICIPANT:
- conference.kickParticipant(action.id);
- break;
-
- case MUTE_REMOTE_PARTICIPANT:
- conference.muteParticipant(action.id);
- break;
-
- // TODO Remove this middleware when the local display name update flow is
- // fully brought into redux.
- case PARTICIPANT_DISPLAY_NAME_CHANGED: {
- if (typeof APP !== 'undefined') {
- const participant = getLocalParticipant(store.getState());
-
- if (participant && participant.id === action.id) {
- APP.UI.emitEvent(UIEvents.NICKNAME_CHANGED, action.name);
- }
- }
-
- break;
- }
-
- case PARTICIPANT_JOINED:
- case PARTICIPANT_UPDATED: {
- const { participant } = action;
- const { id, local, raisedHand } = participant;
-
- // Send an external update of the local participant's raised hand state
- // if a new raised hand state is defined in the action.
- if (typeof raisedHand !== 'undefined') {
- if (local) {
- conference.setLocalParticipantProperty(
- 'raisedHand',
- raisedHand);
- }
-
- if (typeof APP === 'object') {
- if (local) {
- APP.UI.onLocalRaiseHandChanged(raisedHand);
- APP.UI.setLocalRaisedHandStatus(raisedHand);
- } else {
- const remoteParticipant
- = getParticipantById(store.getState(), id);
-
- remoteParticipant
- && APP.UI.setRaisedHandStatus(
- remoteParticipant.id,
- remoteParticipant.name,
- raisedHand);
- }
- }
- }
-
- // Notify external listeners of potential avatarURL changes.
- if (typeof APP === 'object') {
- const preUpdateAvatarURL
- = getAvatarURLByParticipantId(store.getState(), id);
-
- // Allow the redux update to go through and compare the old avatar
- // to the new avatar and emit out change events if necessary.
- const result = next(action);
-
- const postUpdateAvatarURL
- = getAvatarURLByParticipantId(store.getState(), id);
-
- if (preUpdateAvatarURL !== postUpdateAvatarURL) {
- const currentKnownId = local
- ? APP.conference.getMyUserId() : id;
-
- APP.UI.refreshAvatarDisplay(
- currentKnownId, postUpdateAvatarURL);
- APP.API.notifyAvatarChanged(
- currentKnownId, postUpdateAvatarURL);
- }
-
- return result;
- }
-
- break;
- }
- }
-
- return next(action);
- });
-
- /**
- * Plays sounds when participants join/leave conference.
- *
- * @param {Store} store - The Redux store.
- * @param {Action} action - The Redux action. Should be either
- * {@link PARTICIPANT_JOINED} or {@link PARTICIPANT_LEFT}.
- * @private
- * @returns {void}
- */
- function _maybePlaySounds({ getState, dispatch }, action) {
- const state = getState();
- const { startAudioMuted } = state['features/base/config'];
-
- // We're not playing sounds for local participant
- // nor when the user is joining past the "startAudioMuted" limit.
- // The intention there was to not play user joined notification in big
- // conferences where 100th person is joining.
- if (!action.participant.local
- && (!startAudioMuted
- || getParticipantCount(state) < startAudioMuted)) {
- if (action.type === PARTICIPANT_JOINED) {
- dispatch(playSound(PARTICIPANT_JOINED_SOUND_ID));
- } else if (action.type === PARTICIPANT_LEFT) {
- dispatch(playSound(PARTICIPANT_LEFT_SOUND_ID));
- }
- }
- }
-
- /**
- * Registers sounds related with the participants feature.
- *
- * @param {Store} store - The Redux store.
- * @private
- * @returns {void}
- */
- function _registerSounds({ dispatch }) {
- dispatch(
- registerSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_SRC));
- dispatch(
- registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_SRC));
- }
-
- /**
- * Unregisters sounds related with the participants feature.
- *
- * @param {Store} store - The Redux store.
- * @private
- * @returns {void}
- */
- function _unregisterSounds({ dispatch }) {
- dispatch(
- unregisterSound(PARTICIPANT_JOINED_SOUND_ID, PARTICIPANT_JOINED_SRC));
- dispatch(
- unregisterSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_SRC));
- }
|