Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

actions.web.js 12KB

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