Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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