fix(iframe-api-devices): Misc small issues.

This commit is contained in:
Hristo Terezov 2019-03-28 16:29:30 +00:00
parent f2e0704b93
commit 829e5597d5
13 changed files with 148 additions and 155 deletions

View File

@ -2417,7 +2417,7 @@ export default {
*/
updateAudioIconEnabled() {
const audioMediaDevices
= APP.store.getState()['features/base/devices'].devices.audioInput;
= APP.store.getState()['features/base/devices'].availableDevices.audioInput;
const audioDeviceCount
= audioMediaDevices ? audioMediaDevices.length : 0;
@ -2440,7 +2440,7 @@ export default {
*/
updateVideoIconEnabled() {
const videoMediaDevices
= APP.store.getState()['features/base/devices'].devices.videoInput;
= APP.store.getState()['features/base/devices'].availableDevices.videoInput;
const videoDeviceCount
= videoMediaDevices ? videoMediaDevices.length : 0;

View File

@ -81,7 +81,7 @@ var api = new JitsiMeetExternalAPI(domain, options);
### Controlling the embedded Jitsi Meet Conference
You can control the available devices with the following methods of `JitsiMeetExternalAPI` instance:
Device management `JitsiMeetExternalAPI` methods:
* **getAvailableDevices** - Retrieve a list of available devices.
```javascript
@ -151,7 +151,7 @@ api.isDeviceListAvailable().then(function(isDeviceListAvailable) {
...
});
```
* **isMultipleAudioInputSupported** - Resolves with true if the device list is available and with false if not.
* **isMultipleAudioInputSupported** - Resolves with true if multiple audio input is supported and with false if not.
```javascript
api.isMultipleAudioInputSupported().then(function(isMultipleAudioInputSupported) {

View File

@ -12,7 +12,7 @@ import { getJitsiMeetTransport } from '../transport';
import { API_ID } from './constants';
import {
processRequest
processExternalDeviceRequest
} from '../../react/features/device-selection/functions';
const logger = require('jitsi-meet-logger').getLogger(__filename);
@ -122,7 +122,7 @@ function initCommands() {
transport.on('request', (request, callback) => {
const { dispatch, getState } = APP.store;
if (processRequest(dispatch, getState, request, callback)) {
if (processExternalDeviceRequest(dispatch, getState, request, callback)) {
return true;
}

View File

@ -609,7 +609,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
}
/**
* Returns Promise that resolves with result an list of available devices.
* Returns Promise that resolves with a list of available devices.
*
* @returns {Promise}
*/
@ -661,7 +661,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
}
/**
* Returns Promise that resolves with true if the device list is available
* Returns Promise that resolves with true if multiple audio input is supported
* and with false if not.
*
* @returns {Promise}
@ -837,33 +837,39 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
}
/**
* Sets the audio input device to the one with the id that is passed.
* Sets the audio input device to the one with the label or id that is
* passed.
*
* @param {string} label - The label of the new device.
* @param {string} deviceId - The id of the new device.
* @returns {Promise}
*/
setAudioInputDevice(deviceId) {
return setAudioInputDevice(this._transport, deviceId);
setAudioInputDevice(label, deviceId) {
return setAudioInputDevice(this._transport, label, deviceId);
}
/**
* Sets the audio output device to the one with the id that is passed.
* Sets the audio output device to the one with the label or id that is
* passed.
*
* @param {string} label - The label of the new device.
* @param {string} deviceId - The id of the new device.
* @returns {Promise}
*/
setAudioOutputDevice(deviceId) {
return setAudioOutputDevice(this._transport, deviceId);
setAudioOutputDevice(label, deviceId) {
return setAudioOutputDevice(this._transport, label, deviceId);
}
/**
* Sets the video input device to the one with the id that is passed.
* Sets the video input device to the one with the label or id that is
* passed.
*
* @param {string} label - The label of the new device.
* @param {string} deviceId - The id of the new device.
* @returns {Promise}
*/
setVideoInputDevice(deviceId) {
return setVideoInputDevice(this._transport, deviceId);
setVideoInputDevice(label, deviceId) {
return setVideoInputDevice(this._transport, label, deviceId);
}
/**

View File

@ -55,10 +55,6 @@ export function isDeviceChangeAvailable(transport: Object, deviceType: string) {
deviceType,
type: 'devices',
name: 'isDeviceChangeAvailable'
}).catch(e => {
logger.error(e);
return false;
});
}
@ -74,15 +70,11 @@ export function isDeviceListAvailable(transport: Object) {
return transport.sendRequest({
type: 'devices',
name: 'isDeviceListAvailable'
}).catch(e => {
logger.error(e);
return false;
});
}
/**
* Returns Promise that resolves with true if the device list is available
* Returns Promise that resolves with true if multiple audio input is supported
* and with false if not.
*
* @param {Transport} transport - The @code{Transport} instance responsible for
@ -93,10 +85,6 @@ export function isMultipleAudioInputSupported(transport: Object) {
return transport.sendRequest({
type: 'devices',
name: 'isMultipleAudioInputSupported'
}).catch(e => {
logger.error(e);
return false;
});
}

View File

@ -46,8 +46,7 @@ export const ADD_PENDING_DEVICE_REQUEST = 'ADD_PENDING_DEVICE_REQUEST';
* The type of Redux action which will remove all pending device requests.
*
* {
* type: REMOVE_PENDING_DEVICE_REQUESTS,
* request: Object
* type: REMOVE_PENDING_DEVICE_REQUESTS
* }
*/
export const REMOVE_PENDING_DEVICE_REQUESTS = 'REMOVE_PENDING_DEVICE_REQUESTS';

View File

@ -15,12 +15,13 @@ declare var APP: Object;
* otherwise.
*/
export function areDeviceLabelsInitialized(state: Object) {
// TODO: Replace with something that doesn't use APP when the conference.js logic is reactified.
if (APP.conference._localTracksInitialized) {
return true;
}
for (const type of [ 'audioInput', 'audioOutput', 'videoInput' ]) {
if (state['features/base/devices'].devices[type].find(d => Boolean(d.label))) {
if ((state['features/base/devices'].availableDevices[type] || []).find(d => Boolean(d.label))) {
return true;
}
}
@ -50,7 +51,7 @@ export function getDeviceIdByLabel(state: Object, label: string) {
for (const type of types) {
const device
= state['features/base/devices'].devices[type]
= (state['features/base/devices'].availableDevices[type] || [])
.find(d => d.label === label);
if (device) {

View File

@ -1,7 +1,7 @@
/* global APP */
import { CONFERENCE_JOINED } from '../conference';
import { processRequest } from '../../device-selection';
import { processExternalDeviceRequest } from '../../device-selection';
import { MiddlewareRegistry } from '../redux';
import UIEvents from '../../../../service/UI/UIEvents';
@ -53,7 +53,7 @@ function _conferenceJoined({ dispatch, getState }, next, action) {
const { pendingRequests } = state['features/base/devices'];
pendingRequests.forEach(request => {
processRequest(
processExternalDeviceRequest(
dispatch,
getState,
request,

View File

@ -10,7 +10,7 @@ import { groupDevicesByKind } from './functions';
import { ReducerRegistry } from '../redux';
const DEFAULT_STATE = {
devices: {
availableDevices: {
audioInput: [],
audioOutput: [],
videoInput: []
@ -37,7 +37,7 @@ ReducerRegistry.register(
return {
...state,
devices: deviceList
availableDevices: deviceList
};
}

View File

@ -14,7 +14,7 @@ import { i18next } from '../base/i18n';
import { updateSettings } from '../base/settings';
import { SET_DEVICE_SELECTION_POPUP_DATA } from './actionTypes';
import { getDeviceSelectionDialogProps, processRequest } from './functions';
import { getDeviceSelectionDialogProps, processExternalDeviceRequest } from './functions';
const logger = require('jitsi-meet-logger').getLogger(__filename);
@ -58,7 +58,7 @@ export function openDeviceSelectionPopup() {
});
transport.on('request',
processRequest.bind(undefined, dispatch, getState));
processExternalDeviceRequest.bind(undefined, dispatch, getState));
transport.on('event', event => {
if (event.type === 'devices-dialog' && event.name === 'close') {
popup.close();

View File

@ -28,7 +28,7 @@ export function getDeviceSelectionDialogProps(stateful: Object | Function) {
const settings = state['features/base/settings'];
return {
availableDevices: state['features/base/devices'].devices,
availableDevices: state['features/base/devices'].availableDevices,
disableAudioInputChange:
!JitsiMeetJS.isMultipleAudioInputSupported(),
disableDeviceChange:
@ -52,133 +52,132 @@ export function getDeviceSelectionDialogProps(stateful: Object | Function) {
* @param {Object} request - The request to be processed.
* @param {Function} responseCallback - The callback that will send the
* response.
* @returns {boolean}
* @returns {boolean} - True if the request has been processed and false otherwise.
*/
export function processRequest( // eslint-disable-line max-params
export function processExternalDeviceRequest( // eslint-disable-line max-params
dispatch: Dispatch<any>,
getState: Function,
request: Object,
responseCallback: Function) {
if (request.type === 'devices') {
const state = getState();
const settings = state['features/base/settings'];
const { conference } = state['features/base/conference'];
let result = true;
if (request.type !== 'devices') {
return false;
}
const state = getState();
const settings = state['features/base/settings'];
const { conference } = state['features/base/conference'];
let result = true;
switch (request.name) {
case 'isDeviceListAvailable':
responseCallback(JitsiMeetJS.mediaDevices.isDeviceListAvailable());
break;
case 'isDeviceChangeAvailable':
responseCallback(
JitsiMeetJS.mediaDevices.isDeviceChangeAvailable(
request.deviceType));
break;
case 'isMultipleAudioInputSupported':
responseCallback(JitsiMeetJS.isMultipleAudioInputSupported());
break;
case 'getCurrentDevices':
dispatch(getAvailableDevices()).then(devices => {
if (areDeviceLabelsInitialized(state)) {
let audioInput, audioOutput, videoInput;
const audioOutputDeviceId = getAudioOutputDeviceId();
const { cameraDeviceId, micDeviceId } = settings;
switch (request.name) {
case 'isDeviceListAvailable':
responseCallback(JitsiMeetJS.mediaDevices.isDeviceListAvailable());
break;
case 'isDeviceChangeAvailable':
responseCallback(
JitsiMeetJS.mediaDevices.isDeviceChangeAvailable(
request.deviceType));
break;
case 'isMultipleAudioInputSupported':
responseCallback(JitsiMeetJS.isMultipleAudioInputSupported());
break;
case 'getCurrentDevices':
dispatch(getAvailableDevices()).then(devices => {
if (areDeviceLabelsInitialized(state)) {
let audioInput, audioOutput, videoInput;
const audioOutputDeviceId = getAudioOutputDeviceId();
const { cameraDeviceId, micDeviceId } = settings;
devices.forEach(device => {
const { deviceId } = device;
devices.forEach(device => {
const { deviceId } = device;
switch (deviceId) {
case micDeviceId:
audioInput = device;
break;
case audioOutputDeviceId:
audioOutput = device;
break;
case cameraDeviceId:
videoInput = device;
break;
}
});
switch (deviceId) {
case micDeviceId:
audioInput = device;
break;
case audioOutputDeviceId:
audioOutput = device;
break;
case cameraDeviceId:
videoInput = device;
break;
}
});
responseCallback({
audioInput,
audioOutput,
videoInput
});
} else {
// The labels are not available if the A/V permissions are
// not yet granted.
dispatch(addPendingDeviceRequest({
type: 'devices',
name: 'getCurrentDevices',
responseCallback
}));
}
});
break;
case 'getAvailableDevices':
dispatch(getAvailableDevices()).then(devices => {
if (areDeviceLabelsInitialized(state)) {
responseCallback(groupDevicesByKind(devices));
} else {
// The labels are not available if the A/V permissions are
// not yet granted.
dispatch(addPendingDeviceRequest({
type: 'devices',
name: 'getAvailableDevices',
responseCallback
}));
}
});
break;
case 'setDevice': {
const { device } = request;
if (!conference) {
responseCallback({
audioInput,
audioOutput,
videoInput
});
} else {
// The labels are not available if the A/V permissions are
// not yet granted.
dispatch(addPendingDeviceRequest({
type: 'devices',
name: 'setDevice',
device,
name: 'getCurrentDevices',
responseCallback
}));
return true;
}
});
const { label, id } = device;
const deviceId = label ? getDeviceIdByLabel(state, device.label) : id;
if (deviceId) {
switch (device.kind) {
case 'audioinput': {
dispatch(setAudioInputDevice(deviceId));
break;
}
case 'audiooutput':
setAudioOutputDeviceId(deviceId, dispatch);
break;
case 'videoinput':
dispatch(setVideoInputDevice(deviceId));
break;
default:
result = false;
}
break;
case 'getAvailableDevices':
dispatch(getAvailableDevices()).then(devices => {
if (areDeviceLabelsInitialized(state)) {
responseCallback(groupDevicesByKind(devices));
} else {
// The labels are not available if the A/V permissions are
// not yet granted.
dispatch(addPendingDeviceRequest({
type: 'devices',
name: 'getAvailableDevices',
responseCallback
}));
}
});
break;
case 'setDevice': {
const { device } = request;
if (!conference) {
dispatch(addPendingDeviceRequest({
type: 'devices',
name: 'setDevice',
device,
responseCallback
}));
return true;
}
const { label, id } = device;
const deviceId = label ? getDeviceIdByLabel(state, device.label) : id;
if (deviceId) {
switch (device.kind) {
case 'audioinput': {
dispatch(setAudioInputDevice(deviceId));
break;
}
case 'audiooutput':
setAudioOutputDeviceId(deviceId, dispatch);
break;
case 'videoinput':
dispatch(setVideoInputDevice(deviceId));
break;
default:
result = false;
}
responseCallback(result);
break;
}
default:
return false;
} else {
result = false;
}
return true;
responseCallback(result);
break;
}
default:
return false;
}
return false;
return true;
}

View File

@ -18,17 +18,17 @@ MiddlewareRegistry.register(store => next => action => {
if (action.type === UPDATE_DEVICE_LIST) {
const state = store.getState();
const { popupDialogData } = state['features/device-selection'];
const { devices } = state['features/base/devices'];
const { availableDevices } = state['features/base/devices'];
if (popupDialogData) {
popupDialogData.transport.sendEvent({
name: 'deviceListChanged',
devices
devices: availableDevices
});
}
if (typeof APP !== 'undefined') {
APP.API.notifyDeviceListChanged(devices);
APP.API.notifyDeviceListChanged(availableDevices);
}
}

View File

@ -175,7 +175,7 @@ export default class DeviceSelectionPopup {
* @returns {Promise}
*/
_isDeviceChangeAvailable(deviceType) {
return isDeviceChangeAvailable(this._transport, deviceType);
return isDeviceChangeAvailable(this._transport, deviceType).catch(() => false);
}
/**
@ -185,17 +185,17 @@ export default class DeviceSelectionPopup {
* @returns {Promise}
*/
_isDeviceListAvailable() {
return isDeviceListAvailable(this._transport);
return isDeviceListAvailable(this._transport).catch(() => false);
}
/**
* Returns Promise that resolves with true if the device list is available
* Returns Promise that resolves with true if multiple audio input is supported
* and with false if not.
*
* @returns {Promise}
*/
_isMultipleAudioInputSupported() {
return isMultipleAudioInputSupported(this._transport);
return isMultipleAudioInputSupported(this._transport).catch(() => false);
}
/**