fix(audio): review device selection in mobile endpoints
Mobile users have no way to change I/O devices after joining audio. The removal of the audio options chevron in mobile browsers was supposed to be replaced by something else - in this case, by the dedicated leave/join audio button. That didn't happen, leave/join audio button retained the old behavior. Review device selection in mobile endpoints via two UI/UX changes: - Restore the device selection chevron/icon in mobile endpoints - Override the leave/join button action in mobile endpoints so that it opens the device selection contextual menu, which also includes the "Leave audio" option. This retains the old behavior (leaving audio) while also providing an way for users to change devices mid-call in mobile browsers.
This commit is contained in:
parent
be96230894
commit
141c553b17
@ -109,18 +109,14 @@ class AudioControls extends PureComponent {
|
||||
inAudio,
|
||||
} = this.props;
|
||||
|
||||
const { isMobile } = deviceInfo;
|
||||
|
||||
let { enableDynamicAudioDeviceSelection } = Meteor.settings.public.app;
|
||||
|
||||
if (typeof enableDynamicAudioDeviceSelection === 'undefined') {
|
||||
enableDynamicAudioDeviceSelection = true;
|
||||
}
|
||||
|
||||
const _enableDynamicDeviceSelection = enableDynamicAudioDeviceSelection && !isMobile;
|
||||
|
||||
if (inAudio) {
|
||||
return this.renderButtonsAndStreamSelector(_enableDynamicDeviceSelection);
|
||||
return this.renderButtonsAndStreamSelector(enableDynamicAudioDeviceSelection);
|
||||
}
|
||||
|
||||
return this.renderJoinButton();
|
||||
|
@ -77,6 +77,7 @@ const propTypes = {
|
||||
disable: PropTypes.bool.isRequired,
|
||||
talking: PropTypes.bool,
|
||||
notify: PropTypes.func.isRequired,
|
||||
isMobile: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@ -95,7 +96,7 @@ class InputStreamLiveSelector extends Component {
|
||||
super(props);
|
||||
this.updateDeviceList = this.updateDeviceList.bind(this);
|
||||
this.renderDeviceList = this.renderDeviceList.bind(this);
|
||||
this.renderListenOnlyButton = this.renderListenOnlyButton.bind(this);
|
||||
this.renderAudioButton = this.renderAudioButton.bind(this);
|
||||
this.renderMuteToggleButton = this.renderMuteToggleButton.bind(this);
|
||||
this.renderButtonsWithSelectorDevice = this.renderButtonsWithSelectorDevice.bind(this);
|
||||
this.renderButtonsWithoutSelectorDevice = this.renderButtonsWithoutSelectorDevice.bind(this);
|
||||
@ -345,18 +346,23 @@ class InputStreamLiveSelector extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderListenOnlyButton() {
|
||||
renderAudioButton() {
|
||||
const {
|
||||
handleLeaveAudio,
|
||||
intl,
|
||||
shortcuts,
|
||||
isListenOnly,
|
||||
_enableDynamicDeviceSelection,
|
||||
isMobile,
|
||||
} = this.props;
|
||||
|
||||
const actAsSelectorTrigger = _enableDynamicDeviceSelection && isMobile;
|
||||
return (
|
||||
<Button
|
||||
aria-label={intl.formatMessage(intlMessages.leaveAudio)}
|
||||
label={intl.formatMessage(intlMessages.leaveAudio)}
|
||||
label={actAsSelectorTrigger
|
||||
? intl.formatMessage(intlMessages.changeAudioDevice)
|
||||
: intl.formatMessage(intlMessages.leaveAudio)}
|
||||
accessKey={shortcuts.leaveaudio}
|
||||
data-test="leaveListenOnly"
|
||||
hideLabel
|
||||
@ -364,7 +370,9 @@ class InputStreamLiveSelector extends Component {
|
||||
icon={isListenOnly ? 'listen' : 'volume_level_2'}
|
||||
size="lg"
|
||||
circle
|
||||
onClick={(e) => {
|
||||
onClick={actAsSelectorTrigger
|
||||
? () => null
|
||||
: (e) => {
|
||||
e.stopPropagation();
|
||||
handleLeaveAudio();
|
||||
}}
|
||||
@ -372,6 +380,26 @@ class InputStreamLiveSelector extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderMenuTrigger() {
|
||||
const { intl, isMobile, isListenOnly } = this.props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isListenOnly && !isMobile
|
||||
? this.renderMuteToggleButton()
|
||||
: this.renderAudioButton()}
|
||||
<Styled.AudioDropdown
|
||||
data-test="audioDropdownMenu"
|
||||
emoji="device_list_selector"
|
||||
label={intl.formatMessage(intlMessages.changeAudioDevice)}
|
||||
hideLabel
|
||||
tabIndex={0}
|
||||
rotate
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
renderButtonsWithSelectorDevice() {
|
||||
const {
|
||||
audioInputDevices,
|
||||
@ -433,23 +461,10 @@ class InputStreamLiveSelector extends Component {
|
||||
aria-hidden="true"
|
||||
/>
|
||||
) : null}
|
||||
{(!isListenOnly && isMobile) && this.renderMuteToggleButton()}
|
||||
<BBBMenu
|
||||
customStyles={!isMobile ? customStyles : null}
|
||||
trigger={(
|
||||
<>
|
||||
{isListenOnly
|
||||
? this.renderListenOnlyButton()
|
||||
: this.renderMuteToggleButton()}
|
||||
<Styled.AudioDropdown
|
||||
data-test="audioDropdownMenu"
|
||||
emoji="device_list_selector"
|
||||
label={intl.formatMessage(intlMessages.changeAudioDevice)}
|
||||
hideLabel
|
||||
tabIndex={0}
|
||||
rotate
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
trigger={this.renderMenuTrigger()}
|
||||
actions={dropdownListComplete}
|
||||
opts={{
|
||||
id: 'audio-selector-dropdown-menu',
|
||||
@ -469,11 +484,11 @@ class InputStreamLiveSelector extends Component {
|
||||
renderButtonsWithoutSelectorDevice() {
|
||||
const { isListenOnly } = this.props;
|
||||
return isListenOnly
|
||||
? this.renderListenOnlyButton()
|
||||
? this.renderAudioButton()
|
||||
: (
|
||||
<>
|
||||
{this.renderMuteToggleButton()}
|
||||
{this.renderListenOnlyButton()}
|
||||
{this.renderAudioButton()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user