Files
jitsi-meet/react/features/device-selection/actions.web.ts
Hugo Lavernhe 1e15d9421b feat(settings) Add advanced audio settings checkboxes (#16316)
* Add checkboxes to toggle audio settings

* Sync checkboxes with audio mixer effect

* Add tooltips

* Move previewAudioTrack to redux

* Add translation

* Add audio settings state to redux

* Update docs

* Apply review comments

* Create local track with audio contraints when unmuting

* Refactor functions and naming

* Add enableAdvancedAudioSettings config

* Fix mobile imports

* Add tooltips content

* Update react/features/base/config/functions.any.ts

* Layout checkboxes in a two-column grid

* Fix web imports

* Sort translation alphabetically

* Separate audio mute implementation for mobile and web

* Apply review comments

* squash: Add imports for middleware.any

* squash: fix linter errors

* Remove tooltips

* Lint

* Refactored setting of audio constraints in createLocalTracksF with checks for feature flag and desktop

---------

Co-authored-by: Jaya Allamsetty <54324652+jallamsetty1@users.noreply.github.com>
Co-authored-by: Jaya Allamsetty <jaya.allamsetty@8x8.com>
2025-09-05 16:52:35 -04:00

123 lines
5.1 KiB
TypeScript

import { isEqual } from 'lodash-es';
import { createDeviceChangedEvent } from '../analytics/AnalyticsEvents';
import { sendAnalytics } from '../analytics/functions';
import { IStore } from '../app/types';
import {
setAudioInputDevice,
setVideoInputDevice
} from '../base/devices/actions';
import { getDeviceLabelById, setAudioOutputDeviceId } from '../base/devices/functions';
import { updateSettings } from '../base/settings/actions';
import { toggleUpdateAudioSettings } from '../base/tracks/actions.web';
import { getLocalJitsiAudioTrack } from '../base/tracks/functions.any';
import { toggleNoiseSuppression } from '../noise-suppression/actions';
import { setScreenshareFramerate } from '../screen-share/actions.web';
import { setAudioSettings } from '../settings/actions.web';
import { disposePreviewAudioTrack } from '../settings/functions.web';
import { getAudioDeviceSelectionDialogProps, getVideoDeviceSelectionDialogProps } from './functions';
import logger from './logger';
/**
* Submits the settings related to audio device selection.
*
* @param {Object} newState - The new settings.
* @param {boolean} isDisplayedOnWelcomePage - Indicates whether the device selection dialog is displayed on the
* welcome page or not.
* @returns {Function}
*/
export function submitAudioDeviceSelectionTab(newState: any, isDisplayedOnWelcomePage: boolean) {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const currentState = getAudioDeviceSelectionDialogProps(getState(), isDisplayedOnWelcomePage);
const isSelectedAudioInputIdChanged = newState.selectedAudioInputId
&& newState.selectedAudioInputId !== currentState.selectedAudioInputId;
if (isSelectedAudioInputIdChanged) {
dispatch(updateSettings({
userSelectedMicDeviceId: newState.selectedAudioInputId,
userSelectedMicDeviceLabel:
getDeviceLabelById(getState(), newState.selectedAudioInputId, 'audioInput')
}));
await disposePreviewAudioTrack(getState());
dispatch(setAudioSettings(newState.audioSettings));
dispatch(setAudioInputDevice(newState.selectedAudioInputId));
}
if (newState.selectedAudioOutputId
&& newState.selectedAudioOutputId
!== currentState.selectedAudioOutputId) {
sendAnalytics(createDeviceChangedEvent('audio', 'output'));
setAudioOutputDeviceId(
newState.selectedAudioOutputId,
dispatch,
true,
getDeviceLabelById(getState(), newState.selectedAudioOutputId, 'audioOutput'))
.then(() => logger.log('changed audio output device'))
.catch(err => {
logger.warn(
'Failed to change audio output device.',
'Default or previously set audio output device will',
' be used instead.',
err);
});
}
if (newState.noiseSuppressionEnabled !== currentState.noiseSuppressionEnabled) {
dispatch(toggleNoiseSuppression());
}
if (!isEqual(newState.audioSettings, currentState.audioSettings) && !isSelectedAudioInputIdChanged && !newState.noiseSuppressionEnabled) {
const state = getState();
const jitsiTrack = getLocalJitsiAudioTrack(state);
if (!jitsiTrack) {
logger.debug('No local audio track found');
dispatch(setAudioSettings(newState.audioSettings));
return;
}
await disposePreviewAudioTrack(getState());
dispatch(toggleUpdateAudioSettings(newState.audioSettings));
}
};
}
/**
* Submits the settings related to device selection.
*
* @param {Object} newState - The new settings.
* @param {boolean} isDisplayedOnWelcomePage - Indicates whether the device selection dialog is displayed on the
* welcome page or not.
* @returns {Function}
*/
export function submitVideoDeviceSelectionTab(newState: any, isDisplayedOnWelcomePage: boolean) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const currentState = getVideoDeviceSelectionDialogProps(getState(), isDisplayedOnWelcomePage);
if (newState.selectedVideoInputId && (newState.selectedVideoInputId !== currentState.selectedVideoInputId)) {
dispatch(updateSettings({
userSelectedCameraDeviceId: newState.selectedVideoInputId,
userSelectedCameraDeviceLabel:
getDeviceLabelById(getState(), newState.selectedVideoInputId, 'videoInput')
}));
dispatch(setVideoInputDevice(newState.selectedVideoInputId));
}
if (newState.localFlipX !== currentState.localFlipX) {
dispatch(updateSettings({
localFlipX: newState.localFlipX
}));
}
if (newState.currentFramerate !== currentState.currentFramerate) {
const frameRate = parseInt(newState.currentFramerate, 10);
dispatch(setScreenshareFramerate(frameRate));
}
};
}