選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

functions.js 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /* @flow */
  2. import SideContainerToggler
  3. from '../../../modules/UI/side_pannels/SideContainerToggler';
  4. import { appNavigate } from '../app';
  5. import { toggleAudioMuted, toggleVideoMuted } from '../base/media';
  6. import defaultToolbarButtons from './defaultToolbarButtons';
  7. import type { Dispatch } from 'redux-thunk';
  8. type MapOfAttributes = { [key: string]: * };
  9. declare var $: Function;
  10. declare var AJS: Object;
  11. declare var interfaceConfig: Object;
  12. /**
  13. * Maps (redux) actions to React component props.
  14. *
  15. * @param {Function} dispatch - Redux action dispatcher.
  16. * @returns {{
  17. * _onHangup: Function,
  18. * _onToggleAudio: Function,
  19. * _onToggleVideo: Function
  20. * }}
  21. * @private
  22. */
  23. export function abstractMapDispatchToProps(dispatch: Dispatch<*>): Object {
  24. return {
  25. /**
  26. * Dispatches action to leave the current conference.
  27. *
  28. * @private
  29. * @returns {void}
  30. * @type {Function}
  31. */
  32. _onHangup() {
  33. // XXX We don't know here which value is effectively/internally
  34. // used when there's no valid room name to join. It isn't our
  35. // business to know that anyway. The undefined value is our
  36. // expression of (1) the lack of knowledge & (2) the desire to no
  37. // longer have a valid room name to join.
  38. return dispatch(appNavigate(undefined));
  39. },
  40. /**
  41. * Dispatches an action to toggle the mute state of the
  42. * audio/microphone.
  43. *
  44. * @private
  45. * @returns {Object} - Dispatched action.
  46. * @type {Function}
  47. */
  48. _onToggleAudio() {
  49. return dispatch(toggleAudioMuted());
  50. },
  51. /**
  52. * Dispatches an action to toggle the mute state of the video/camera.
  53. *
  54. * @private
  55. * @returns {Object} - Dispatched action.
  56. * @type {Function}
  57. */
  58. _onToggleVideo() {
  59. return dispatch(toggleVideoMuted());
  60. }
  61. };
  62. }
  63. /**
  64. * Maps parts of media state to component props.
  65. *
  66. * @param {Object} state - Redux state.
  67. * @protected
  68. * @returns {{
  69. * _audioMuted: boolean,
  70. * _videoMuted: boolean,
  71. * _visible: boolean
  72. * }}
  73. */
  74. export function abstractMapStateToProps(state: Object): Object {
  75. const media = state['features/base/media'];
  76. const { visible } = state['features/toolbox'];
  77. return {
  78. /**
  79. * Flag showing that audio is muted.
  80. *
  81. * @protected
  82. * @type {boolean}
  83. */
  84. _audioMuted: media.audio.muted,
  85. /**
  86. * Flag showing whether video is muted.
  87. *
  88. * @protected
  89. * @type {boolean}
  90. */
  91. _videoMuted: media.video.muted,
  92. /**
  93. * Flag showing whether toolbox is visible.
  94. *
  95. * @protected
  96. * @type {boolean}
  97. */
  98. _visible: visible
  99. };
  100. }
  101. /**
  102. * Takes toolbar button props and maps them to HTML attributes to set.
  103. *
  104. * @param {Object} props - Props set to the React component.
  105. * @returns {MapOfAttributes}
  106. */
  107. export function getButtonAttributesByProps(props: Object): MapOfAttributes {
  108. const classNames = [ ...props.classNames ];
  109. props.toggled && classNames.push('toggled');
  110. props.unclickable && classNames.push('unclickable');
  111. const result: MapOfAttributes = {
  112. className: classNames.join(' '),
  113. 'data-container': 'body',
  114. 'data-placement': 'bottom',
  115. id: props.id
  116. };
  117. if (!props.enabled) {
  118. result.disabled = 'disabled';
  119. }
  120. if (props.hidden) {
  121. result.style = { display: 'none' };
  122. }
  123. return result;
  124. }
  125. /**
  126. * Returns object containing default buttons for the primary and secondary
  127. * toolbars.
  128. *
  129. * @returns {Object}
  130. */
  131. export function getDefaultToolbarButtons(): Object {
  132. let toolbarButtons = {
  133. primaryToolbarButtons: new Map(),
  134. secondaryToolbarButtons: new Map()
  135. };
  136. if (typeof interfaceConfig !== 'undefined'
  137. && interfaceConfig.TOOLBAR_BUTTONS) {
  138. toolbarButtons
  139. = interfaceConfig.TOOLBAR_BUTTONS.reduce(
  140. (acc, buttonName) => {
  141. const button = defaultToolbarButtons[buttonName];
  142. if (button) {
  143. const place = _getToolbarButtonPlace(buttonName);
  144. button.buttonName = buttonName;
  145. acc[place].set(buttonName, button);
  146. }
  147. return acc;
  148. },
  149. toolbarButtons);
  150. }
  151. return toolbarButtons;
  152. }
  153. /**
  154. * Get place for toolbar button. Now it can be in the primary Toolbar or in the
  155. * secondary Toolbar.
  156. *
  157. * @param {string} btn - Button name.
  158. * @private
  159. * @returns {string}
  160. */
  161. function _getToolbarButtonPlace(btn) {
  162. return (
  163. interfaceConfig.MAIN_TOOLBAR_BUTTONS.includes(btn)
  164. ? 'primaryToolbarButtons'
  165. : 'secondaryToolbarButtons');
  166. }
  167. /**
  168. * Returns toolbar class names to add while rendering.
  169. *
  170. * @param {Object} props - Props object pass to React component.
  171. * @returns {Object}
  172. * @private
  173. */
  174. export function getToolbarClassNames(props: Object) {
  175. const primaryToolbarClassNames = [ 'toolbar_primary' ];
  176. const secondaryToolbarClassNames = [ 'toolbar_secondary' ];
  177. if (props._visible) {
  178. const slideInAnimation
  179. = SideContainerToggler.isVisible ? 'slideInExtX' : 'slideInX';
  180. primaryToolbarClassNames.push('fadeIn');
  181. secondaryToolbarClassNames.push(slideInAnimation);
  182. } else {
  183. const slideOutAnimation
  184. = SideContainerToggler.isVisible ? 'slideOutExtX' : 'slideOutX';
  185. primaryToolbarClassNames.push('fadeOut');
  186. secondaryToolbarClassNames.push(slideOutAnimation);
  187. }
  188. return {
  189. primaryToolbarClassName: primaryToolbarClassNames.join(' '),
  190. secondaryToolbarClassName: secondaryToolbarClassNames.join(' ')
  191. };
  192. }
  193. /**
  194. * Show custom popup/tooltip for a specified button.
  195. *
  196. * @param {string} popupSelectorID - The selector id of the popup to show.
  197. * @param {boolean} show - True or false/show or hide the popup.
  198. * @param {number} timeout - The time to show the popup.
  199. * @returns {void}
  200. */
  201. export function showCustomToolbarPopup(
  202. popupSelectorID: string,
  203. show: boolean,
  204. timeout: number) {
  205. AJS.$(popupSelectorID).tooltip({
  206. gravity: $(popupSelectorID).attr('data-popup'),
  207. html: true,
  208. title: 'title',
  209. trigger: 'manual'
  210. });
  211. if (show) {
  212. AJS.$(popupSelectorID).tooltip('show');
  213. setTimeout(
  214. () => {
  215. // hide the tooltip
  216. AJS.$(popupSelectorID).tooltip('hide');
  217. },
  218. timeout);
  219. } else {
  220. AJS.$(popupSelectorID).tooltip('hide');
  221. }
  222. }