2018-12-19 18:40:17 +00:00
|
|
|
// @flow
|
2021-02-26 21:26:09 +00:00
|
|
|
import { getLogger } from 'jitsi-meet-logger';
|
2020-02-24 12:47:37 +00:00
|
|
|
import type { Dispatch } from 'redux';
|
2018-12-19 18:40:17 +00:00
|
|
|
|
2020-05-20 10:57:03 +00:00
|
|
|
import UIEvents from '../../../service/UI/UIEvents';
|
2020-02-24 12:47:37 +00:00
|
|
|
import {
|
|
|
|
AUDIO_MUTE,
|
|
|
|
createRemoteMuteConfirmedEvent,
|
|
|
|
createToolbarEvent,
|
2021-02-24 21:45:07 +00:00
|
|
|
sendAnalytics,
|
|
|
|
VIDEO_MUTE
|
2020-02-24 12:47:37 +00:00
|
|
|
} from '../analytics';
|
2021-09-28 16:11:13 +00:00
|
|
|
import { rejectParticipantAudio, rejectParticipantVideo, showModeratedNotification } from '../av-moderation/actions';
|
2021-06-23 11:23:44 +00:00
|
|
|
import { shouldShowModeratedNotification } from '../av-moderation/functions';
|
2021-02-24 21:45:07 +00:00
|
|
|
import {
|
|
|
|
MEDIA_TYPE,
|
|
|
|
setAudioMuted,
|
|
|
|
setVideoMuted,
|
|
|
|
VIDEO_MUTISM_AUTHORITY
|
|
|
|
} from '../base/media';
|
2020-02-24 12:47:37 +00:00
|
|
|
import {
|
|
|
|
getLocalParticipant,
|
2021-07-09 12:36:19 +00:00
|
|
|
getRemoteParticipants,
|
2020-02-24 12:47:37 +00:00
|
|
|
muteRemoteParticipant
|
|
|
|
} from '../base/participants';
|
2021-09-22 12:11:43 +00:00
|
|
|
import { toggleScreensharing } from '../base/tracks';
|
2021-09-15 08:28:44 +00:00
|
|
|
import { isModerationNotificationDisplayed } from '../notifications';
|
2018-12-19 18:40:17 +00:00
|
|
|
|
2020-02-24 12:47:37 +00:00
|
|
|
declare var APP: Object;
|
|
|
|
|
2021-02-26 21:26:09 +00:00
|
|
|
const logger = getLogger(__filename);
|
|
|
|
|
2020-02-24 12:47:37 +00:00
|
|
|
/**
|
|
|
|
* Mutes the local participant.
|
|
|
|
*
|
|
|
|
* @param {boolean} enable - Whether to mute or unmute.
|
2021-02-24 21:45:07 +00:00
|
|
|
* @param {MEDIA_TYPE} mediaType - The type of the media channel to mute.
|
2021-09-24 07:53:41 +00:00
|
|
|
* @param {boolean} stopScreenSharing - Whether or not to stop the screensharing.
|
2020-02-24 12:47:37 +00:00
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2021-09-24 07:53:41 +00:00
|
|
|
export function muteLocal(enable: boolean, mediaType: MEDIA_TYPE, stopScreenSharing: boolean = false) {
|
2021-06-23 11:23:44 +00:00
|
|
|
return (dispatch: Dispatch<any>, getState: Function) => {
|
2021-02-24 21:45:07 +00:00
|
|
|
const isAudio = mediaType === MEDIA_TYPE.AUDIO;
|
|
|
|
|
|
|
|
if (!isAudio && mediaType !== MEDIA_TYPE.VIDEO) {
|
2021-02-26 21:26:09 +00:00
|
|
|
logger.error(`Unsupported media type: ${mediaType}`);
|
2021-02-24 21:45:07 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2021-06-23 11:23:44 +00:00
|
|
|
|
|
|
|
// check for A/V Moderation when trying to unmute
|
|
|
|
if (!enable && shouldShowModeratedNotification(MEDIA_TYPE.AUDIO, getState())) {
|
2021-09-15 08:28:44 +00:00
|
|
|
if (!isModerationNotificationDisplayed(MEDIA_TYPE.AUDIO, getState())) {
|
|
|
|
dispatch(showModeratedNotification(MEDIA_TYPE.AUDIO));
|
|
|
|
}
|
2021-06-23 11:23:44 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-09-24 07:53:41 +00:00
|
|
|
if (enable && stopScreenSharing) {
|
2021-09-22 12:11:43 +00:00
|
|
|
dispatch(toggleScreensharing(false, false, true));
|
|
|
|
}
|
|
|
|
|
2021-02-24 21:45:07 +00:00
|
|
|
sendAnalytics(createToolbarEvent(isAudio ? AUDIO_MUTE : VIDEO_MUTE, { enable }));
|
|
|
|
dispatch(isAudio ? setAudioMuted(enable, /* ensureTrack */ true)
|
|
|
|
: setVideoMuted(enable, mediaType, VIDEO_MUTISM_AUTHORITY.USER, /* ensureTrack */ true));
|
2020-02-24 12:47:37 +00:00
|
|
|
|
2021-04-16 09:43:34 +00:00
|
|
|
// FIXME: The old conference logic still relies on this event being emitted.
|
2020-02-24 12:47:37 +00:00
|
|
|
typeof APP === 'undefined'
|
2021-04-16 09:43:34 +00:00
|
|
|
|| APP.UI.emitEvent(isAudio ? UIEvents.AUDIO_MUTED : UIEvents.VIDEO_MUTED, enable);
|
2020-02-24 12:47:37 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mutes the remote participant with the given ID.
|
|
|
|
*
|
|
|
|
* @param {string} participantId - ID of the participant to mute.
|
2021-02-24 21:45:07 +00:00
|
|
|
* @param {MEDIA_TYPE} mediaType - The type of the media channel to mute.
|
2020-02-24 12:47:37 +00:00
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2021-02-24 21:45:07 +00:00
|
|
|
export function muteRemote(participantId: string, mediaType: MEDIA_TYPE) {
|
2020-02-24 12:47:37 +00:00
|
|
|
return (dispatch: Dispatch<any>) => {
|
2021-02-24 21:45:07 +00:00
|
|
|
if (mediaType !== MEDIA_TYPE.AUDIO && mediaType !== MEDIA_TYPE.VIDEO) {
|
2021-02-26 21:26:09 +00:00
|
|
|
logger.error(`Unsupported media type: ${mediaType}`);
|
2021-02-24 21:45:07 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sendAnalytics(createRemoteMuteConfirmedEvent(participantId, mediaType));
|
|
|
|
dispatch(muteRemoteParticipant(participantId, mediaType));
|
2020-02-24 12:47:37 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mutes all participants.
|
|
|
|
*
|
|
|
|
* @param {Array<string>} exclude - Array of participant IDs to not mute.
|
2021-02-24 21:45:07 +00:00
|
|
|
* @param {MEDIA_TYPE} mediaType - The media type to mute.
|
2020-02-24 12:47:37 +00:00
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2021-02-24 21:45:07 +00:00
|
|
|
export function muteAllParticipants(exclude: Array<string>, mediaType: MEDIA_TYPE) {
|
2020-02-24 12:47:37 +00:00
|
|
|
return (dispatch: Dispatch<any>, getState: Function) => {
|
|
|
|
const state = getState();
|
|
|
|
const localId = getLocalParticipant(state).id;
|
2021-07-09 12:36:19 +00:00
|
|
|
|
|
|
|
if (!exclude.includes(localId)) {
|
2021-09-24 07:53:41 +00:00
|
|
|
dispatch(muteLocal(true, mediaType, true));
|
2021-07-09 12:36:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getRemoteParticipants(state).forEach((p, id) => {
|
|
|
|
if (exclude.includes(id)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatch(muteRemote(id, mediaType));
|
2021-09-28 16:11:13 +00:00
|
|
|
if (mediaType === MEDIA_TYPE.AUDIO) {
|
|
|
|
dispatch(rejectParticipantAudio(id));
|
|
|
|
} else {
|
|
|
|
dispatch(rejectParticipantVideo(id));
|
|
|
|
}
|
2021-07-09 12:36:19 +00:00
|
|
|
});
|
2020-02-24 12:47:37 +00:00
|
|
|
};
|
|
|
|
}
|
2021-06-08 15:43:10 +00:00
|
|
|
|