You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

actions.web.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /* @flow */
  2. import Recording from '../../../modules/UI/recording/Recording';
  3. import SideContainerToggler
  4. from '../../../modules/UI/side_pannels/SideContainerToggler';
  5. import UIEvents from '../../../service/UI/UIEvents';
  6. import {
  7. changeLocalRaiseHand,
  8. clearToolboxTimeout,
  9. setSubjectSlideIn,
  10. setToolbarButton,
  11. setToolboxTimeout,
  12. setToolboxTimeoutMS,
  13. setToolboxVisible,
  14. toggleFullScreen,
  15. toggleToolbarButton
  16. } from './actions.native';
  17. import { SET_DEFAULT_TOOLBOX_BUTTONS } from './actionTypes';
  18. import {
  19. getButton,
  20. getDefaultToolboxButtons,
  21. isButtonEnabled
  22. } from './functions';
  23. declare var $: Function;
  24. declare var APP: Object;
  25. declare var config: Object;
  26. declare var interfaceConfig: Object;
  27. export * from './actions.native';
  28. /**
  29. * Checks whether desktop sharing is enabled and whether
  30. * we have params to start automatically sharing.
  31. *
  32. * @returns {Function}
  33. */
  34. export function checkAutoEnableDesktopSharing(): Function {
  35. return () => {
  36. // XXX Should use dispatcher to toggle screensharing but screensharing
  37. // hasn't been React-ified yet.
  38. if (isButtonEnabled('desktop')
  39. && config.autoEnableDesktopSharing) {
  40. APP.UI.eventEmitter.emit(UIEvents.TOGGLE_SCREENSHARING);
  41. }
  42. };
  43. }
  44. /**
  45. * Dispatches an action to hide any popups displayed by the associated button.
  46. *
  47. * @param {string} buttonName - The name of the button as specified in the
  48. * button configurations for the toolbar.
  49. * @returns {Function}
  50. */
  51. export function clearButtonPopup(buttonName) {
  52. return (dispatch, getState) => {
  53. _clearPopupTimeout(buttonName, getState());
  54. dispatch(setToolbarButton(buttonName, {
  55. popupDisplay: null
  56. }));
  57. };
  58. }
  59. /**
  60. * Docks/undocks the Toolbox.
  61. *
  62. * @param {boolean} dock - True if dock, false otherwise.
  63. * @returns {Function}
  64. */
  65. export function dockToolbox(dock: boolean): Function {
  66. return (dispatch: Dispatch<*>, getState: Function) => {
  67. if (interfaceConfig.filmStripOnly) {
  68. return;
  69. }
  70. const { timeoutMS, visible } = getState()['features/toolbox'];
  71. if (dock) {
  72. // First make sure the toolbox is shown.
  73. visible || dispatch(showToolbox());
  74. dispatch(clearToolboxTimeout());
  75. } else if (visible) {
  76. dispatch(
  77. setToolboxTimeout(
  78. () => dispatch(hideToolbox()),
  79. timeoutMS));
  80. } else {
  81. dispatch(showToolbox());
  82. }
  83. };
  84. }
  85. /**
  86. * Returns button on mount/unmount handlers with dispatch function stored in
  87. * closure.
  88. *
  89. * @param {Function} dispatch - Redux action dispatcher.
  90. * @returns {Object} Button on mount/unmount handlers.
  91. * @private
  92. */
  93. function _getButtonHandlers(dispatch) {
  94. const localRaiseHandHandler
  95. = (...args) => dispatch(changeLocalRaiseHand(...args));
  96. const toggleFullScreenHandler
  97. = (...args) => dispatch(toggleFullScreen(...args));
  98. return {
  99. /**
  100. * Mount handler for desktop button.
  101. *
  102. * @type {Object}
  103. */
  104. desktop: {
  105. onMount: () => dispatch(showDesktopSharingButton())
  106. },
  107. /**
  108. * Mount/Unmount handler for toggling fullscreen button.
  109. *
  110. * @type {Object}
  111. */
  112. fullscreen: {
  113. onMount: () =>
  114. APP.UI.addListener(
  115. UIEvents.FULLSCREEN_TOGGLED,
  116. toggleFullScreenHandler),
  117. onUnmount: () =>
  118. APP.UI.removeListener(
  119. UIEvents.FULLSCREEN_TOGGLED,
  120. toggleFullScreenHandler)
  121. },
  122. /**
  123. * Mount/Unmount handlers for raisehand button.
  124. *
  125. * @type {button}
  126. */
  127. raisehand: {
  128. onMount: () =>
  129. APP.UI.addListener(
  130. UIEvents.LOCAL_RAISE_HAND_CHANGED,
  131. localRaiseHandHandler),
  132. onUnmount: () =>
  133. APP.UI.removeListener(
  134. UIEvents.LOCAL_RAISE_HAND_CHANGED,
  135. localRaiseHandHandler)
  136. },
  137. /**
  138. * Mount handler for recording button.
  139. *
  140. * @type {Object}
  141. */
  142. recording: {
  143. onMount: () =>
  144. config.enableRecording && dispatch(showRecordingButton())
  145. }
  146. };
  147. }
  148. /**
  149. * Hides the toolbox.
  150. *
  151. * @param {boolean} force - True to force the hiding of the toolbox without
  152. * caring about the extended toolbar side panels.
  153. * @returns {Function}
  154. */
  155. export function hideToolbox(force: boolean = false): Function {
  156. return (dispatch: Dispatch<*>, getState: Function) => {
  157. const state = getState();
  158. const {
  159. alwaysVisible,
  160. hovered,
  161. timeoutMS
  162. } = state['features/toolbox'];
  163. if (alwaysVisible) {
  164. return;
  165. }
  166. dispatch(clearToolboxTimeout());
  167. if (!force
  168. && (hovered
  169. || state['features/base/jwt'].callOverlayVisible
  170. || SideContainerToggler.isVisible())) {
  171. dispatch(
  172. setToolboxTimeout(
  173. () => dispatch(hideToolbox()),
  174. timeoutMS));
  175. } else {
  176. dispatch(setToolboxVisible(false));
  177. dispatch(setSubjectSlideIn(false));
  178. }
  179. };
  180. }
  181. /**
  182. * Dispatches an action to show the popup associated with a button. Sets a
  183. * timeout to be fired which will dismiss the popup.
  184. *
  185. * @param {string} buttonName - The name of the button as specified in the
  186. * button configurations for the toolbar.
  187. * @param {string} popupName - The id of the popup to show as specified in
  188. * the button configurations for the toolbar.
  189. * @param {number} timeout - The time in milliseconds to show the popup.
  190. * @returns {Function}
  191. */
  192. export function setButtonPopupTimeout(buttonName, popupName, timeout) {
  193. return (dispatch, getState) => {
  194. _clearPopupTimeout(buttonName, getState());
  195. const newTimeoutId = setTimeout(() => {
  196. dispatch(clearButtonPopup(buttonName));
  197. }, timeout);
  198. dispatch(setToolbarButton(buttonName, {
  199. popupDisplay: {
  200. popupID: popupName,
  201. timeoutID: newTimeoutId
  202. }
  203. }));
  204. };
  205. }
  206. /**
  207. * Sets the default toolbar buttons of the Toolbox.
  208. *
  209. * @returns {Function}
  210. */
  211. export function setDefaultToolboxButtons(): Function {
  212. return (dispatch: Dispatch) => {
  213. // Save dispatch function in closure.
  214. const buttonHandlers = _getButtonHandlers(dispatch);
  215. const toolboxButtons = getDefaultToolboxButtons(buttonHandlers);
  216. dispatch({
  217. type: SET_DEFAULT_TOOLBOX_BUTTONS,
  218. ...toolboxButtons
  219. });
  220. };
  221. }
  222. /**
  223. * Shows desktop sharing button.
  224. *
  225. * @returns {Function}
  226. */
  227. export function showDesktopSharingButton(): Function {
  228. return (dispatch: Dispatch<*>) => {
  229. const buttonName = 'desktop';
  230. const disabledTooltipText
  231. = APP.conference.desktopSharingDisabledTooltip;
  232. const showTooltip
  233. = disabledTooltipText
  234. && APP.conference.isDesktopSharingDisabledByConfig;
  235. const visible
  236. = isButtonEnabled(buttonName)
  237. && (APP.conference.isDesktopSharingEnabled || showTooltip);
  238. const newState = {
  239. enabled: APP.conference.isDesktopSharingEnabled,
  240. hidden: !visible,
  241. tooltipText: showTooltip ? disabledTooltipText : undefined
  242. };
  243. dispatch(setToolbarButton(buttonName, newState));
  244. };
  245. }
  246. /**
  247. * Shows or hides the dialpad button.
  248. *
  249. * @param {boolean} show - Flag showing whether to show button or not.
  250. * @returns {Function}
  251. */
  252. export function showDialPadButton(show: boolean): Function {
  253. return (dispatch: Dispatch<*>) => {
  254. const buttonName = 'dialpad';
  255. if (show && isButtonEnabled(buttonName)) {
  256. dispatch(setToolbarButton(buttonName, {
  257. hidden: false
  258. }));
  259. }
  260. };
  261. }
  262. /**
  263. * Shows recording button.
  264. *
  265. * @returns {Function}
  266. */
  267. export function showRecordingButton(): Function {
  268. return (dispatch: Dispatch<*>) => {
  269. dispatch(setToolbarButton('recording', {
  270. hidden: false
  271. }));
  272. Recording.initRecordingButton();
  273. };
  274. }
  275. /**
  276. * Shows or hides the 'shared video' button.
  277. *
  278. * @returns {Function}
  279. */
  280. export function showSharedVideoButton(): Function {
  281. return (dispatch: Dispatch<*>) => {
  282. const buttonName = 'sharedvideo';
  283. if (isButtonEnabled(buttonName)
  284. && !config.disableThirdPartyRequests) {
  285. dispatch(setToolbarButton(buttonName, {
  286. hidden: false
  287. }));
  288. }
  289. };
  290. }
  291. /**
  292. * Shows the toolbox for specified timeout.
  293. *
  294. * @param {number} timeout - Timeout for showing the toolbox.
  295. * @returns {Function}
  296. */
  297. export function showToolbox(timeout: number = 0): Object {
  298. return (dispatch: Dispatch<*>, getState: Function) => {
  299. const state = getState();
  300. const {
  301. alwaysVisible,
  302. enabled,
  303. timeoutMS,
  304. visible
  305. } = state['features/toolbox'];
  306. if (enabled && !visible) {
  307. dispatch(setToolboxVisible(true));
  308. dispatch(setSubjectSlideIn(true));
  309. // If the Toolbox is always visible, there's no need for a timeout
  310. // to toggle its visibility.
  311. if (!alwaysVisible) {
  312. dispatch(
  313. setToolboxTimeout(
  314. () => dispatch(hideToolbox()),
  315. timeout || timeoutMS));
  316. dispatch(setToolboxTimeoutMS(interfaceConfig.TOOLBAR_TIMEOUT));
  317. }
  318. }
  319. };
  320. }
  321. /**
  322. * Event handler for side toolbar container toggled event.
  323. *
  324. * @param {string} containerId - ID of the container.
  325. * @returns {Function}
  326. */
  327. export function toggleSideToolbarContainer(containerId: string): Function {
  328. return (dispatch: Dispatch, getState: Function) => {
  329. const { secondaryToolbarButtons } = getState()['features/toolbox'];
  330. for (const key of secondaryToolbarButtons.keys()) {
  331. const button = secondaryToolbarButtons.get(key);
  332. if (isButtonEnabled(key)
  333. && button.sideContainerId
  334. && button.sideContainerId === containerId) {
  335. dispatch(toggleToolbarButton(key));
  336. break;
  337. }
  338. }
  339. };
  340. }
  341. /**
  342. * Clears the timeout set for hiding a button popup.
  343. *
  344. * @param {string} buttonName - The name of the button as specified in the
  345. * button configurations for the toolbar.
  346. * @param {Object} state - The redux state in which the button is expected to
  347. * be defined.
  348. * @private
  349. * @returns {void}
  350. */
  351. function _clearPopupTimeout(buttonName, state) {
  352. const { popupDisplay } = getButton(buttonName, state);
  353. const { timeoutID } = popupDisplay || {};
  354. clearTimeout(timeoutID);
  355. }