ref(config): override config from URL on mobile

Moves the things around to be able to override the config with the URL
params specified in the hash part of the location URI to which the app
is navigating to.
This commit is contained in:
paweldomas 2018-03-06 10:08:23 -06:00 committed by Lyubo Marinov
parent 6a066c3079
commit ef52f09910
3 changed files with 78 additions and 51 deletions

View File

@ -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
});
};
}

View File

@ -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 */

View File

@ -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<Object>}
*/
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;
}