fix(device-selection): Handle properly on prejoin

The device selection initialization on the prejoin use case was handled
like the welcome page. This was introducing issues with selecting the
stored devices and not the ones used, enabling the device selection when
it will fail and others.
This commit is contained in:
Hristo Terezov 2022-05-24 14:04:21 -05:00
parent 7e942173aa
commit ae565aaac6
6 changed files with 44 additions and 19 deletions

View File

@ -14,11 +14,13 @@ import logger from './logger';
* 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 submitDeviceSelectionTab(newState) {
export function submitDeviceSelectionTab(newState, isDisplayedOnWelcomePage) {
return (dispatch, getState) => {
const currentState = getDeviceSelectionDialogProps(getState());
const currentState = getDeviceSelectionDialogProps(getState(), isDisplayedOnWelcomePage);
if (newState.selectedVideoInputId && (newState.selectedVideoInputId !== currentState.selectedVideoInputId)) {
dispatch(updateSettings({

View File

@ -27,23 +27,28 @@ import {
*
* @param {(Function|Object)} stateful -The (whole) redux state, or redux's
* {@code getState} function to be used to retrieve the state.
* @param {boolean} isDisplayedOnWelcomePage - Indicates whether the device selection dialog is displayed on the
* welcome page or not.
* @returns {Object} - The properties for the device selection dialog.
*/
export function getDeviceSelectionDialogProps(stateful: Object | Function) {
export function getDeviceSelectionDialogProps(stateful: Object | Function, isDisplayedOnWelcomePage) {
// On mobile Safari because of https://bugs.webkit.org/show_bug.cgi?id=179363#c30, the old track is stopped
// by the browser when a new track is created for preview. That's why we are disabling all previews.
const disablePreviews = isIosMobileBrowser();
const state = toState(stateful);
const settings = state['features/base/settings'];
const { conference } = state['features/base/conference'];
const { permissions } = state['features/base/devices'];
const cameraChangeSupported = JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('input');
const inputDeviceChangeSupported = JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('input');
const speakerChangeSupported = JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('output');
const userSelectedCamera = getUserSelectedCameraDeviceId(state);
const userSelectedMic = getUserSelectedMicDeviceId(state);
let disableAudioInputChange = !JitsiMeetJS.mediaDevices.isMultipleAudioInputSupported();
let disableVideoInputSelect = !cameraChangeSupported;
// When the previews are disabled we don't need multiple audio input support in order to chage the mic. This is the
// case for Safari on iOS.
let disableAudioInputChange
= !JitsiMeetJS.mediaDevices.isMultipleAudioInputSupported() && !(disablePreviews && inputDeviceChangeSupported);
let disableVideoInputSelect = !inputDeviceChangeSupported;
let selectedAudioInputId = settings.micDeviceId;
let selectedAudioOutputId = getAudioOutputDeviceId();
let selectedVideoInputId = settings.cameraDeviceId;
@ -52,7 +57,7 @@ export function getDeviceSelectionDialogProps(stateful: Object | Function) {
// conference and this is not supported, when we open device selection on
// welcome page changing input devices will not be a problem
// on welcome page we also show only what we have saved as user selected devices
if (!conference) {
if (isDisplayedOnWelcomePage) {
disableAudioInputChange = false;
disableVideoInputSelect = false;
selectedAudioInputId = userSelectedMic;
@ -72,7 +77,7 @@ export function getDeviceSelectionDialogProps(stateful: Object | Function) {
hideAudioInputPreview: disableAudioInputChange || !JitsiMeetJS.isCollectingLocalStats() || disablePreviews,
hideAudioOutputPreview: !speakerChangeSupported || disablePreviews,
hideAudioOutputSelect: !speakerChangeSupported,
hideVideoInputPreview: !cameraChangeSupported || disablePreviews,
hideVideoInputPreview: !inputDeviceChangeSupported || disablePreviews,
selectedAudioInputId,
selectedAudioOutputId,
selectedVideoInputId

View File

@ -43,10 +43,15 @@ export function openLogoutDialog(onLogout: Function) {
*
* @param {string} defaultTab - The tab in {@code SettingsDialog} that should be
* displayed initially.
* @param {boolean} isDisplayedOnWelcomePage - Indicates whether the device selection dialog is displayed on the
* welcome page or not.
* @returns {Function}
*/
export function openSettingsDialog(defaultTab: string) {
return openDialog(SettingsDialog, { defaultTab });
export function openSettingsDialog(defaultTab: string, isDisplayedOnWelcomePage: boolean) {
return openDialog(SettingsDialog, {
defaultTab,
isDisplayedOnWelcomePage
});
}
/**

View File

@ -21,7 +21,13 @@ type Props = AbstractButtonProps & {
/**
* The redux {@code dispatch} function.
*/
dispatch: Function
dispatch: Function,
/**
* Indicates whether the device selection dialog is displayed on the
* welcome page or not.
*/
isDisplayedOnWelcomePage: boolean
};
/**
@ -40,10 +46,10 @@ class SettingsButton extends AbstractButton<Props, *> {
* @returns {void}
*/
_handleClick() {
const { defaultTab = SETTINGS_TABS.DEVICES, dispatch } = this.props;
const { defaultTab = SETTINGS_TABS.DEVICES, dispatch, isDisplayedOnWelcomePage = false } = this.props;
sendAnalytics(createToolbarEvent('settings'));
dispatch(openSettingsDialog(defaultTab));
dispatch(openSettingsDialog(defaultTab, isDisplayedOnWelcomePage));
}
}

View File

@ -59,7 +59,13 @@ type Props = {
/**
* Invoked to save changed settings.
*/
dispatch: Function
dispatch: Function,
/**
* Indicates whether the device selection dialog is displayed on the
* welcome page or not.
*/
isDisplayedOnWelcomePage: boolean
};
/**
@ -253,7 +259,7 @@ class SettingsDialog extends Component<Props> {
* }}
*/
function _mapStateToProps(state, ownProps) {
const { classes } = ownProps;
const { classes, isDisplayedOnWelcomePage } = ownProps;
const configuredTabs = interfaceConfig.SETTINGS_SECTIONS || [];
// The settings sections to display.
@ -276,7 +282,7 @@ function _mapStateToProps(state, ownProps) {
component: DeviceSelection,
label: 'settings.devices',
onMount: getAvailableDevices,
props: getDeviceSelectionDialogProps(state),
props: getDeviceSelectionDialogProps(state, isDisplayedOnWelcomePage),
propsUpdateFunction: (tabState, newProps) => {
// Ensure the device selection tab gets updated when new devices
// are found by taking the new props and only preserving the
@ -292,7 +298,7 @@ function _mapStateToProps(state, ownProps) {
};
},
styles: `settings-pane ${classes.settingsDialog} devices-pane`,
submit: submitDeviceSelectionTab
submit: newState => submitDeviceSelectionTab(newState, isDisplayedOnWelcomePage)
});
}

View File

@ -191,7 +191,8 @@ class WelcomePage extends AbstractWelcomePage {
<div className = 'header'>
<div className = 'welcome-page-settings'>
<SettingsButton
defaultTab = { SETTINGS_TABS.CALENDAR } />
defaultTab = { SETTINGS_TABS.CALENDAR }
isDisplayedOnWelcomePage = { true } />
{ showAdditionalToolbarContent
? <div
className = 'settings-toolbar-content'