diff --git a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx index 02ab96667c..3fd4455271 100644 --- a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx @@ -28,14 +28,29 @@ import { replaceableComponent } from "../../../../../utils/replaceableComponent" import SettingsFlag from '../../../elements/SettingsFlag'; import ErrorDialog from '../../../dialogs/ErrorDialog'; +const getDefaultDevice = (devices: Array>) => { + // Note we're looking for a device with deviceId 'default' but adding a device + // with deviceId == the empty string: this is because Chrome gives us a device + // with deviceId 'default', so we're looking for this, not the one we are adding. + if (!devices.some((i) => i.deviceId === 'default')) { + devices.unshift({ + deviceId: '', + label: _t('Default Device'), + }); + return ''; + } else { + return 'default'; + } +}; + interface IState extends Record { mediaDevices: IMediaDevices; } @replaceableComponent("views.settings.tabs.user.VoiceUserSettingsTab") export default class VoiceUserSettingsTab extends React.Component<{}, IState> { - constructor() { - super({}); + constructor(props: {}) { + super(props); this.state = { mediaDevices: null, @@ -103,25 +118,9 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> { } }; - private setAudioOutput = (e): void => { - MediaDeviceHandler.instance.setAudioOutput(e.target.value); - this.setState({ - [MediaDeviceKindEnum.AudioOutput]: e.target.value, - }); - }; - - private setAudioInput = (e): void => { - MediaDeviceHandler.instance.setAudioInput(e.target.value); - this.setState({ - [MediaDeviceKindEnum.AudioInput]: e.target.value, - }); - }; - - private setVideoInput = (e): void => { - MediaDeviceHandler.instance.setVideoInput(e.target.value); - this.setState({ - [MediaDeviceKindEnum.VideoInput]: e.target.value, - }); + private setDevice = (deviceId: string, kind: MediaDeviceKindEnum): void => { + MediaDeviceHandler.instance.setDevice(deviceId, kind); + this.setState({ [kind]: deviceId }); }; private changeWebRtcMethod = (p2p: boolean): void => { @@ -138,6 +137,23 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> { }); } + private renderDropdown(kind: MediaDeviceKindEnum, label: string): JSX.Element { + const devices = this.state.mediaDevices[kind].slice(0); + if (devices.length === 0) return null; + + const defaultDevice = getDefaultDevice(devices); + return ( + this.setDevice(e.target.value, kind)} + > + { this.renderDeviceOptions(devices, kind) } + + ); + } + render() { let requestButton = null; let speakerDropdown = null; @@ -153,71 +169,28 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> { ); } else if (this.state.mediaDevices) { - speakerDropdown =

{ _t('No Audio Outputs detected') }

; - microphoneDropdown =

{ _t('No Microphones detected') }

; - webcamDropdown =

{ _t('No Webcams detected') }

; - - const defaultOption = { - deviceId: '', - label: _t('Default Device'), - }; - const getDefaultDevice = (devices) => { - // Note we're looking for a device with deviceId 'default' but adding a device - // with deviceId == the empty string: this is because Chrome gives us a device - // with deviceId 'default', so we're looking for this, not the one we are adding. - if (!devices.some((i) => i.deviceId === 'default')) { - devices.unshift(defaultOption); - return ''; - } else { - return 'default'; - } - }; - - const audioOutputs = this.state.mediaDevices[MediaDeviceKindEnum.AudioOutput].slice(0); - if (audioOutputs.length > 0) { - const defaultDevice = getDefaultDevice(audioOutputs); - speakerDropdown = ( - - {this.renderDeviceOptions(audioOutputs, MediaDeviceKindEnum.AudioOutput)} - - ); - } - - const audioInputs = this.state.mediaDevices[MediaDeviceKindEnum.AudioInput].slice(0); - if (audioInputs.length > 0) { - const defaultDevice = getDefaultDevice(audioInputs); - microphoneDropdown = ( - - {this.renderDeviceOptions(audioInputs, MediaDeviceKindEnum.AudioInput)} - - ); - } - - const videoInputs = this.state.mediaDevices[MediaDeviceKindEnum.VideoInput].slice(0); - if (videoInputs.length > 0) { - const defaultDevice = getDefaultDevice(videoInputs); - webcamDropdown = ( - - {this.renderDeviceOptions(videoInputs, MediaDeviceKindEnum.VideoInput)} - - ); - } + speakerDropdown = ( + this.renderDropdown(MediaDeviceKindEnum.AudioOutput, _t("Audio Output")) || +

{ _t('No Audio Outputs detected') }

+ ); + microphoneDropdown = ( + this.renderDropdown(MediaDeviceKindEnum.AudioInput, _t("Microphone")) || +

{ _t('No Microphones detected') }

+ ); + webcamDropdown = ( + this.renderDropdown(MediaDeviceKindEnum.VideoInput, _t("Camera")) || +

{ _t('No Webcams detected') }

+ ); } return (
{_t("Voice & Video")}
- {requestButton} - {speakerDropdown} - {microphoneDropdown} - {webcamDropdown} + { requestButton } + { speakerDropdown } + { microphoneDropdown } + { webcamDropdown }