Ilya Daynatovich bcbdaaa6ea Fix interface_config.js/interfaceConfig overriding
It got broken while rewriting the Web toolbar in React Toolbox. There is
a problem with the toolbars and how we construct the intialState of the
buttons. The _getInitialState() in the toolbox reducer gets the list of
buttons from interfaceConfig, but in fact interfaceConfig is meant to be
overriden in several very important cases. One of the cases being the
external API, which we use in several projects in production.
2017-04-04 17:00:39 -05:00

217 lines
5.1 KiB
JavaScript

/* @flow */
import { ReducerRegistry } from '../base/redux';
import {
CLEAR_TOOLBOX_TIMEOUT,
SET_DEFAULT_TOOLBOX_BUTTONS,
SET_TOOLBOX_ALWAYS_VISIBLE,
SET_SUBJECT,
SET_SUBJECT_SLIDE_IN,
SET_TOOLBAR_BUTTON,
SET_TOOLBAR_HOVERED,
SET_TOOLBOX_TIMEOUT,
SET_TOOLBOX_TIMEOUT_MS,
SET_TOOLBOX_VISIBLE
} from './actionTypes';
declare var interfaceConfig: Object;
/**
* Returns initial state for toolbox's part of Redux store.
*
* @private
* @returns {{
* alwaysVisible: boolean,
* hovered: boolean,
* primaryToolbarButtons: Map,
* secondaryToolbarButtons: Map,
* subject: string,
* subjectSlideIn: boolean,
* timeoutID: number,
* timeoutMS: number,
* visible: boolean
* }}
*/
function _getInitialState() {
// Default toolbox timeout for mobile app.
let timeoutMS = 5000;
if (typeof interfaceConfig !== 'undefined'
&& interfaceConfig.INITIAL_TOOLBAR_TIMEOUT) {
timeoutMS = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
}
return {
/**
* The indicator which determines whether the Toolbox should always be
* visible.
*
* @type {boolean}
*/
alwaysVisible: false,
/**
* The indicator which determines whether a Toolbar in the Toolbox is
* hovered.
*
* @type {boolean}
*/
hovered: false,
/**
* A Map of the default buttons of the PrimaryToolbar.
*
* @type {Map}
*/
primaryToolbarButtons: new Map(),
/**
* A Map of the default buttons of the SecondaryToolbar.
*
* @type {Map}
*/
secondaryToolbarButtons: new Map(),
/**
* The text of the conference subject.
*
* @type {string}
*/
subject: '',
/**
* The indicator which determines whether the subject is sliding in.
*
* @type {boolean}
*/
subjectSlideIn: false,
/**
* A number, non-zero value which identifies the timer created by a call
* to setTimeout() with timeoutMS.
*
* @type {number|null}
*/
timeoutID: null,
/**
* The delay in milliseconds before timeoutID executes (after its
* initialization).
*
* @type {number}
*/
timeoutMS,
/**
* The indicator which determines whether the Toolbox is visible.
*
* @type {boolean}
*/
visible: false
};
}
ReducerRegistry.register(
'features/toolbox',
(state: Object = _getInitialState(), action: Object) => {
switch (action.type) {
case CLEAR_TOOLBOX_TIMEOUT:
return {
...state,
timeoutID: undefined
};
case SET_DEFAULT_TOOLBOX_BUTTONS: {
const { primaryToolbarButtons, secondaryToolbarButtons } = action;
return {
...state,
primaryToolbarButtons,
secondaryToolbarButtons
};
}
case SET_TOOLBOX_ALWAYS_VISIBLE:
return {
...state,
alwaysVisible: action.alwaysVisible
};
case SET_SUBJECT:
return {
...state,
subject: action.subject
};
case SET_SUBJECT_SLIDE_IN:
return {
...state,
subjectSlideIn: action.subjectSlideIn
};
case SET_TOOLBAR_BUTTON:
return _setButton(state, action);
case SET_TOOLBAR_HOVERED:
return {
...state,
hovered: action.hovered
};
case SET_TOOLBOX_TIMEOUT:
return {
...state,
timeoutID: action.timeoutID,
timeoutMS: action.timeoutMS
};
case SET_TOOLBOX_TIMEOUT_MS:
return {
...state,
timeoutMS: action.timeoutMS
};
case SET_TOOLBOX_VISIBLE:
return {
...state,
visible: action.visible
};
}
return state;
});
/**
* Sets new value of the button.
*
* @param {Object} state - Redux state.
* @param {Object} action - Dispatched action.
* @param {Object} action.button - Object describing toolbar button.
* @param {Object} action.buttonName - The name of the button.
* @private
* @returns {Object}
*/
function _setButton(state, { button, buttonName }): Object {
const { primaryToolbarButtons, secondaryToolbarButtons } = state;
let selectedButton = primaryToolbarButtons.get(buttonName);
let place = 'primaryToolbarButtons';
if (!selectedButton) {
selectedButton = secondaryToolbarButtons.get(buttonName);
place = 'secondaryToolbarButtons';
}
selectedButton = {
...selectedButton,
...button
};
const updatedToolbar = state[place].set(buttonName, selectedButton);
return {
...state,
[place]: new Map(updatedToolbar)
};
}