2017-02-16 23:02:40 +00:00
|
|
|
/* @flow */
|
|
|
|
|
|
|
|
import Recording from '../../../modules/UI/recording/Recording';
|
|
|
|
import SideContainerToggler
|
|
|
|
from '../../../modules/UI/side_pannels/SideContainerToggler';
|
2017-07-26 21:00:10 +00:00
|
|
|
|
2017-05-31 22:14:58 +00:00
|
|
|
import UIEvents from '../../../service/UI/UIEvents';
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
import {
|
2017-05-26 21:28:16 +00:00
|
|
|
changeLocalRaiseHand,
|
2017-04-01 05:52:40 +00:00
|
|
|
clearToolboxTimeout,
|
2017-02-16 23:02:40 +00:00
|
|
|
setSubjectSlideIn,
|
|
|
|
setToolbarButton,
|
2017-04-01 05:52:40 +00:00
|
|
|
setToolboxTimeout,
|
|
|
|
setToolboxTimeoutMS,
|
|
|
|
setToolboxVisible,
|
2017-05-26 21:28:16 +00:00
|
|
|
toggleFullScreen,
|
2017-02-16 23:02:40 +00:00
|
|
|
toggleToolbarButton
|
|
|
|
} from './actions.native';
|
2017-05-01 23:04:12 +00:00
|
|
|
import { SET_DEFAULT_TOOLBOX_BUTTONS } from './actionTypes';
|
2017-07-26 20:52:41 +00:00
|
|
|
import {
|
2017-08-15 23:52:42 +00:00
|
|
|
getButton,
|
2017-07-26 20:52:41 +00:00
|
|
|
getDefaultToolboxButtons,
|
|
|
|
isButtonEnabled
|
|
|
|
} from './functions';
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
declare var $: Function;
|
|
|
|
declare var APP: Object;
|
|
|
|
declare var config: Object;
|
|
|
|
declare var interfaceConfig: Object;
|
|
|
|
|
2017-05-01 23:04:12 +00:00
|
|
|
export * from './actions.native';
|
|
|
|
|
2017-02-16 23:02:40 +00:00
|
|
|
/**
|
|
|
|
* Checks whether desktop sharing is enabled and whether
|
|
|
|
* we have params to start automatically sharing.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function checkAutoEnableDesktopSharing(): Function {
|
|
|
|
return () => {
|
|
|
|
// XXX Should use dispatcher to toggle screensharing but screensharing
|
|
|
|
// hasn't been React-ified yet.
|
2017-07-26 20:52:41 +00:00
|
|
|
if (isButtonEnabled('desktop')
|
2017-02-16 23:02:40 +00:00
|
|
|
&& config.autoEnableDesktopSharing) {
|
|
|
|
APP.UI.eventEmitter.emit(UIEvents.TOGGLE_SCREENSHARING);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-08-15 23:52:42 +00:00
|
|
|
/**
|
|
|
|
* Dispatches an action to hide any popups displayed by the associated button.
|
|
|
|
*
|
|
|
|
* @param {string} buttonName - The name of the button as specified in the
|
|
|
|
* button configurations for the toolbar.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function clearButtonPopup(buttonName) {
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
_clearPopupTimeout(buttonName, getState());
|
|
|
|
|
|
|
|
dispatch(setToolbarButton(buttonName, {
|
|
|
|
popupDisplay: null
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-02-16 23:02:40 +00:00
|
|
|
/**
|
2017-04-01 05:52:40 +00:00
|
|
|
* Docks/undocks the Toolbox.
|
2017-02-16 23:02:40 +00:00
|
|
|
*
|
|
|
|
* @param {boolean} dock - True if dock, false otherwise.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2017-04-01 05:52:40 +00:00
|
|
|
export function dockToolbox(dock: boolean): Function {
|
2017-02-16 23:02:40 +00:00
|
|
|
return (dispatch: Dispatch<*>, getState: Function) => {
|
|
|
|
if (interfaceConfig.filmStripOnly) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-31 22:14:58 +00:00
|
|
|
const { timeoutMS, visible } = getState()['features/toolbox'];
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
if (dock) {
|
2017-04-01 05:52:40 +00:00
|
|
|
// First make sure the toolbox is shown.
|
|
|
|
visible || dispatch(showToolbox());
|
2017-02-16 23:02:40 +00:00
|
|
|
|
2017-04-01 05:52:40 +00:00
|
|
|
dispatch(clearToolboxTimeout());
|
2017-02-16 23:02:40 +00:00
|
|
|
} else if (visible) {
|
|
|
|
dispatch(
|
2017-04-01 05:52:40 +00:00
|
|
|
setToolboxTimeout(
|
|
|
|
() => dispatch(hideToolbox()),
|
|
|
|
timeoutMS));
|
2017-02-16 23:02:40 +00:00
|
|
|
} else {
|
2017-04-01 05:52:40 +00:00
|
|
|
dispatch(showToolbox());
|
2017-02-16 23:02:40 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-05-26 21:28:16 +00:00
|
|
|
/**
|
|
|
|
* Returns button on mount/unmount handlers with dispatch function stored in
|
|
|
|
* closure.
|
|
|
|
*
|
|
|
|
* @param {Function} dispatch - Redux action dispatcher.
|
|
|
|
* @param {Function} getState - The function fetching the Redux state.
|
|
|
|
* @returns {Object} Button on mount/unmount handlers.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function _getButtonHandlers(dispatch, getState) {
|
2017-05-31 22:14:58 +00:00
|
|
|
const localRaiseHandHandler
|
|
|
|
= (...args) => dispatch(changeLocalRaiseHand(...args));
|
|
|
|
const toggleFullScreenHandler
|
|
|
|
= (...args) => dispatch(toggleFullScreen(...args));
|
2017-05-26 21:28:16 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
/**
|
|
|
|
* Mount handler for desktop button.
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
desktop: {
|
|
|
|
onMount: () => dispatch(showDesktopSharingButton())
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mount/Unmount handler for toggling fullscreen button.
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
fullscreen: {
|
|
|
|
onMount: () =>
|
|
|
|
APP.UI.addListener(
|
|
|
|
UIEvents.FULLSCREEN_TOGGLED,
|
|
|
|
toggleFullScreenHandler),
|
|
|
|
onUnmount: () =>
|
|
|
|
APP.UI.removeListener(
|
|
|
|
UIEvents.FULLSCREEN_TOGGLED,
|
|
|
|
toggleFullScreenHandler)
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mount handler for profile button.
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
profile: {
|
|
|
|
onMount: () =>
|
2017-05-31 22:14:58 +00:00
|
|
|
getState()['features/jwt']
|
|
|
|
|| dispatch(setProfileButtonUnclickable(true))
|
2017-05-26 21:28:16 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mount/Unmount handlers for raisehand button.
|
|
|
|
*
|
|
|
|
* @type {button}
|
|
|
|
*/
|
|
|
|
raisehand: {
|
|
|
|
onMount: () =>
|
|
|
|
APP.UI.addListener(
|
|
|
|
UIEvents.LOCAL_RAISE_HAND_CHANGED,
|
|
|
|
localRaiseHandHandler),
|
|
|
|
onUnmount: () =>
|
|
|
|
APP.UI.removeListener(
|
|
|
|
UIEvents.LOCAL_RAISE_HAND_CHANGED,
|
|
|
|
localRaiseHandHandler)
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mount handler for recording button.
|
|
|
|
*
|
|
|
|
* @type {Object}
|
|
|
|
*/
|
|
|
|
recording: {
|
|
|
|
onMount: () =>
|
2017-05-31 22:14:58 +00:00
|
|
|
config.enableRecording && dispatch(showRecordingButton())
|
2017-05-26 21:28:16 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-02-16 23:02:40 +00:00
|
|
|
/**
|
2017-04-01 05:52:40 +00:00
|
|
|
* Hides the toolbox.
|
2017-02-16 23:02:40 +00:00
|
|
|
*
|
2017-04-01 05:52:40 +00:00
|
|
|
* @param {boolean} force - True to force the hiding of the toolbox without
|
2017-02-16 23:02:40 +00:00
|
|
|
* caring about the extended toolbar side panels.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2017-04-01 05:52:40 +00:00
|
|
|
export function hideToolbox(force: boolean = false): Function {
|
2017-02-16 23:02:40 +00:00
|
|
|
return (dispatch: Dispatch<*>, getState: Function) => {
|
|
|
|
const state = getState();
|
|
|
|
const {
|
|
|
|
alwaysVisible,
|
|
|
|
hovered,
|
2017-04-01 05:52:40 +00:00
|
|
|
timeoutMS
|
|
|
|
} = state['features/toolbox'];
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
if (alwaysVisible) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-01 05:52:40 +00:00
|
|
|
dispatch(clearToolboxTimeout());
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
if (!force
|
|
|
|
&& (hovered
|
2017-06-05 18:19:25 +00:00
|
|
|
|| state['features/jwt'].callOverlayVisible
|
2017-02-16 23:02:40 +00:00
|
|
|
|| SideContainerToggler.isVisible())) {
|
|
|
|
dispatch(
|
2017-04-01 05:52:40 +00:00
|
|
|
setToolboxTimeout(
|
|
|
|
() => dispatch(hideToolbox()),
|
|
|
|
timeoutMS));
|
2017-02-16 23:02:40 +00:00
|
|
|
} else {
|
2017-04-01 05:52:40 +00:00
|
|
|
dispatch(setToolboxVisible(false));
|
2017-02-16 23:02:40 +00:00
|
|
|
dispatch(setSubjectSlideIn(false));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-08-15 23:52:42 +00:00
|
|
|
/**
|
|
|
|
* Dispatches an action to show the popup associated with a button. Sets a
|
|
|
|
* timeout to be fired which will dismiss the popup.
|
|
|
|
*
|
|
|
|
* @param {string} buttonName - The name of the button as specified in the
|
|
|
|
* button configurations for the toolbar.
|
|
|
|
* @param {string} popupName - The id of the popup to show as specified in
|
|
|
|
* the button configurations for the toolbar.
|
|
|
|
* @param {number} timeout - The time in milliseconds to show the popup.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function setButtonPopupTimeout(buttonName, popupName, timeout) {
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
_clearPopupTimeout(buttonName, getState());
|
|
|
|
|
|
|
|
const newTimeoutId = setTimeout(() => {
|
|
|
|
dispatch(clearButtonPopup(buttonName));
|
|
|
|
}, timeout);
|
|
|
|
|
|
|
|
dispatch(setToolbarButton(buttonName, {
|
|
|
|
popupDisplay: {
|
|
|
|
popupID: popupName,
|
|
|
|
timeoutID: newTimeoutId
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-05-01 23:04:12 +00:00
|
|
|
/**
|
|
|
|
* Sets the default toolbar buttons of the Toolbox.
|
|
|
|
*
|
2017-05-26 21:28:16 +00:00
|
|
|
* @returns {Function}
|
2017-05-01 23:04:12 +00:00
|
|
|
*/
|
2017-05-26 21:28:16 +00:00
|
|
|
export function setDefaultToolboxButtons(): Function {
|
|
|
|
return (dispatch: Dispatch, getState: Function) => {
|
|
|
|
// Save dispatch function in closure.
|
|
|
|
const buttonHandlers = _getButtonHandlers(dispatch, getState);
|
|
|
|
const toolboxButtons = getDefaultToolboxButtons(buttonHandlers);
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
type: SET_DEFAULT_TOOLBOX_BUTTONS,
|
|
|
|
...toolboxButtons
|
|
|
|
});
|
2017-05-01 23:04:12 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-02-16 23:02:40 +00:00
|
|
|
/**
|
|
|
|
* Signals that unclickable property of profile button should change its value.
|
|
|
|
*
|
|
|
|
* @param {boolean} unclickable - Shows whether button is unclickable.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function setProfileButtonUnclickable(unclickable: boolean): Function {
|
|
|
|
return (dispatch: Dispatch<*>) => {
|
|
|
|
const buttonName = 'profile';
|
|
|
|
|
|
|
|
dispatch(setToolbarButton(buttonName, {
|
|
|
|
unclickable
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows desktop sharing button.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function showDesktopSharingButton(): Function {
|
|
|
|
return (dispatch: Dispatch<*>) => {
|
|
|
|
const buttonName = 'desktop';
|
2017-07-14 09:25:28 +00:00
|
|
|
const disabledTooltipText
|
|
|
|
= APP.conference.desktopSharingDisabledTooltip;
|
|
|
|
const showTooltip
|
|
|
|
= disabledTooltipText
|
|
|
|
&& APP.conference.isDesktopSharingDisabledByConfig;
|
2017-02-16 23:02:40 +00:00
|
|
|
const visible
|
2017-07-26 20:52:41 +00:00
|
|
|
= isButtonEnabled(buttonName)
|
2017-07-14 09:25:28 +00:00
|
|
|
&& (APP.conference.isDesktopSharingEnabled || showTooltip);
|
2017-02-16 23:02:40 +00:00
|
|
|
|
2017-07-14 09:25:28 +00:00
|
|
|
const newState = {
|
|
|
|
enabled: APP.conference.isDesktopSharingEnabled,
|
|
|
|
hidden: !visible,
|
|
|
|
tooltipText: showTooltip ? disabledTooltipText : undefined
|
|
|
|
};
|
|
|
|
|
|
|
|
dispatch(setToolbarButton(buttonName, newState));
|
2017-02-16 23:02:40 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows or hides the dialpad button.
|
|
|
|
*
|
|
|
|
* @param {boolean} show - Flag showing whether to show button or not.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function showDialPadButton(show: boolean): Function {
|
|
|
|
return (dispatch: Dispatch<*>) => {
|
|
|
|
const buttonName = 'dialpad';
|
|
|
|
|
2017-07-26 20:52:41 +00:00
|
|
|
if (show && isButtonEnabled(buttonName)) {
|
2017-02-16 23:02:40 +00:00
|
|
|
dispatch(setToolbarButton(buttonName, {
|
|
|
|
hidden: false
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows recording button.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function showRecordingButton(): Function {
|
|
|
|
return (dispatch: Dispatch<*>) => {
|
2017-04-12 19:06:56 +00:00
|
|
|
dispatch(setToolbarButton('recording', {
|
2017-02-16 23:02:40 +00:00
|
|
|
hidden: false
|
|
|
|
}));
|
|
|
|
|
2017-04-12 19:06:56 +00:00
|
|
|
Recording.initRecordingButton();
|
2017-02-16 23:02:40 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows or hides the 'shared video' button.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function showSharedVideoButton(): Function {
|
|
|
|
return (dispatch: Dispatch<*>) => {
|
|
|
|
const buttonName = 'sharedvideo';
|
|
|
|
|
2017-07-26 20:52:41 +00:00
|
|
|
if (isButtonEnabled(buttonName)
|
2017-05-17 21:44:28 +00:00
|
|
|
&& !config.disableThirdPartyRequests) {
|
2017-02-16 23:02:40 +00:00
|
|
|
dispatch(setToolbarButton(buttonName, {
|
|
|
|
hidden: false
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-05-19 15:12:24 +00:00
|
|
|
* Shows the dial out button if it's required and appropriate
|
|
|
|
* flag is passed.
|
2017-02-16 23:02:40 +00:00
|
|
|
*
|
|
|
|
* @param {boolean} show - Flag showing whether to show button or not.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2017-05-19 15:12:24 +00:00
|
|
|
export function showDialOutButton(show: boolean): Function {
|
2017-05-17 21:44:28 +00:00
|
|
|
return (dispatch: Dispatch<*>, getState: Function) => {
|
2017-05-19 15:12:24 +00:00
|
|
|
const buttonName = 'dialout';
|
2017-04-17 21:40:21 +00:00
|
|
|
|
2017-05-17 21:44:28 +00:00
|
|
|
if (show
|
|
|
|
&& APP.conference.sipGatewayEnabled()
|
2017-07-26 20:52:41 +00:00
|
|
|
&& isButtonEnabled(buttonName)
|
2017-04-17 21:40:21 +00:00
|
|
|
&& (!config.enableUserRolesBasedOnToken
|
2017-05-17 21:44:28 +00:00
|
|
|
|| !getState()['features/jwt'].isGuest)) {
|
2017-02-16 23:02:40 +00:00
|
|
|
dispatch(setToolbarButton(buttonName, {
|
2017-05-17 21:44:28 +00:00
|
|
|
hidden: false
|
2017-02-16 23:02:40 +00:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-04-01 05:52:40 +00:00
|
|
|
* Shows the toolbox for specified timeout.
|
2017-02-16 23:02:40 +00:00
|
|
|
*
|
2017-04-01 05:52:40 +00:00
|
|
|
* @param {number} timeout - Timeout for showing the toolbox.
|
2017-02-16 23:02:40 +00:00
|
|
|
* @returns {Function}
|
|
|
|
*/
|
2017-04-01 05:52:40 +00:00
|
|
|
export function showToolbox(timeout: number = 0): Object {
|
2017-02-16 23:02:40 +00:00
|
|
|
return (dispatch: Dispatch<*>, getState: Function) => {
|
|
|
|
const state = getState();
|
2017-04-12 19:06:56 +00:00
|
|
|
const {
|
|
|
|
alwaysVisible,
|
|
|
|
enabled,
|
|
|
|
timeoutMS,
|
|
|
|
visible
|
|
|
|
} = state['features/toolbox'];
|
2017-02-16 23:02:40 +00:00
|
|
|
|
2017-04-12 19:06:56 +00:00
|
|
|
if (enabled && !visible) {
|
2017-04-01 05:52:40 +00:00
|
|
|
dispatch(setToolboxVisible(true));
|
2017-02-16 23:02:40 +00:00
|
|
|
dispatch(setSubjectSlideIn(true));
|
2017-04-06 18:43:36 +00:00
|
|
|
|
|
|
|
// If the Toolbox is always visible, there's no need for a timeout
|
|
|
|
// to toggle its visibility.
|
|
|
|
if (!alwaysVisible) {
|
|
|
|
dispatch(
|
|
|
|
setToolboxTimeout(
|
|
|
|
() => dispatch(hideToolbox()),
|
|
|
|
timeout || timeoutMS));
|
|
|
|
dispatch(setToolboxTimeoutMS(interfaceConfig.TOOLBAR_TIMEOUT));
|
|
|
|
}
|
2017-02-16 23:02:40 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Event handler for side toolbar container toggled event.
|
|
|
|
*
|
|
|
|
* @param {string} containerId - ID of the container.
|
2017-04-01 05:52:40 +00:00
|
|
|
* @returns {Function}
|
2017-02-16 23:02:40 +00:00
|
|
|
*/
|
|
|
|
export function toggleSideToolbarContainer(containerId: string): Function {
|
|
|
|
return (dispatch: Dispatch, getState: Function) => {
|
2017-05-31 22:14:58 +00:00
|
|
|
const { secondaryToolbarButtons } = getState()['features/toolbox'];
|
2017-02-16 23:02:40 +00:00
|
|
|
|
|
|
|
for (const key of secondaryToolbarButtons.keys()) {
|
|
|
|
const button = secondaryToolbarButtons.get(key);
|
|
|
|
|
2017-07-26 20:52:41 +00:00
|
|
|
if (isButtonEnabled(key)
|
2017-02-16 23:02:40 +00:00
|
|
|
&& button.sideContainerId
|
|
|
|
&& button.sideContainerId === containerId) {
|
|
|
|
dispatch(toggleToolbarButton(key));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2017-08-15 23:52:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the timeout set for hiding a button popup.
|
|
|
|
*
|
|
|
|
* @param {string} buttonName - The name of the button as specified in the
|
|
|
|
* button configurations for the toolbar.
|
|
|
|
* @param {Object} state - The redux state in which the button is expected to
|
|
|
|
* be defined.
|
|
|
|
* @private
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
function _clearPopupTimeout(buttonName, state) {
|
|
|
|
const { popupDisplay } = getButton(buttonName, state);
|
|
|
|
const { timeoutID } = popupDisplay || {};
|
|
|
|
|
|
|
|
clearTimeout(timeoutID);
|
|
|
|
}
|