mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-05-14 17:57:49 +00:00
On Android the files will be copied to the assets/sounds directory of the SDK bundle on build time. To play the "asset:/" prefix has to be used to locate the files correctly. On iOS each sound file must be added to the SDK's Xcode project in order to be bundled correctly. To playback we need to know the path of the SDK bundle which is now exposed by the AppInfo iOS module.
232 lines
6.8 KiB
JavaScript
232 lines
6.8 KiB
JavaScript
// @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_FILE, PARTICIPANT_LEFT_FILE } 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_FILE));
|
|
dispatch(
|
|
registerSound(PARTICIPANT_LEFT_SOUND_ID, PARTICIPANT_LEFT_FILE));
|
|
}
|
|
|
|
/**
|
|
* 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));
|
|
dispatch(
|
|
unregisterSound(PARTICIPANT_LEFT_SOUND_ID));
|
|
}
|