您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

actions.js 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* globals APP, interfaceConfig */
  2. import { API_ID } from '../../../modules/API/constants';
  3. import {
  4. PostMessageTransportBackend,
  5. Transport
  6. } from '../../../modules/transport';
  7. import {
  8. getAudioOutputDeviceId,
  9. setAudioInputDevice,
  10. setAudioOutputDevice,
  11. setVideoInputDevice
  12. } from '../base/devices';
  13. import { openDialog } from '../base/dialog';
  14. import { i18next } from '../base/i18n';
  15. import JitsiMeetJS from '../base/lib-jitsi-meet';
  16. import { SET_DEVICE_SELECTION_POPUP_DATA } from './actionTypes';
  17. import { DeviceSelectionDialog } from './components';
  18. /**
  19. * Open DeviceSelectionDialog with a configuration based on the environment's
  20. * supported abilities.
  21. *
  22. * @returns {Function}
  23. */
  24. export function openDeviceSelectionDialog() {
  25. return dispatch => {
  26. if (interfaceConfig.filmStripOnly) {
  27. dispatch(_openDeviceSelectionDialogInPopup());
  28. } else {
  29. dispatch(_openDeviceSelectionDialogHere());
  30. }
  31. };
  32. }
  33. /**
  34. * Opens the DeviceSelectionDialog in the same window.
  35. *
  36. * @returns {Function}
  37. */
  38. function _openDeviceSelectionDialogHere() {
  39. return dispatch =>
  40. JitsiMeetJS.mediaDevices.isDeviceListAvailable()
  41. .then(isDeviceListAvailable => {
  42. const settings = APP.store.getState()['features/base/settings'];
  43. dispatch(openDialog(DeviceSelectionDialog, {
  44. currentAudioInputId: settings.micDeviceId,
  45. currentAudioOutputId: getAudioOutputDeviceId(),
  46. currentVideoInputId: settings.cameraDeviceId,
  47. disableAudioInputChange:
  48. !JitsiMeetJS.isMultipleAudioInputSupported(),
  49. disableDeviceChange: !isDeviceListAvailable
  50. || !JitsiMeetJS.mediaDevices.isDeviceChangeAvailable(),
  51. hasAudioPermission: JitsiMeetJS.mediaDevices
  52. .isDevicePermissionGranted.bind(null, 'audio'),
  53. hasVideoPermission: JitsiMeetJS.mediaDevices
  54. .isDevicePermissionGranted.bind(null, 'video'),
  55. hideAudioInputPreview:
  56. !JitsiMeetJS.isCollectingLocalStats(),
  57. hideAudioOutputSelect: !JitsiMeetJS.mediaDevices
  58. .isDeviceChangeAvailable('output')
  59. }));
  60. });
  61. }
  62. /**
  63. * Opens a popup window with the device selection dialog in it.
  64. *
  65. * @returns {Function}
  66. */
  67. function _openDeviceSelectionDialogInPopup() {
  68. return (dispatch, getState) => {
  69. const { popupDialogData } = getState()['features/device-selection'];
  70. if (popupDialogData) {
  71. popupDialogData.popup.focus();
  72. return;
  73. }
  74. // API_ID will always be defined because the iframe api is enabled
  75. const scope = `dialog_${API_ID}`;
  76. const url = `${
  77. window.location.origin}/static/deviceSelectionPopup.html#scope=${
  78. encodeURIComponent(JSON.stringify(scope))}`;
  79. const popup
  80. = window.open(
  81. url,
  82. 'device-selection-popup',
  83. 'toolbar=no,scrollbars=no,resizable=no,width=720,height=458');
  84. popup.addEventListener('DOMContentLoaded', () => {
  85. popup.init(i18next);
  86. });
  87. const transport = new Transport({
  88. backend: new PostMessageTransportBackend({
  89. postisOptions: {
  90. scope,
  91. window: popup
  92. }
  93. })
  94. });
  95. transport.on('request',
  96. _processRequest.bind(undefined, dispatch, getState));
  97. transport.on('event', event => {
  98. if (event.type === 'devices-dialog' && event.name === 'close') {
  99. popup.close();
  100. transport.dispose();
  101. dispatch(_setDeviceSelectionPopupData());
  102. return true;
  103. }
  104. return false;
  105. });
  106. dispatch(_setDeviceSelectionPopupData({
  107. popup,
  108. transport
  109. }));
  110. };
  111. }
  112. /**
  113. * Processes device requests from external applications.
  114. *
  115. * @param {Dispatch} dispatch - The redux {@code dispatch} function.
  116. * @param {Function} getState - The redux function that gets/retrieves the redux
  117. * state.
  118. * @param {Object} request - The request to be processed.
  119. * @param {Function} responseCallback - The callback that will send the
  120. * response.
  121. * @returns {boolean}
  122. */
  123. function _processRequest(dispatch, getState, request, responseCallback) { // eslint-disable-line max-len, max-params
  124. if (request.type === 'devices') {
  125. const state = getState();
  126. const settings = state['features/base/settings'];
  127. switch (request.name) {
  128. case 'isDeviceListAvailable':
  129. JitsiMeetJS.mediaDevices.isDeviceListAvailable()
  130. .then(isDeviceListAvailable =>
  131. responseCallback(isDeviceListAvailable))
  132. .catch(e => responseCallback(null, e));
  133. break;
  134. case 'isDeviceChangeAvailable':
  135. responseCallback(
  136. JitsiMeetJS.mediaDevices.isDeviceChangeAvailable(
  137. request.deviceType));
  138. break;
  139. case 'isMultipleAudioInputSupported':
  140. responseCallback(JitsiMeetJS.isMultipleAudioInputSupported());
  141. break;
  142. case 'getCurrentDevices':
  143. responseCallback({
  144. audioInput: settings.micDeviceId,
  145. audioOutput: getAudioOutputDeviceId(),
  146. videoInput: settings.cameraDeviceId
  147. });
  148. break;
  149. case 'getAvailableDevices':
  150. responseCallback(getState()['features/base/devices']);
  151. break;
  152. case 'setDevice': {
  153. let action;
  154. const { device } = request;
  155. switch (device.kind) {
  156. case 'audioinput':
  157. action = setAudioInputDevice;
  158. break;
  159. case 'audiooutput':
  160. action = setAudioOutputDevice;
  161. break;
  162. case 'videoinput':
  163. action = setVideoInputDevice;
  164. break;
  165. default:
  166. }
  167. dispatch(action(device.id));
  168. responseCallback(true);
  169. break;
  170. }
  171. default:
  172. return false;
  173. }
  174. return true;
  175. }
  176. return false;
  177. }
  178. /**
  179. * Sets information about device selection popup in the store.
  180. *
  181. * @param {Object} popupDialogData - Information about the popup.
  182. * @param {Object} popupDialog.popup - The popup object returned from
  183. * window.open.
  184. * @param {Object} popupDialogData.transport - The transport instance used for
  185. * communication with the popup window.
  186. * @returns {{
  187. * type: SET_DEVICE_SELECTION_POPUP_DATA,
  188. * popupDialogData: Object
  189. * }}
  190. */
  191. function _setDeviceSelectionPopupData(popupDialogData) {
  192. return {
  193. type: SET_DEVICE_SELECTION_POPUP_DATA,
  194. popupDialogData
  195. };
  196. }