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:
parent
7e942173aa
commit
ae565aaac6
|
@ -14,11 +14,13 @@ import logger from './logger';
|
||||||
* Submits the settings related to device selection.
|
* Submits the settings related to device selection.
|
||||||
*
|
*
|
||||||
* @param {Object} newState - The new settings.
|
* @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}
|
* @returns {Function}
|
||||||
*/
|
*/
|
||||||
export function submitDeviceSelectionTab(newState) {
|
export function submitDeviceSelectionTab(newState, isDisplayedOnWelcomePage) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const currentState = getDeviceSelectionDialogProps(getState());
|
const currentState = getDeviceSelectionDialogProps(getState(), isDisplayedOnWelcomePage);
|
||||||
|
|
||||||
if (newState.selectedVideoInputId && (newState.selectedVideoInputId !== currentState.selectedVideoInputId)) {
|
if (newState.selectedVideoInputId && (newState.selectedVideoInputId !== currentState.selectedVideoInputId)) {
|
||||||
dispatch(updateSettings({
|
dispatch(updateSettings({
|
||||||
|
|
|
@ -27,23 +27,28 @@ import {
|
||||||
*
|
*
|
||||||
* @param {(Function|Object)} stateful -The (whole) redux state, or redux's
|
* @param {(Function|Object)} stateful -The (whole) redux state, or redux's
|
||||||
* {@code getState} function to be used to retrieve the state.
|
* {@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.
|
* @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
|
// 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.
|
// by the browser when a new track is created for preview. That's why we are disabling all previews.
|
||||||
const disablePreviews = isIosMobileBrowser();
|
const disablePreviews = isIosMobileBrowser();
|
||||||
|
|
||||||
const state = toState(stateful);
|
const state = toState(stateful);
|
||||||
const settings = state['features/base/settings'];
|
const settings = state['features/base/settings'];
|
||||||
const { conference } = state['features/base/conference'];
|
|
||||||
const { permissions } = state['features/base/devices'];
|
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 speakerChangeSupported = JitsiMeetJS.mediaDevices.isDeviceChangeAvailable('output');
|
||||||
const userSelectedCamera = getUserSelectedCameraDeviceId(state);
|
const userSelectedCamera = getUserSelectedCameraDeviceId(state);
|
||||||
const userSelectedMic = getUserSelectedMicDeviceId(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 selectedAudioInputId = settings.micDeviceId;
|
||||||
let selectedAudioOutputId = getAudioOutputDeviceId();
|
let selectedAudioOutputId = getAudioOutputDeviceId();
|
||||||
let selectedVideoInputId = settings.cameraDeviceId;
|
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
|
// conference and this is not supported, when we open device selection on
|
||||||
// welcome page changing input devices will not be a problem
|
// 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
|
// on welcome page we also show only what we have saved as user selected devices
|
||||||
if (!conference) {
|
if (isDisplayedOnWelcomePage) {
|
||||||
disableAudioInputChange = false;
|
disableAudioInputChange = false;
|
||||||
disableVideoInputSelect = false;
|
disableVideoInputSelect = false;
|
||||||
selectedAudioInputId = userSelectedMic;
|
selectedAudioInputId = userSelectedMic;
|
||||||
|
@ -72,7 +77,7 @@ export function getDeviceSelectionDialogProps(stateful: Object | Function) {
|
||||||
hideAudioInputPreview: disableAudioInputChange || !JitsiMeetJS.isCollectingLocalStats() || disablePreviews,
|
hideAudioInputPreview: disableAudioInputChange || !JitsiMeetJS.isCollectingLocalStats() || disablePreviews,
|
||||||
hideAudioOutputPreview: !speakerChangeSupported || disablePreviews,
|
hideAudioOutputPreview: !speakerChangeSupported || disablePreviews,
|
||||||
hideAudioOutputSelect: !speakerChangeSupported,
|
hideAudioOutputSelect: !speakerChangeSupported,
|
||||||
hideVideoInputPreview: !cameraChangeSupported || disablePreviews,
|
hideVideoInputPreview: !inputDeviceChangeSupported || disablePreviews,
|
||||||
selectedAudioInputId,
|
selectedAudioInputId,
|
||||||
selectedAudioOutputId,
|
selectedAudioOutputId,
|
||||||
selectedVideoInputId
|
selectedVideoInputId
|
||||||
|
|
|
@ -43,10 +43,15 @@ export function openLogoutDialog(onLogout: Function) {
|
||||||
*
|
*
|
||||||
* @param {string} defaultTab - The tab in {@code SettingsDialog} that should be
|
* @param {string} defaultTab - The tab in {@code SettingsDialog} that should be
|
||||||
* displayed initially.
|
* displayed initially.
|
||||||
|
* @param {boolean} isDisplayedOnWelcomePage - Indicates whether the device selection dialog is displayed on the
|
||||||
|
* welcome page or not.
|
||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
*/
|
*/
|
||||||
export function openSettingsDialog(defaultTab: string) {
|
export function openSettingsDialog(defaultTab: string, isDisplayedOnWelcomePage: boolean) {
|
||||||
return openDialog(SettingsDialog, { defaultTab });
|
return openDialog(SettingsDialog, {
|
||||||
|
defaultTab,
|
||||||
|
isDisplayedOnWelcomePage
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,7 +21,13 @@ type Props = AbstractButtonProps & {
|
||||||
/**
|
/**
|
||||||
* The redux {@code dispatch} function.
|
* 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}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
_handleClick() {
|
_handleClick() {
|
||||||
const { defaultTab = SETTINGS_TABS.DEVICES, dispatch } = this.props;
|
const { defaultTab = SETTINGS_TABS.DEVICES, dispatch, isDisplayedOnWelcomePage = false } = this.props;
|
||||||
|
|
||||||
sendAnalytics(createToolbarEvent('settings'));
|
sendAnalytics(createToolbarEvent('settings'));
|
||||||
dispatch(openSettingsDialog(defaultTab));
|
dispatch(openSettingsDialog(defaultTab, isDisplayedOnWelcomePage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,13 @@ type Props = {
|
||||||
/**
|
/**
|
||||||
* Invoked to save changed settings.
|
* 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) {
|
function _mapStateToProps(state, ownProps) {
|
||||||
const { classes } = ownProps;
|
const { classes, isDisplayedOnWelcomePage } = ownProps;
|
||||||
const configuredTabs = interfaceConfig.SETTINGS_SECTIONS || [];
|
const configuredTabs = interfaceConfig.SETTINGS_SECTIONS || [];
|
||||||
|
|
||||||
// The settings sections to display.
|
// The settings sections to display.
|
||||||
|
@ -276,7 +282,7 @@ function _mapStateToProps(state, ownProps) {
|
||||||
component: DeviceSelection,
|
component: DeviceSelection,
|
||||||
label: 'settings.devices',
|
label: 'settings.devices',
|
||||||
onMount: getAvailableDevices,
|
onMount: getAvailableDevices,
|
||||||
props: getDeviceSelectionDialogProps(state),
|
props: getDeviceSelectionDialogProps(state, isDisplayedOnWelcomePage),
|
||||||
propsUpdateFunction: (tabState, newProps) => {
|
propsUpdateFunction: (tabState, newProps) => {
|
||||||
// Ensure the device selection tab gets updated when new devices
|
// Ensure the device selection tab gets updated when new devices
|
||||||
// are found by taking the new props and only preserving the
|
// 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`,
|
styles: `settings-pane ${classes.settingsDialog} devices-pane`,
|
||||||
submit: submitDeviceSelectionTab
|
submit: newState => submitDeviceSelectionTab(newState, isDisplayedOnWelcomePage)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,8 @@ class WelcomePage extends AbstractWelcomePage {
|
||||||
<div className = 'header'>
|
<div className = 'header'>
|
||||||
<div className = 'welcome-page-settings'>
|
<div className = 'welcome-page-settings'>
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
defaultTab = { SETTINGS_TABS.CALENDAR } />
|
defaultTab = { SETTINGS_TABS.CALENDAR }
|
||||||
|
isDisplayedOnWelcomePage = { true } />
|
||||||
{ showAdditionalToolbarContent
|
{ showAdditionalToolbarContent
|
||||||
? <div
|
? <div
|
||||||
className = 'settings-toolbar-content'
|
className = 'settings-toolbar-content'
|
||||||
|
|
Loading…
Reference in New Issue