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 10KB

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