diff --git a/react/features/base/config/actions.js b/react/features/base/config/actions.js index 88fd65030..432317a30 100644 --- a/react/features/base/config/actions.js +++ b/react/features/base/config/actions.js @@ -1,10 +1,13 @@ -/* @flow */ +// @flow + +import type { Dispatch } from 'redux'; import { CONFIG_WILL_LOAD, LOAD_CONFIG_ERROR, SET_CONFIG } from './actionTypes'; +import { setConfigFromURLParams } from './functions'; /** * Signals that the configuration for a specific locationURL will be loaded now. @@ -51,14 +54,36 @@ export function loadConfigError(error: Error, locationURL: string | URL) { * * @param {Object} config - The configuration to be represented by the feature * base/config. - * @returns {{ - * type: SET_CONFIG, - * config: Object - * }} + * @returns {Function} */ export function setConfig(config: Object = {}) { - return { - type: SET_CONFIG, - config + return (dispatch: Dispatch<*>, getState: Function) => { + const { locationURL } = getState()['features/base/connection']; + + // Now that the loading of the config was successful override the values + // with the parameters passed in the hash part of the location URI. + // TODO We're still in the middle ground between old Web with config, + // interfaceConfig, and loggingConfig used via global variables and new + // Web and mobile reading the respective values from the redux store. + // On React Native there's no interfaceConfig at all yet and + // loggingConfig is not loaded but there's a default value in the redux + // store. + // Only the config will be overridden on React Native, as the other + // globals will be undefined here. It's intentional - we do not care to + // override those configs yet. + locationURL + && setConfigFromURLParams( + + // On Web the config also comes from the window.config global, + // but it is resolved in the loadConfig procedure. + config, + window.interfaceConfig, + window.loggingConfig, + locationURL); + + dispatch({ + type: SET_CONFIG, + config + }); }; } diff --git a/react/features/base/config/functions.js b/react/features/base/config/functions.js index 55413a272..ef3cdcf9a 100644 --- a/react/features/base/config/functions.js +++ b/react/features/base/config/functions.js @@ -179,7 +179,7 @@ export function obtainConfig( * @returns {void} */ export function overrideConfigJSON( - config: Object, interfaceConfig: Object, loggingConfig: Object, + config: ?Object, interfaceConfig: ?Object, loggingConfig: ?Object, json: Object) { for (const configName of Object.keys(json)) { let configObj; @@ -212,6 +212,8 @@ export function overrideConfigJSON( } } +/* eslint-enable max-params, no-shadow */ + /** * Whitelist only config.js, skips this for others configs * (interfaceConfig, loggingConfig). @@ -220,9 +222,9 @@ export function overrideConfigJSON( * @param {string} configName - The config name, one of config, * interfaceConfig, loggingConfig. * @param {Object} configJSON - The object with keys and values to override. + * @private * @returns {Object} - The result object only with the keys * that are whitelisted. - * @private */ function _getWhitelistedJSON(configName, configJSON) { if (configName !== 'config') { @@ -232,40 +234,48 @@ function _getWhitelistedJSON(configName, configJSON) { return _.pick(configJSON, WHITELISTED_KEYS); } -/* eslint-enable max-params, no-shadow */ +/* eslint-disable max-params */ /** - * Converts 'URL_PARAMS' to JSON object. - * We have: - * { - * "config.disableAudioLevels": false, - * "config.channelLastN": -1, - * "interfaceConfig.APP_NAME": "Jitsi Meet" - * }. - * We want to have: - * { - * "config": { - * "disableAudioLevels": false, - * "channelLastN": -1 - * }, - * interfaceConfig: { - * "APP_NAME": "Jitsi Meet" - * } - * }. + * Inspects the hash part of the location URI and overrides values specified + * there in the corresponding config objects given as the arguments. The syntax + * is: {@code https://server.com/room#config.debug=true + * &interfaceConfig.showButton=false&loggingConfig.something=1}. * + * In the hash part each parameter will be parsed to JSON and then the root + * object will be matched with the corresponding config object given as the + * argument to this function. + * + * @param {Object} config - This is the general config. + * @param {Object} interfaceConfig - This is the interface config. + * @param {Object} loggingConfig - The logging config. + * @param {URI} location - The new location to which the app is navigating to. * @returns {void} */ -export function setConfigFromURLParams() { - const params = parseURLParams(window.location); - - const { config, interfaceConfig, loggingConfig } = window; +export function setConfigFromURLParams( + config: ?Object, + interfaceConfig: ?Object, + loggingConfig: ?Object, + location: Object) { + const params = parseURLParams(location); const json = {}; - // TODO We're still in the middle ground between old Web with config, - // interfaceConfig, and loggingConfig used via global variables and new Web - // and mobile reading the respective values from the redux store. On React - // Native there's no interfaceConfig at all yet and loggingConfig is not - // loaded but there's a default value in the redux store. + // At this point we have: + // params = { + // "config.disableAudioLevels": false, + // "config.channelLastN": -1, + // "interfaceConfig.APP_NAME": "Jitsi Meet" + // } + // We want to have: + // json = { + // config: { + // "disableAudioLevels": false, + // "channelLastN": -1 + // }, + // interfaceConfig: { + // "APP_NAME": "Jitsi Meet" + // } + // } config && (json.config = {}); interfaceConfig && (json.interfaceConfig = {}); loggingConfig && (json.loggingConfig = {}); @@ -284,3 +294,5 @@ export function setConfigFromURLParams() { overrideConfigJSON(config, interfaceConfig, loggingConfig, json); } + +/* eslint-enable max-params */ diff --git a/react/features/base/lib-jitsi-meet/functions.js b/react/features/base/lib-jitsi-meet/functions.js index caafacdfe..1301ea1ab 100644 --- a/react/features/base/lib-jitsi-meet/functions.js +++ b/react/features/base/lib-jitsi-meet/functions.js @@ -1,6 +1,5 @@ // @flow -import { setConfigFromURLParams } from '../config'; import { toState } from '../redux'; import { loadScript } from '../util'; @@ -12,7 +11,7 @@ const JitsiConferenceErrors = JitsiMeetJS.errors.conference; const JitsiConnectionErrors = JitsiMeetJS.errors.connection; /** - * Creates a JitsiLocalTrack model from the given device id. + * Creates a {@link JitsiLocalTrack} model from the given device id. * * @param {string} type - The media type of track being created. Expected values * are "video" or "audio". @@ -107,9 +106,9 @@ export function isFatalJitsiConnectionError(error: Object | string) { * Loads config.js from a specific remote server. * * @param {string} url - The URL to load. - * @param {number} [timeout] - The timeout for the configuration to be loaded, - * in milliseconds. If not specified, a default value deamed appropriate for the - * purpsoe is used. + * @param {number} [timeout] - The timeout in milliseconds for the {@code url} + * to load. If not specified, a default value deemed appropriate for the purpose + * is used. * @returns {Promise} */ export function loadConfig( @@ -145,14 +144,5 @@ export function loadConfig( promise = Promise.resolve(window.config); } - // FIXME It's neither here nor there at the time of this writing where - // config, interfaceConfig, and loggingConfig should be overwritten by URL - // params. - promise = promise.then(value => { - setConfigFromURLParams(); - - return value; - }); - return promise; }