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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // @flow
  2. import {
  3. MEDIA_TYPE,
  4. SET_AUDIO_AVAILABLE,
  5. SET_VIDEO_AVAILABLE
  6. } from '../base/media';
  7. import { MiddlewareRegistry } from '../base/redux';
  8. import { isLocalTrackMuted, TRACK_UPDATED } from '../base/tracks';
  9. import { setToolbarButton, toggleFullScreen } from './actions';
  10. import {
  11. CLEAR_TOOLBOX_TIMEOUT,
  12. FULL_SCREEN_CHANGED,
  13. SET_TOOLBOX_TIMEOUT,
  14. SET_FULL_SCREEN
  15. } from './actionTypes';
  16. declare var APP: Object;
  17. /**
  18. * Middleware which intercepts Toolbox actions to handle changes to the
  19. * visibility timeout of the Toolbox.
  20. *
  21. * @param {Store} store - The redux store.
  22. * @returns {Function}
  23. */
  24. MiddlewareRegistry.register(store => next => action => {
  25. switch (action.type) {
  26. case CLEAR_TOOLBOX_TIMEOUT: {
  27. const { timeoutID } = store.getState()['features/toolbox'];
  28. clearTimeout(timeoutID);
  29. break;
  30. }
  31. case FULL_SCREEN_CHANGED:
  32. return _fullScreenChanged(store, next, action);
  33. case SET_AUDIO_AVAILABLE:
  34. return _setMediaAvailableOrMuted(store, next, action);
  35. case SET_FULL_SCREEN:
  36. return _setFullScreen(next, action);
  37. case SET_TOOLBOX_TIMEOUT: {
  38. const { timeoutID } = store.getState()['features/toolbox'];
  39. const { handler, timeoutMS } = action;
  40. clearTimeout(timeoutID);
  41. const newTimeoutId = setTimeout(handler, timeoutMS);
  42. action.timeoutID = newTimeoutId;
  43. break;
  44. }
  45. case SET_VIDEO_AVAILABLE:
  46. return _setMediaAvailableOrMuted(store, next, action);
  47. case TRACK_UPDATED:
  48. if (action.track.jitsiTrack.isLocal()) {
  49. return _setMediaAvailableOrMuted(store, next, action);
  50. }
  51. break;
  52. }
  53. return next(action);
  54. });
  55. /**
  56. * Updates the the redux state with the current known state of full screen.
  57. *
  58. * @param {Store} store - The redux store in which the specified action is being
  59. * dispatched.
  60. * @param {Dispatch} next - The redux dispatch function to dispatch the
  61. * specified action to the specified store.
  62. * @param {Action} action - The redux action FULL_SCREEN_CHANGED which is being
  63. * dispatched in the specified store.
  64. * @private
  65. * @returns {Object} The value returned by {@code next(action)}.
  66. */
  67. function _fullScreenChanged({ dispatch }, next, action) {
  68. if (typeof APP === 'object') {
  69. dispatch(toggleFullScreen(action.fullScreen));
  70. }
  71. return next(action);
  72. }
  73. /**
  74. * Adjusts the state of toolbar's microphone or camera button.
  75. *
  76. * @param {Store} store - The redux store.
  77. * @param {Function} next - The redux function to continue dispatching the
  78. * specified {@code action} in the specified {@code store}.
  79. * @param {Object} action - {@code SET_AUDIO_AVAILABLE},
  80. * {@code SET_VIDEO_AVAILABLE}, or {@code TRACK_UPDATED}.
  81. * @returns {*}
  82. */
  83. function _setMediaAvailableOrMuted({ dispatch, getState }, next, action) {
  84. const result = next(action);
  85. let mediaType;
  86. switch (action.type) {
  87. case SET_AUDIO_AVAILABLE:
  88. mediaType = MEDIA_TYPE.AUDIO;
  89. break;
  90. case SET_VIDEO_AVAILABLE:
  91. mediaType = MEDIA_TYPE.VIDEO;
  92. break;
  93. case TRACK_UPDATED:
  94. mediaType
  95. = action.track.jitsiTrack.isAudioTrack()
  96. ? MEDIA_TYPE.AUDIO
  97. : MEDIA_TYPE.VIDEO;
  98. break;
  99. default:
  100. throw new Error(`Unsupported action ${action}`);
  101. }
  102. const state = getState();
  103. const { audio, video } = state['features/base/media'];
  104. const { available } = mediaType === MEDIA_TYPE.AUDIO ? audio : video;
  105. const i18nKey
  106. = mediaType === MEDIA_TYPE.AUDIO
  107. ? available ? 'mute' : 'micDisabled'
  108. : available ? 'videomute' : 'cameraDisabled';
  109. const tracks = state['features/base/tracks'];
  110. const muted = isLocalTrackMuted(tracks, mediaType);
  111. dispatch(
  112. setToolbarButton(
  113. mediaType === MEDIA_TYPE.AUDIO ? 'microphone' : 'camera',
  114. {
  115. enabled: available,
  116. i18n: `[content]toolbar.${i18nKey}`,
  117. toggled: available ? muted : true
  118. }));
  119. return result;
  120. }
  121. /**
  122. * Makes an external request to enter or exit full screen mode.
  123. *
  124. * @param {Dispatch} next - The redux dispatch function to dispatch the
  125. * specified action to the specified store.
  126. * @param {Action} action - The redux action SET_FULL_SCREEN which is being
  127. * dispatched in the specified store.
  128. * @private
  129. * @returns {Object} The value returned by {@code next(action)}.
  130. */
  131. function _setFullScreen(next, action) {
  132. if (typeof APP === 'object') {
  133. const { fullScreen } = action;
  134. if (fullScreen) {
  135. const documentElement = document.documentElement || {};
  136. if (typeof documentElement.requestFullscreen === 'function') {
  137. documentElement.requestFullscreen();
  138. } else if (
  139. typeof documentElement.msRequestFullscreen === 'function') {
  140. documentElement.msRequestFullscreen();
  141. } else if (
  142. typeof documentElement.mozRequestFullScreen === 'function') {
  143. documentElement.mozRequestFullScreen();
  144. } else if (
  145. typeof documentElement.webkitRequestFullscreen === 'function') {
  146. documentElement.webkitRequestFullscreen();
  147. }
  148. } else if (typeof document.exitFullscreen === 'function') {
  149. document.exitFullscreen();
  150. } else if (typeof document.msExitFullscreen === 'function') {
  151. document.msExitFullscreen();
  152. } else if (typeof document.mozCancelFullScreen === 'function') {
  153. document.mozCancelFullScreen();
  154. } else if (typeof document.webkitExitFullscreen === 'function') {
  155. document.webkitExitFullscreen();
  156. }
  157. }
  158. return next(action);
  159. }