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.

reducer.js 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /* @flow */
  2. import { ReducerRegistry } from '../base/redux';
  3. import {
  4. CLEAR_TOOLBOX_TIMEOUT,
  5. SET_DEFAULT_TOOLBOX_BUTTONS,
  6. SET_SUBJECT,
  7. SET_SUBJECT_SLIDE_IN,
  8. SET_TOOLBAR_BUTTON,
  9. SET_TOOLBAR_HOVERED,
  10. SET_TOOLBOX_ALWAYS_VISIBLE,
  11. SET_TOOLBOX_ENABLED,
  12. SET_TOOLBOX_TIMEOUT,
  13. SET_TOOLBOX_TIMEOUT_MS,
  14. SET_TOOLBOX_VISIBLE
  15. } from './actionTypes';
  16. declare var interfaceConfig: Object;
  17. /**
  18. * Returns initial state for toolbox's part of Redux store.
  19. *
  20. * @private
  21. * @returns {{
  22. * alwaysVisible: boolean,
  23. * hovered: boolean,
  24. * primaryToolbarButtons: Map,
  25. * secondaryToolbarButtons: Map,
  26. * subject: string,
  27. * subjectSlideIn: boolean,
  28. * timeoutID: number,
  29. * timeoutMS: number,
  30. * visible: boolean
  31. * }}
  32. */
  33. function _getInitialState() {
  34. // Default toolbox timeout for mobile app.
  35. let timeoutMS = 5000;
  36. if (typeof interfaceConfig !== 'undefined'
  37. && interfaceConfig.INITIAL_TOOLBAR_TIMEOUT) {
  38. timeoutMS = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
  39. }
  40. return {
  41. /**
  42. * The indicator which determines whether the Toolbox should always be
  43. * visible.
  44. *
  45. * @type {boolean}
  46. */
  47. alwaysVisible: false,
  48. /**
  49. * The indicator which determines whether the Toolbox is enabled. For
  50. * example, modules/UI/recording/Recording.js disables the Toolbox.
  51. *
  52. * @type {boolean}
  53. */
  54. enabled: true,
  55. /**
  56. * The indicator which determines whether a Toolbar in the Toolbox is
  57. * hovered.
  58. *
  59. * @type {boolean}
  60. */
  61. hovered: false,
  62. /**
  63. * A Map of the default buttons of the PrimaryToolbar.
  64. *
  65. * @type {Map}
  66. */
  67. primaryToolbarButtons: new Map(),
  68. /**
  69. * A Map of the default buttons of the SecondaryToolbar.
  70. *
  71. * @type {Map}
  72. */
  73. secondaryToolbarButtons: new Map(),
  74. /**
  75. * The text of the conference subject.
  76. *
  77. * @type {string}
  78. */
  79. subject: '',
  80. /**
  81. * The indicator which determines whether the subject is sliding in.
  82. *
  83. * @type {boolean}
  84. */
  85. subjectSlideIn: false,
  86. /**
  87. * A number, non-zero value which identifies the timer created by a call
  88. * to setTimeout() with timeoutMS.
  89. *
  90. * @type {number|null}
  91. */
  92. timeoutID: null,
  93. /**
  94. * The delay in milliseconds before timeoutID executes (after its
  95. * initialization).
  96. *
  97. * @type {number}
  98. */
  99. timeoutMS,
  100. /**
  101. * The indicator which determines whether the Toolbox is visible.
  102. *
  103. * @type {boolean}
  104. */
  105. visible: false
  106. };
  107. }
  108. ReducerRegistry.register(
  109. 'features/toolbox',
  110. (state: Object = _getInitialState(), action: Object) => {
  111. switch (action.type) {
  112. case CLEAR_TOOLBOX_TIMEOUT:
  113. return {
  114. ...state,
  115. timeoutID: undefined
  116. };
  117. case SET_DEFAULT_TOOLBOX_BUTTONS: {
  118. const { primaryToolbarButtons, secondaryToolbarButtons } = action;
  119. return {
  120. ...state,
  121. primaryToolbarButtons,
  122. secondaryToolbarButtons
  123. };
  124. }
  125. case SET_SUBJECT:
  126. return {
  127. ...state,
  128. subject: action.subject
  129. };
  130. case SET_SUBJECT_SLIDE_IN:
  131. return {
  132. ...state,
  133. subjectSlideIn: action.subjectSlideIn
  134. };
  135. case SET_TOOLBAR_BUTTON:
  136. return _setButton(state, action);
  137. case SET_TOOLBAR_HOVERED:
  138. return {
  139. ...state,
  140. hovered: action.hovered
  141. };
  142. case SET_TOOLBOX_ALWAYS_VISIBLE:
  143. return {
  144. ...state,
  145. alwaysVisible: action.alwaysVisible
  146. };
  147. case SET_TOOLBOX_ENABLED:
  148. return {
  149. ...state,
  150. enabled: action.enabled
  151. };
  152. case SET_TOOLBOX_TIMEOUT:
  153. return {
  154. ...state,
  155. timeoutID: action.timeoutID,
  156. timeoutMS: action.timeoutMS
  157. };
  158. case SET_TOOLBOX_TIMEOUT_MS:
  159. return {
  160. ...state,
  161. timeoutMS: action.timeoutMS
  162. };
  163. case SET_TOOLBOX_VISIBLE:
  164. return {
  165. ...state,
  166. visible: action.visible
  167. };
  168. }
  169. return state;
  170. });
  171. /**
  172. * Sets new value of the button.
  173. *
  174. * @param {Object} state - Redux state.
  175. * @param {Object} action - Dispatched action.
  176. * @param {Object} action.button - Object describing toolbar button.
  177. * @param {Object} action.buttonName - The name of the button.
  178. * @private
  179. * @returns {Object}
  180. */
  181. function _setButton(state, { button, buttonName }): Object {
  182. const { primaryToolbarButtons, secondaryToolbarButtons } = state;
  183. let selectedButton = primaryToolbarButtons.get(buttonName);
  184. let place = 'primaryToolbarButtons';
  185. if (!selectedButton) {
  186. selectedButton = secondaryToolbarButtons.get(buttonName);
  187. place = 'secondaryToolbarButtons';
  188. }
  189. selectedButton = {
  190. ...selectedButton,
  191. ...button
  192. };
  193. // In filmstrip-only mode we only show buttons if they're filmstrip-only
  194. // enabled, so we don't need to update if this isn't the case.
  195. // FIXME A reducer should be a pure function of the current state and the
  196. // specified action so it should not use the global variable
  197. // interfaceConfig. Anyway, we'll move interfaceConfig into the (redux)
  198. // store so we'll surely revisit the source code bellow.
  199. if (interfaceConfig.filmStripOnly && !selectedButton.filmstripOnlyEnabled) {
  200. return {
  201. ...state
  202. };
  203. }
  204. const updatedToolbar = state[place].set(buttonName, selectedButton);
  205. return {
  206. ...state,
  207. [place]: new Map(updatedToolbar)
  208. };
  209. }