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.

actions.js 6.1KB

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