diff --git a/config.js b/config.js index 45b064a68..1a13688b8 100644 --- a/config.js +++ b/config.js @@ -683,13 +683,38 @@ var config = { // userRegion: "asia" }, + // Array of disabled sounds. + // Possible values: + // - 'E2EE_OFF_SOUND' + // - 'E2EE_ON_SOUND' + // - 'INCOMING_MSG_SOUND' + // - 'KNOCKING_PARTICIPANT_SOUND' + // - 'LIVE_STREAMING_OFF_SOUND' + // - 'LIVE_STREAMING_ON_SOUND' + // - 'NO_AUDIO_SIGNAL_SOUND' + // - 'NOISY_AUDIO_INPUT_SOUND' + // - 'OUTGOING_CALL_EXPIRED_SOUND' + // - 'OUTGOING_CALL_REJECTED_SOUND' + // - 'OUTGOING_CALL_RINGING_SOUND' + // - 'OUTGOING_CALL_START_SOUND' + // - 'PARTICIPANT_JOINED_SOUND' + // - 'PARTICIPANT_LEFT_SOUND' + // - 'RAISE_HAND_SOUND' + // - 'RECORDING_OFF_SOUND' + // - 'RECORDING_ON_SOUND' + // - 'TALK_WHILE_MUTED_SOUND' + // disabledSounds: [], + + // DEPRECATED! Use `disabledSounds` instead. // Decides whether the start/stop recording audio notifications should play on record. // disableRecordAudioNotification: false, + // DEPRECATED! Use `disabledSounds` instead. // Disables the sounds that play when other participants join or leave the // conference (if set to true, these sounds will not be played). // disableJoinLeaveSounds: false, + // DEPRECATED! Use `disabledSounds` instead. // Disables the sounds that play when a chat message is received. // disableIncomingMessageSound: false, diff --git a/react/features/base/config/configWhitelist.js b/react/features/base/config/configWhitelist.js index 9a2a3ca78..7c9702653 100644 --- a/react/features/base/config/configWhitelist.js +++ b/react/features/base/config/configWhitelist.js @@ -84,6 +84,7 @@ export default [ 'disableAP', 'disableAudioLevels', 'disableDeepLinking', + 'disabledSounds', 'disableFilmstripAutohiding', 'disableInitialGUM', 'disableH264', diff --git a/react/features/base/config/reducer.js b/react/features/base/config/reducer.js index a7a77960c..d5baf419a 100644 --- a/react/features/base/config/reducer.js +++ b/react/features/base/config/reducer.js @@ -66,11 +66,11 @@ ReducerRegistry.register('features/base/config', (state = _getInitialState(), ac error: undefined, /** - * The URL of the location associated with/configured by this - * configuration. - * - * @type URL - */ + * The URL of the location associated with/configured by this + * configuration. + * + * @type URL + */ locationURL: action.locationURL }; @@ -84,11 +84,11 @@ ReducerRegistry.register('features/base/config', (state = _getInitialState(), ac if (state.locationURL === action.locationURL) { return { /** - * The {@link Error} which prevented the loading of the - * configuration of the associated {@code locationURL}. - * - * @type Error - */ + * The {@link Error} which prevented the loading of the + * configuration of the associated {@code locationURL}. + * + * @type Error + */ error: action.error }; } @@ -206,6 +206,25 @@ function _translateLegacyConfig(oldValue: Object) { }; } + newValue.disabledSounds = newValue.disabledSounds || []; + + if (oldValue.disableJoinLeaveSounds) { + newValue.disabledSounds.unshift('PARTICIPANT_LEFT_SOUND', 'PARTICIPANT_JOINED_SOUND'); + } + + if (oldValue.disableRecordAudioNotification) { + newValue.disabledSounds.unshift( + 'RECORDING_ON_SOUND', + 'RECORDING_OFF_SOUND', + 'LIVE_STREAMING_ON_SOUND', + 'LIVE_STREAMING_OFF_SOUND' + ); + } + + if (oldValue.disableIncomingMessageSound) { + newValue.disabledSounds.unshift('INCOMING_MSG_SOUND'); + } + if (oldValue.stereo || oldValue.opusMaxAverageBitrate) { newValue.audioQuality = { opusMaxAverageBitrate: oldValue.audioQuality?.opusMaxAverageBitrate ?? oldValue.opusMaxAverageBitrate, diff --git a/react/features/base/participants/middleware.js b/react/features/base/participants/middleware.js index 03a54832e..99ded632c 100644 --- a/react/features/base/participants/middleware.js +++ b/react/features/base/participants/middleware.js @@ -371,14 +371,9 @@ function _localParticipantLeft({ dispatch }, next, action) { */ function _maybePlaySounds({ getState, dispatch }, action) { const state = getState(); - const { startAudioMuted, disableJoinLeaveSounds } = state['features/base/config']; + const { startAudioMuted } = state['features/base/config']; const { soundsParticipantJoined: joinSound, soundsParticipantLeft: leftSound } = state['features/base/settings']; - // If we have join/leave sounds disabled, don't play anything. - if (disableJoinLeaveSounds) { - return; - } - // 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 diff --git a/react/features/base/sounds/actions.js b/react/features/base/sounds/actions.js index 997a4c4a9..bd9d9071e 100644 --- a/react/features/base/sounds/actions.js +++ b/react/features/base/sounds/actions.js @@ -11,6 +11,7 @@ import { UNREGISTER_SOUND } from './actionTypes'; import { getSoundsPath } from './functions'; +import { getDisabledSounds } from './functions.any'; /** * Adds {@link AudioElement} instance to the base/sounds feature state for the @@ -63,15 +64,18 @@ export function _removeAudioElement(soundId: string) { * * @param {string} soundId - The id of the sound to be played (the same one * which was used in {@link registerSound} to register the sound). - * @returns {{ - * type: PLAY_SOUND, - * soundId: string - * }} + * @returns {Function} */ export function playSound(soundId: string): Object { - return { - type: PLAY_SOUND, - soundId + return (dispatch: Function, getState: Function) => { + const disabledSounds = getDisabledSounds(getState()); + + if (!disabledSounds.includes(soundId)) { + dispatch({ + type: PLAY_SOUND, + soundId + }); + } }; } diff --git a/react/features/base/sounds/functions.any.js b/react/features/base/sounds/functions.any.js new file mode 100644 index 000000000..251fa3a84 --- /dev/null +++ b/react/features/base/sounds/functions.any.js @@ -0,0 +1,11 @@ +// @flow + +/** + * Selector for retrieving the disabled sounds array. + * + * @param {Object} state - The Redux state. + * @returns {Array} - The disabled sound id's array. + */ +export function getDisabledSounds(state: Object) { + return state['features/base/config'].disabledSounds || []; +} diff --git a/react/features/chat/middleware.js b/react/features/chat/middleware.js index b32f53db5..8e409147c 100644 --- a/react/features/chat/middleware.js +++ b/react/features/chat/middleware.js @@ -313,10 +313,10 @@ function _handleReceivedMessage({ dispatch, getState }, // Logic for all platforms: const state = getState(); const { isOpen: isChatOpen } = state['features/chat']; - const { disableIncomingMessageSound, iAmRecorder } = state['features/base/config']; + const { iAmRecorder } = state['features/base/config']; const { soundsIncomingMessage: soundEnabled } = state['features/base/settings']; - if (!disableIncomingMessageSound && soundEnabled && shouldPlaySound && !isChatOpen) { + if (soundEnabled && shouldPlaySound && !isChatOpen) { dispatch(playSound(INCOMING_MSG_SOUND_ID)); } diff --git a/react/features/invite/constants.js b/react/features/invite/constants.js index 32af28c33..6f06a9efb 100644 --- a/react/features/invite/constants.js +++ b/react/features/invite/constants.js @@ -17,7 +17,7 @@ export const DIAL_IN_SUMMARY_VIEW_ID = 'DIAL_IN_SUMMARY_VIEW_ID'; * @type {string} */ export const OUTGOING_CALL_EXPIRED_SOUND_ID - = 'OUTGOING_CALL_EXPIRED_SOUND_ID'; + = 'OUTGOING_CALL_EXPIRED_SOUND'; /** * The identifier of the sound to be played when the status of an outgoing call @@ -26,7 +26,7 @@ export const OUTGOING_CALL_EXPIRED_SOUND_ID * @type {string} */ export const OUTGOING_CALL_REJECTED_SOUND_ID - = 'OUTGOING_CALL_REJECTED_SOUND_ID'; + = 'OUTGOING_CALL_REJECTED_SOUND'; /** * The identifier of the sound to be played when the status of an outgoing call @@ -34,14 +34,14 @@ export const OUTGOING_CALL_REJECTED_SOUND_ID * * @type {string} */ -export const OUTGOING_CALL_RINGING_SOUND_ID = 'OUTGOING_CALL_RINGING_SOUND_ID'; +export const OUTGOING_CALL_RINGING_SOUND_ID = 'OUTGOING_CALL_RINGING_SOUND'; /** * The identifier of the sound to be played when outgoing call is started. * * @type {string} */ -export const OUTGOING_CALL_START_SOUND_ID = 'OUTGOING_CALL_START_SOUND_ID'; +export const OUTGOING_CALL_START_SOUND_ID = 'OUTGOING_CALL_START_SOUND'; /** * Regex for matching sip addresses. diff --git a/react/features/no-audio-signal/constants.js b/react/features/no-audio-signal/constants.js index dcab9e6e5..386cf4600 100644 --- a/react/features/no-audio-signal/constants.js +++ b/react/features/no-audio-signal/constants.js @@ -3,4 +3,4 @@ * * @type {string} */ -export const NO_AUDIO_SIGNAL_SOUND_ID = 'NO_AUDIO_SIGNAL_SOUND_ID'; +export const NO_AUDIO_SIGNAL_SOUND_ID = 'NO_AUDIO_SIGNAL_SOUND'; diff --git a/react/features/noise-detection/constants.js b/react/features/noise-detection/constants.js index 231300e86..2d827ce59 100644 --- a/react/features/noise-detection/constants.js +++ b/react/features/noise-detection/constants.js @@ -3,4 +3,4 @@ * * @type {string} */ -export const NOISY_AUDIO_INPUT_SOUND_ID = 'NOISY_AUDIO_INPUT_SOUND_ID'; +export const NOISY_AUDIO_INPUT_SOUND_ID = 'NOISY_AUDIO_INPUT_SOUND'; diff --git a/react/features/reactions/constants.js b/react/features/reactions/constants.js index 109159aeb..266dbdac9 100644 --- a/react/features/reactions/constants.js +++ b/react/features/reactions/constants.js @@ -68,7 +68,7 @@ export const SILENCE_SOUND_ID = 'SILENCE_SOUND_'; * * @type {string} */ -export const RAISE_HAND_SOUND_ID = 'RAISE_HAND_SOUND_ID'; +export const RAISE_HAND_SOUND_ID = 'RAISE_HAND_SOUND'; export type ReactionEmojiProps = { diff --git a/react/features/recording/middleware.js b/react/features/recording/middleware.js index 9ec0a6fb4..3970fa17c 100644 --- a/react/features/recording/middleware.js +++ b/react/features/recording/middleware.js @@ -135,7 +135,6 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { const { iAmRecorder, iAmSipGateway, - disableRecordAudioNotification, recordingLimit } = getState()['features/base/config']; @@ -165,10 +164,6 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { sendAnalytics(createRecordingEvent('start', mode)); - if (disableRecordAudioNotification) { - break; - } - let soundID; if (mode === JitsiRecordingConstants.mode.FILE) { @@ -200,10 +195,6 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { } sendAnalytics(createRecordingEvent('stop', mode, duration)); - if (disableRecordAudioNotification) { - break; - } - if (mode === JitsiRecordingConstants.mode.FILE) { soundOff = RECORDING_OFF_SOUND_ID; soundOn = RECORDING_ON_SOUND_ID; diff --git a/react/features/talk-while-muted/constants.js b/react/features/talk-while-muted/constants.js index 1f4d5b612..b54af126d 100644 --- a/react/features/talk-while-muted/constants.js +++ b/react/features/talk-while-muted/constants.js @@ -3,4 +3,4 @@ * * @type {string} */ -export const TALK_WHILE_MUTED_SOUND_ID = 'TALK_WHILE_MUTED_SOUND_ID'; +export const TALK_WHILE_MUTED_SOUND_ID = 'TALK_WHILE_MUTED_SOUND';