2018-05-23 21:10:04 +00:00
|
|
|
// @flow
|
2017-07-05 20:23:10 +00:00
|
|
|
|
|
|
|
import _ from 'lodash';
|
|
|
|
|
2021-04-22 08:56:22 +00:00
|
|
|
import { equals, ReducerRegistry } from '../redux';
|
2017-04-23 20:14:02 +00:00
|
|
|
|
2021-03-10 15:39:35 +00:00
|
|
|
import {
|
|
|
|
UPDATE_CONFIG,
|
|
|
|
CONFIG_WILL_LOAD,
|
|
|
|
LOAD_CONFIG_ERROR,
|
|
|
|
SET_CONFIG,
|
|
|
|
OVERWRITE_CONFIG
|
|
|
|
} from './actionTypes';
|
2019-04-30 10:24:12 +00:00
|
|
|
import { _cleanupConfig } from './functions';
|
2017-04-23 20:14:02 +00:00
|
|
|
|
2021-03-10 15:39:35 +00:00
|
|
|
declare var interfaceConfig: Object;
|
|
|
|
|
2017-04-23 20:14:02 +00:00
|
|
|
/**
|
2017-07-05 20:23:10 +00:00
|
|
|
* The initial state of the feature base/config when executing in a
|
|
|
|
* non-React Native environment. The mandatory configuration to be passed to
|
|
|
|
* JitsiMeetJS#init(). The app will download config.js from the Jitsi Meet
|
2021-03-16 15:59:33 +00:00
|
|
|
* deployment and take its values into account but the values below will be
|
2017-07-05 20:23:10 +00:00
|
|
|
* enforced (because they are essential to the correct execution of the
|
2017-04-23 20:14:02 +00:00
|
|
|
* application).
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
2017-07-05 20:23:10 +00:00
|
|
|
const INITIAL_NON_RN_STATE = {
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The initial state of the feature base/config when executing in a React Native
|
|
|
|
* environment. The mandatory configuration to be passed to JitsiMeetJS#init().
|
|
|
|
* The app will download config.js from the Jitsi Meet deployment and take its
|
2021-03-16 15:59:33 +00:00
|
|
|
* values into account but the values below will be enforced (because they are
|
2017-07-05 20:23:10 +00:00
|
|
|
* essential to the correct execution of the application).
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
const INITIAL_RN_STATE = {
|
2019-04-30 10:24:12 +00:00
|
|
|
analytics: {},
|
|
|
|
|
2017-04-23 20:14:02 +00:00
|
|
|
// FIXME The support for audio levels in lib-jitsi-meet polls the statistics
|
|
|
|
// of WebRTC at a short interval multiple times a second. Unfortunately,
|
|
|
|
// React Native is slow to fetch these statistics from the native WebRTC
|
|
|
|
// API, through the React Native bridge and eventually to JavaScript.
|
|
|
|
// Because the audio levels are of no interest to the mobile app, it is
|
|
|
|
// fastest to merely disable them.
|
|
|
|
disableAudioLevels: true,
|
|
|
|
|
2017-07-05 20:23:10 +00:00
|
|
|
p2p: {
|
2021-04-15 10:49:29 +00:00
|
|
|
disabledCodec: '',
|
|
|
|
disableH264: false, // deprecated
|
|
|
|
preferredCodec: 'H264',
|
|
|
|
preferH264: true // deprecated
|
|
|
|
}
|
2017-04-23 20:14:02 +00:00
|
|
|
};
|
|
|
|
|
2019-10-18 14:30:59 +00:00
|
|
|
ReducerRegistry.register('features/base/config', (state = _getInitialState(), action) => {
|
|
|
|
switch (action.type) {
|
2020-08-14 07:45:15 +00:00
|
|
|
case UPDATE_CONFIG:
|
2019-10-18 14:30:59 +00:00
|
|
|
return _updateConfig(state, action);
|
|
|
|
|
|
|
|
case CONFIG_WILL_LOAD:
|
|
|
|
return {
|
|
|
|
error: undefined,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The URL of the location associated with/configured by this
|
|
|
|
* configuration.
|
|
|
|
*
|
|
|
|
* @type URL
|
|
|
|
*/
|
|
|
|
locationURL: action.locationURL
|
|
|
|
};
|
|
|
|
|
|
|
|
case LOAD_CONFIG_ERROR:
|
|
|
|
// XXX LOAD_CONFIG_ERROR is one of the settlement execution paths of
|
|
|
|
// the asynchronous "loadConfig procedure/process" started with
|
|
|
|
// CONFIG_WILL_LOAD. Due to the asynchronous nature of it, whoever
|
|
|
|
// is settling the process needs to provide proof that they have
|
|
|
|
// started it and that the iteration of the process being completed
|
|
|
|
// now is still of interest to the app.
|
|
|
|
if (state.locationURL === action.locationURL) {
|
2017-11-29 14:15:57 +00:00
|
|
|
return {
|
2018-05-23 21:10:04 +00:00
|
|
|
/**
|
2019-10-18 14:30:59 +00:00
|
|
|
* The {@link Error} which prevented the loading of the
|
|
|
|
* configuration of the associated {@code locationURL}.
|
|
|
|
*
|
|
|
|
* @type Error
|
|
|
|
*/
|
|
|
|
error: action.error
|
2017-11-29 14:15:57 +00:00
|
|
|
};
|
2017-04-23 20:14:02 +00:00
|
|
|
}
|
2019-10-18 14:30:59 +00:00
|
|
|
break;
|
2018-05-23 21:10:04 +00:00
|
|
|
|
2019-10-18 14:30:59 +00:00
|
|
|
case SET_CONFIG:
|
|
|
|
return _setConfig(state, action);
|
2021-03-10 15:39:35 +00:00
|
|
|
|
|
|
|
case OVERWRITE_CONFIG:
|
|
|
|
return {
|
|
|
|
...state,
|
|
|
|
...action.config
|
|
|
|
};
|
2019-10-18 14:30:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return state;
|
|
|
|
});
|
2017-04-23 20:14:02 +00:00
|
|
|
|
2017-07-05 20:23:10 +00:00
|
|
|
/**
|
|
|
|
* Gets the initial state of the feature base/config. The mandatory
|
|
|
|
* configuration to be passed to JitsiMeetJS#init(). The app will download
|
|
|
|
* config.js from the Jitsi Meet deployment and take its values into account but
|
2021-03-16 15:59:33 +00:00
|
|
|
* the values below will be enforced (because they are essential to the correct
|
2017-07-05 20:23:10 +00:00
|
|
|
* execution of the application).
|
|
|
|
*
|
|
|
|
* @returns {Object}
|
|
|
|
*/
|
|
|
|
function _getInitialState() {
|
|
|
|
return (
|
2017-07-19 08:51:07 +00:00
|
|
|
navigator.product === 'ReactNative'
|
2017-07-05 20:23:10 +00:00
|
|
|
? INITIAL_RN_STATE
|
|
|
|
: INITIAL_NON_RN_STATE);
|
|
|
|
}
|
|
|
|
|
2017-04-23 20:14:02 +00:00
|
|
|
/**
|
|
|
|
* Reduces a specific Redux action SET_CONFIG of the feature
|
|
|
|
* base/lib-jitsi-meet.
|
|
|
|
*
|
2019-10-18 14:30:59 +00:00
|
|
|
* @param {Object} state - The Redux state of the feature base/config.
|
2017-04-23 20:14:02 +00:00
|
|
|
* @param {Action} action - The Redux action SET_CONFIG to reduce.
|
|
|
|
* @private
|
2019-10-18 14:30:59 +00:00
|
|
|
* @returns {Object} The new state after the reduction of the specified action.
|
2017-04-23 20:14:02 +00:00
|
|
|
*/
|
2017-11-29 14:15:57 +00:00
|
|
|
function _setConfig(state, { config }) {
|
2017-07-05 20:23:10 +00:00
|
|
|
// The mobile app bundles jitsi-meet and lib-jitsi-meet at build time and
|
|
|
|
// does not download them at runtime from the deployment on which it will
|
|
|
|
// join a conference. The downloading is planned for implementation in the
|
|
|
|
// future (later rather than sooner) but is not implemented yet at the time
|
|
|
|
// of this writing and, consequently, we must provide legacy support in the
|
|
|
|
// meantime.
|
2017-11-29 14:15:57 +00:00
|
|
|
|
|
|
|
// eslint-disable-next-line no-param-reassign
|
2017-07-05 20:23:10 +00:00
|
|
|
config = _translateLegacyConfig(config);
|
2021-04-13 11:26:07 +00:00
|
|
|
|
2021-04-14 11:23:40 +00:00
|
|
|
const { audioQuality } = config;
|
|
|
|
const hdAudioOptions = {};
|
2021-04-13 11:26:07 +00:00
|
|
|
|
2021-04-14 11:23:40 +00:00
|
|
|
if (audioQuality?.stereo) {
|
2021-04-13 11:26:07 +00:00
|
|
|
Object.assign(hdAudioOptions, {
|
|
|
|
disableAP: true,
|
|
|
|
enableNoAudioDetection: false,
|
|
|
|
enableNoisyMicDetection: false,
|
2021-04-14 11:23:40 +00:00
|
|
|
enableTalkWhileMuted: false
|
2021-04-13 11:26:07 +00:00
|
|
|
});
|
|
|
|
}
|
2017-04-23 20:14:02 +00:00
|
|
|
|
2017-07-05 20:23:10 +00:00
|
|
|
const newState = _.merge(
|
|
|
|
{},
|
|
|
|
config,
|
2021-04-13 11:26:07 +00:00
|
|
|
hdAudioOptions,
|
2017-11-29 14:15:57 +00:00
|
|
|
{ error: undefined },
|
2017-07-05 20:23:10 +00:00
|
|
|
|
|
|
|
// The config of _getInitialState() is meant to override the config
|
2017-04-23 20:14:02 +00:00
|
|
|
// downloaded from the Jitsi Meet deployment because the former contains
|
|
|
|
// values that are mandatory.
|
2017-07-05 20:23:10 +00:00
|
|
|
_getInitialState()
|
|
|
|
);
|
|
|
|
|
2019-04-30 10:24:12 +00:00
|
|
|
_cleanupConfig(newState);
|
|
|
|
|
2017-07-05 20:23:10 +00:00
|
|
|
return equals(state, newState) ? state : newState;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructs a new config {@code Object}, if necessary, out of a specific
|
|
|
|
* config {@code Object} which is in the latest format supported by jitsi-meet.
|
|
|
|
* Such a translation from an old config format to a new/the latest config
|
|
|
|
* format is necessary because the mobile app bundles jitsi-meet and
|
|
|
|
* lib-jitsi-meet at build time and does not download them at runtime from the
|
|
|
|
* deployment on which it will join a conference.
|
|
|
|
*
|
|
|
|
* @param {Object} oldValue - The config {@code Object} which may or may not be
|
|
|
|
* in the latest form supported by jitsi-meet and from which a new config
|
|
|
|
* {@code Object} is to be constructed if necessary.
|
|
|
|
* @returns {Object} A config {@code Object} which is in the latest format
|
|
|
|
* supported by jitsi-meet.
|
|
|
|
*/
|
|
|
|
function _translateLegacyConfig(oldValue: Object) {
|
2021-04-22 08:56:22 +00:00
|
|
|
const newValue = oldValue;
|
2017-07-05 20:23:10 +00:00
|
|
|
|
2021-04-22 08:55:03 +00:00
|
|
|
if (!Array.isArray(oldValue.toolbarButtons)
|
|
|
|
&& typeof interfaceConfig === 'object' && Array.isArray(interfaceConfig.TOOLBAR_BUTTONS)) {
|
2021-03-10 15:39:35 +00:00
|
|
|
newValue.toolbarButtons = interfaceConfig.TOOLBAR_BUTTONS;
|
|
|
|
}
|
|
|
|
|
2021-04-14 11:23:40 +00:00
|
|
|
if (oldValue.stereo || oldValue.opusMaxAverageBitrate) {
|
|
|
|
newValue.audioQuality = {
|
|
|
|
opusMaxAverageBitrate: oldValue.audioQuality?.opusMaxAverageBitrate ?? oldValue.opusMaxAverageBitrate,
|
|
|
|
stereo: oldValue.audioQuality?.stereo ?? oldValue.stereo
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-07-05 20:23:10 +00:00
|
|
|
return newValue;
|
2017-04-23 20:14:02 +00:00
|
|
|
}
|
2019-10-18 14:30:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates the stored configuration with the given extra options.
|
|
|
|
*
|
|
|
|
* @param {Object} state - The Redux state of the feature base/config.
|
|
|
|
* @param {Action} action - The Redux action to reduce.
|
|
|
|
* @private
|
|
|
|
* @returns {Object} The new state after the reduction of the specified action.
|
|
|
|
*/
|
|
|
|
function _updateConfig(state, { config }) {
|
|
|
|
const newState = _.merge({}, state, config);
|
|
|
|
|
|
|
|
_cleanupConfig(newState);
|
|
|
|
|
|
|
|
return equals(state, newState) ? state : newState;
|
|
|
|
}
|