Merge branch 'feature-settings' into develop
|
|
@ -20,9 +20,8 @@ const ROOM_OPTIONS =
|
||||||
|
|
||||||
const VIDEO_CONSTRAINS =
|
const VIDEO_CONSTRAINS =
|
||||||
{
|
{
|
||||||
qvga : { width: { ideal: 320 }, height: { ideal: 240 }, aspectRatio: 1.334 },
|
width : { ideal: 1280 },
|
||||||
vga : { width: { ideal: 640 }, height: { ideal: 480 }, aspectRatio: 1.334 },
|
aspectRatio : 1.334
|
||||||
hd : { width: { ideal: 800 }, height: { ideal: 600 }, aspectRatio: 1.334 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class RoomClient
|
export default class RoomClient
|
||||||
|
|
@ -55,6 +54,9 @@ export default class RoomClient
|
||||||
// Redux store getState function.
|
// Redux store getState function.
|
||||||
this._getState = getState;
|
this._getState = getState;
|
||||||
|
|
||||||
|
// This device
|
||||||
|
this._device = device;
|
||||||
|
|
||||||
// My peer name.
|
// My peer name.
|
||||||
this._peerName = peerName;
|
this._peerName = peerName;
|
||||||
|
|
||||||
|
|
@ -79,7 +81,9 @@ export default class RoomClient
|
||||||
|
|
||||||
// Map of webcam MediaDeviceInfos indexed by deviceId.
|
// Map of webcam MediaDeviceInfos indexed by deviceId.
|
||||||
// @type {Map<String, MediaDeviceInfos>}
|
// @type {Map<String, MediaDeviceInfos>}
|
||||||
this._webcams = new Map();
|
this._webcams = {};
|
||||||
|
|
||||||
|
this._audioDevices = {};
|
||||||
|
|
||||||
// Local Webcam. Object with:
|
// Local Webcam. Object with:
|
||||||
// - {MediaDeviceInfo} [device]
|
// - {MediaDeviceInfo} [device]
|
||||||
|
|
@ -89,6 +93,10 @@ export default class RoomClient
|
||||||
resolution : 'hd'
|
resolution : 'hd'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._audioDevice = {
|
||||||
|
device : null
|
||||||
|
};
|
||||||
|
|
||||||
this._screenSharing = ScreenShare.create();
|
this._screenSharing = ScreenShare.create();
|
||||||
|
|
||||||
this._screenSharingProducer = null;
|
this._screenSharingProducer = null;
|
||||||
|
|
@ -117,6 +125,8 @@ export default class RoomClient
|
||||||
|
|
||||||
login()
|
login()
|
||||||
{
|
{
|
||||||
|
this._dispatch(stateActions.setLoginInProgress(true));
|
||||||
|
|
||||||
const url = `/login?roomId=${this._room.roomId}&peerName=${this._peerName}`;
|
const url = `/login?roomId=${this._room.roomId}&peerName=${this._peerName}`;
|
||||||
|
|
||||||
this._loginWindow = window.open(url, 'loginWindow');
|
this._loginWindow = window.open(url, 'loginWindow');
|
||||||
|
|
@ -366,9 +376,75 @@ export default class RoomClient
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
changeWebcam()
|
changeAudioDevice(deviceId)
|
||||||
{
|
{
|
||||||
logger.debug('changeWebcam()');
|
logger.debug('changeAudioDevice() [deviceId: %s]', deviceId);
|
||||||
|
|
||||||
|
this._dispatch(
|
||||||
|
stateActions.setAudioInProgress(true));
|
||||||
|
|
||||||
|
return Promise.resolve()
|
||||||
|
.then(() =>
|
||||||
|
{
|
||||||
|
this._audioDevice.device = this._audioDevices[deviceId];
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
'changeAudioDevice() | new selected webcam [device:%o]',
|
||||||
|
this._audioDevice.device);
|
||||||
|
})
|
||||||
|
.then(() =>
|
||||||
|
{
|
||||||
|
const { device } = this._audioDevice;
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
throw new Error('no audio devices');
|
||||||
|
|
||||||
|
logger.debug('changeAudioDevice() | calling getUserMedia()');
|
||||||
|
|
||||||
|
return navigator.mediaDevices.getUserMedia(
|
||||||
|
{
|
||||||
|
audio :
|
||||||
|
{
|
||||||
|
deviceId : { exact: device.deviceId }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then((stream) =>
|
||||||
|
{
|
||||||
|
const track = stream.getAudioTracks()[0];
|
||||||
|
|
||||||
|
return this._micProducer.replaceTrack(track)
|
||||||
|
.then((newTrack) =>
|
||||||
|
{
|
||||||
|
track.stop();
|
||||||
|
|
||||||
|
return newTrack;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then((newTrack) =>
|
||||||
|
{
|
||||||
|
this._dispatch(
|
||||||
|
stateActions.setProducerTrack(this._micProducer.id, newTrack));
|
||||||
|
|
||||||
|
return this._updateAudioDevices();
|
||||||
|
})
|
||||||
|
.then(() =>
|
||||||
|
{
|
||||||
|
this._dispatch(
|
||||||
|
stateActions.setAudioInProgress(false));
|
||||||
|
})
|
||||||
|
.catch((error) =>
|
||||||
|
{
|
||||||
|
logger.error('changeAudioDevice() failed: %o', error);
|
||||||
|
|
||||||
|
this._dispatch(
|
||||||
|
stateActions.setAudioInProgress(false));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
changeWebcam(deviceId)
|
||||||
|
{
|
||||||
|
logger.debug('changeWebcam() [deviceId: %s]', deviceId);
|
||||||
|
|
||||||
this._dispatch(
|
this._dispatch(
|
||||||
stateActions.setWebcamInProgress(true));
|
stateActions.setWebcamInProgress(true));
|
||||||
|
|
@ -376,22 +452,7 @@ export default class RoomClient
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
.then(() =>
|
.then(() =>
|
||||||
{
|
{
|
||||||
return this._updateWebcams();
|
this._webcam.device = this._webcams[deviceId];
|
||||||
})
|
|
||||||
.then(() =>
|
|
||||||
{
|
|
||||||
const array = Array.from(this._webcams.keys());
|
|
||||||
const len = array.length;
|
|
||||||
const deviceId =
|
|
||||||
this._webcam.device ? this._webcam.device.deviceId : undefined;
|
|
||||||
let idx = array.indexOf(deviceId);
|
|
||||||
|
|
||||||
if (idx < len - 1)
|
|
||||||
idx++;
|
|
||||||
else
|
|
||||||
idx = 0;
|
|
||||||
|
|
||||||
this._webcam.device = this._webcams.get(array[idx]);
|
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'changeWebcam() | new selected webcam [device:%o]',
|
'changeWebcam() | new selected webcam [device:%o]',
|
||||||
|
|
@ -402,7 +463,7 @@ export default class RoomClient
|
||||||
})
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
{
|
{
|
||||||
const { device, resolution } = this._webcam;
|
const { device } = this._webcam;
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
throw new Error('no webcam devices');
|
throw new Error('no webcam devices');
|
||||||
|
|
@ -414,7 +475,7 @@ export default class RoomClient
|
||||||
video :
|
video :
|
||||||
{
|
{
|
||||||
deviceId : { exact: device.deviceId },
|
deviceId : { exact: device.deviceId },
|
||||||
...VIDEO_CONSTRAINS[resolution]
|
...VIDEO_CONSTRAINS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
@ -435,6 +496,10 @@ export default class RoomClient
|
||||||
this._dispatch(
|
this._dispatch(
|
||||||
stateActions.setProducerTrack(this._webcamProducer.id, newTrack));
|
stateActions.setProducerTrack(this._webcamProducer.id, newTrack));
|
||||||
|
|
||||||
|
return this._updateWebcams();
|
||||||
|
})
|
||||||
|
.then(() =>
|
||||||
|
{
|
||||||
this._dispatch(
|
this._dispatch(
|
||||||
stateActions.setWebcamInProgress(false));
|
stateActions.setWebcamInProgress(false));
|
||||||
})
|
})
|
||||||
|
|
@ -479,7 +544,7 @@ export default class RoomClient
|
||||||
})
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
{
|
{
|
||||||
const { device, resolution } = this._webcam;
|
const { device } = this._webcam;
|
||||||
|
|
||||||
logger.debug('changeWebcamResolution() | calling getUserMedia()');
|
logger.debug('changeWebcamResolution() | calling getUserMedia()');
|
||||||
|
|
||||||
|
|
@ -488,7 +553,7 @@ export default class RoomClient
|
||||||
video :
|
video :
|
||||||
{
|
{
|
||||||
deviceId : { exact: device.deviceId },
|
deviceId : { exact: device.deviceId },
|
||||||
...VIDEO_CONSTRAINS[resolution]
|
...VIDEO_CONSTRAINS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
@ -935,6 +1000,8 @@ export default class RoomClient
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
this.closeLoginWindow();
|
this.closeLoginWindow();
|
||||||
|
|
||||||
|
this._dispatch(stateActions.setLoginInProgress(false));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1163,6 +1230,12 @@ export default class RoomClient
|
||||||
let producer;
|
let producer;
|
||||||
|
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
|
.then(() =>
|
||||||
|
{
|
||||||
|
logger.debug('_setMicProducer() | calling _updateAudioDevices()');
|
||||||
|
|
||||||
|
return this._updateAudioDevices();
|
||||||
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
{
|
{
|
||||||
logger.debug('_setMicProducer() | calling getUserMedia()');
|
logger.debug('_setMicProducer() | calling getUserMedia()');
|
||||||
|
|
@ -1380,7 +1453,7 @@ export default class RoomClient
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
.then(() =>
|
.then(() =>
|
||||||
{
|
{
|
||||||
const { device, resolution } = this._webcam;
|
const { device } = this._webcam;
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
throw new Error('no webcam devices');
|
throw new Error('no webcam devices');
|
||||||
|
|
@ -1392,7 +1465,7 @@ export default class RoomClient
|
||||||
video :
|
video :
|
||||||
{
|
{
|
||||||
deviceId : { exact: device.deviceId },
|
deviceId : { exact: device.deviceId },
|
||||||
...VIDEO_CONSTRAINS[resolution]
|
...VIDEO_CONSTRAINS
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
@ -1482,12 +1555,64 @@ export default class RoomClient
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updateAudioDevices()
|
||||||
|
{
|
||||||
|
logger.debug('_updateAudioDevices()');
|
||||||
|
|
||||||
|
// Reset the list.
|
||||||
|
this._audioDevices = {};
|
||||||
|
|
||||||
|
return Promise.resolve()
|
||||||
|
.then(() =>
|
||||||
|
{
|
||||||
|
logger.debug('_updateAudioDevices() | calling enumerateDevices()');
|
||||||
|
|
||||||
|
return navigator.mediaDevices.enumerateDevices();
|
||||||
|
})
|
||||||
|
.then((devices) =>
|
||||||
|
{
|
||||||
|
for (const device of devices)
|
||||||
|
{
|
||||||
|
if (device.kind !== 'audioinput')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
this._audioDevices[device.deviceId] = {
|
||||||
|
value : device.deviceId,
|
||||||
|
label : device.label,
|
||||||
|
deviceId : device.deviceId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() =>
|
||||||
|
{
|
||||||
|
const currentAudioDeviceId =
|
||||||
|
this._audioDevice.device ? this._audioDevice.device.deviceId : undefined;
|
||||||
|
|
||||||
|
logger.debug('_updateAudioDevices() [audiodevices:%o]', this._audioDevices);
|
||||||
|
|
||||||
|
const len = Object.keys(this._audioDevices).length;
|
||||||
|
|
||||||
|
if (len === 0)
|
||||||
|
this._audioDevice.device = null;
|
||||||
|
else if (!this._audioDevices[currentAudioDeviceId])
|
||||||
|
for (this._audioDevice.device in this._audioDevices)
|
||||||
|
if (this._audioDevices.hasOwnProperty(this._audioDevice.device))
|
||||||
|
break;
|
||||||
|
|
||||||
|
this._dispatch(
|
||||||
|
stateActions.setCanChangeAudioDevice(len >= 2));
|
||||||
|
if (len >= 1)
|
||||||
|
this._dispatch(
|
||||||
|
stateActions.setAudioDevices(this._audioDevices));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_updateWebcams()
|
_updateWebcams()
|
||||||
{
|
{
|
||||||
logger.debug('_updateWebcams()');
|
logger.debug('_updateWebcams()');
|
||||||
|
|
||||||
// Reset the list.
|
// Reset the list.
|
||||||
this._webcams = new Map();
|
this._webcams = {};
|
||||||
|
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
.then(() =>
|
.then(() =>
|
||||||
|
|
@ -1503,25 +1628,34 @@ export default class RoomClient
|
||||||
if (device.kind !== 'videoinput')
|
if (device.kind !== 'videoinput')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
this._webcams.set(device.deviceId, device);
|
this._webcams[device.deviceId] = {
|
||||||
|
value : device.deviceId,
|
||||||
|
label : device.label,
|
||||||
|
deviceId : device.deviceId
|
||||||
|
};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(() =>
|
.then(() =>
|
||||||
{
|
{
|
||||||
const array = Array.from(this._webcams.values());
|
|
||||||
const len = array.length;
|
|
||||||
const currentWebcamId =
|
const currentWebcamId =
|
||||||
this._webcam.device ? this._webcam.device.deviceId : undefined;
|
this._webcam.device ? this._webcam.device.deviceId : undefined;
|
||||||
|
|
||||||
logger.debug('_updateWebcams() [webcams:%o]', array);
|
logger.debug('_updateWebcams() [webcams:%o]', this._webcams);
|
||||||
|
|
||||||
|
const len = Object.keys(this._webcams).length;
|
||||||
|
|
||||||
if (len === 0)
|
if (len === 0)
|
||||||
this._webcam.device = null;
|
this._webcam.device = null;
|
||||||
else if (!this._webcams.has(currentWebcamId))
|
else if (!this._webcams[currentWebcamId])
|
||||||
this._webcam.device = array[0];
|
for (this._webcam.device in this._webcams)
|
||||||
|
if (this._webcams.hasOwnProperty(this._webcam.device))
|
||||||
|
break;
|
||||||
|
|
||||||
this._dispatch(
|
this._dispatch(
|
||||||
stateActions.setCanChangeWebcam(this._webcams.size >= 2));
|
stateActions.setCanChangeWebcam(len >= 2));
|
||||||
|
if (len >= 1)
|
||||||
|
this._dispatch(
|
||||||
|
stateActions.setWebcamDevices(this._webcams));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,7 @@ class Me extends React.Component
|
||||||
onMuteMic,
|
onMuteMic,
|
||||||
onUnmuteMic,
|
onUnmuteMic,
|
||||||
onEnableWebcam,
|
onEnableWebcam,
|
||||||
onDisableWebcam,
|
onDisableWebcam
|
||||||
onChangeWebcam
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
let micState;
|
let micState;
|
||||||
|
|
@ -59,13 +58,6 @@ class Me extends React.Component
|
||||||
else
|
else
|
||||||
webcamState = 'off';
|
webcamState = 'off';
|
||||||
|
|
||||||
let changeWebcamState;
|
|
||||||
|
|
||||||
if (Boolean(webcamProducer) && me.canChangeWebcam)
|
|
||||||
changeWebcamState = 'on';
|
|
||||||
else
|
|
||||||
changeWebcamState = 'unsupported';
|
|
||||||
|
|
||||||
const videoVisible = (
|
const videoVisible = (
|
||||||
Boolean(webcamProducer) &&
|
Boolean(webcamProducer) &&
|
||||||
!webcamProducer.locallyPaused &&
|
!webcamProducer.locallyPaused &&
|
||||||
|
|
@ -88,7 +80,9 @@ class Me extends React.Component
|
||||||
{connected ?
|
{connected ?
|
||||||
<div className='controls'>
|
<div className='controls'>
|
||||||
<div
|
<div
|
||||||
className={classnames('button', 'mic', micState)}
|
className={classnames('button', 'mic', micState, {
|
||||||
|
disabled : me.audioInProgress
|
||||||
|
})}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
micState === 'on' ? onMuteMic() : onUnmuteMic();
|
micState === 'on' ? onMuteMic() : onUnmuteMic();
|
||||||
|
|
@ -104,13 +98,6 @@ class Me extends React.Component
|
||||||
webcamState === 'on' ? onDisableWebcam() : onEnableWebcam();
|
webcamState === 'on' ? onDisableWebcam() : onEnableWebcam();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
|
||||||
className={classnames('button', 'change-webcam', changeWebcamState, {
|
|
||||||
disabled : me.webcamInProgress
|
|
||||||
})}
|
|
||||||
onClick={() => onChangeWebcam()}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
:null
|
:null
|
||||||
}
|
}
|
||||||
|
|
@ -179,8 +166,7 @@ Me.propTypes =
|
||||||
onMuteMic : PropTypes.func.isRequired,
|
onMuteMic : PropTypes.func.isRequired,
|
||||||
onUnmuteMic : PropTypes.func.isRequired,
|
onUnmuteMic : PropTypes.func.isRequired,
|
||||||
onEnableWebcam : PropTypes.func.isRequired,
|
onEnableWebcam : PropTypes.func.isRequired,
|
||||||
onDisableWebcam : PropTypes.func.isRequired,
|
onDisableWebcam : PropTypes.func.isRequired
|
||||||
onChangeWebcam : PropTypes.func.isRequired
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
|
|
@ -209,8 +195,7 @@ const mapDispatchToProps = (dispatch) =>
|
||||||
onMuteMic : () => dispatch(requestActions.muteMic()),
|
onMuteMic : () => dispatch(requestActions.muteMic()),
|
||||||
onUnmuteMic : () => dispatch(requestActions.unmuteMic()),
|
onUnmuteMic : () => dispatch(requestActions.unmuteMic()),
|
||||||
onEnableWebcam : () => dispatch(requestActions.enableWebcam()),
|
onEnableWebcam : () => dispatch(requestActions.enableWebcam()),
|
||||||
onDisableWebcam : () => dispatch(requestActions.disableWebcam()),
|
onDisableWebcam : () => dispatch(requestActions.disableWebcam())
|
||||||
onChangeWebcam : () => dispatch(requestActions.changeWebcam())
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { connect } from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import * as appPropTypes from './appPropTypes';
|
import * as appPropTypes from './appPropTypes';
|
||||||
import * as stateActions from '../redux/stateActions';
|
|
||||||
import { Appear } from './transitions';
|
import { Appear } from './transitions';
|
||||||
import Peer from './Peer';
|
import Peer from './Peer';
|
||||||
|
|
||||||
|
|
@ -13,13 +12,20 @@ class Peers extends React.Component
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.state = {
|
this.state = {
|
||||||
ratio : 1.334
|
peerWidth : 400,
|
||||||
|
peerHeight : 300,
|
||||||
|
ratio : 1.334
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDimensions(nextProps = null)
|
resizeUpdate()
|
||||||
{
|
{
|
||||||
const n = nextProps ? nextProps.peers.length : this.props.peers.length;
|
this.updateDimensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDimensions(props = this.props)
|
||||||
|
{
|
||||||
|
const n = props.peers ? props.peers.length : 0;
|
||||||
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -47,40 +53,42 @@ class Peers extends React.Component
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Math.ceil(this.props.peerWidth) !== Math.ceil(0.9 * x))
|
if (Math.ceil(this.state.peerWidth) !== Math.ceil(0.9 * x))
|
||||||
{
|
{
|
||||||
this.props.onComponentResize(0.9 * x, 0.9 * y);
|
this.setState({
|
||||||
|
peerWidth : 0.9 * x,
|
||||||
|
peerHeight : 0.9 * y
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount()
|
componentDidMount()
|
||||||
{
|
{
|
||||||
window.addEventListener('resize', this.updateDimensions.bind(this));
|
window.addEventListener('resize', this.resizeUpdate.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount()
|
componentWillUnmount()
|
||||||
{
|
{
|
||||||
window.removeEventListener('resize', this.updateDimensions.bind(this));
|
window.removeEventListener('resize', this.resizeUpdate.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps)
|
componentWillReceiveProps(nextProps)
|
||||||
{
|
{
|
||||||
this.updateDimensions(nextProps);
|
if (nextProps.peers)
|
||||||
|
this.updateDimensions(nextProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
render()
|
render()
|
||||||
{
|
{
|
||||||
const {
|
const {
|
||||||
activeSpeakerName,
|
activeSpeakerName,
|
||||||
peers,
|
peers
|
||||||
peerWidth,
|
|
||||||
peerHeight
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const style =
|
const style =
|
||||||
{
|
{
|
||||||
'width' : peerWidth,
|
'width' : this.state.peerWidth,
|
||||||
'height' : peerHeight
|
'height' : this.state.peerHeight
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -109,39 +117,21 @@ class Peers extends React.Component
|
||||||
Peers.propTypes =
|
Peers.propTypes =
|
||||||
{
|
{
|
||||||
peers : PropTypes.arrayOf(appPropTypes.Peer).isRequired,
|
peers : PropTypes.arrayOf(appPropTypes.Peer).isRequired,
|
||||||
activeSpeakerName : PropTypes.string,
|
activeSpeakerName : PropTypes.string
|
||||||
peerHeight : PropTypes.number,
|
|
||||||
peerWidth : PropTypes.number,
|
|
||||||
onComponentResize : PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) =>
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
onComponentResize : (peerWidth, peerHeight) =>
|
|
||||||
{
|
|
||||||
dispatch(stateActions.onComponentResize(peerWidth, peerHeight));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
{
|
{
|
||||||
// TODO: This is not OK since it's creating a new array every time, so triggering a
|
|
||||||
// component rendering.
|
|
||||||
const peersArray = Object.values(state.peers);
|
const peersArray = Object.values(state.peers);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
peers : peersArray,
|
peers : peersArray,
|
||||||
activeSpeakerName : state.room.activeSpeakerName,
|
activeSpeakerName : state.room.activeSpeakerName
|
||||||
peerHeight : state.room.peerHeight,
|
|
||||||
peerWidth : state.room.peerWidth
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const PeersContainer = connect(
|
const PeersContainer = connect(
|
||||||
mapStateToProps,
|
mapStateToProps
|
||||||
mapDispatchToProps
|
|
||||||
)(Peers);
|
)(Peers);
|
||||||
|
|
||||||
export default PeersContainer;
|
export default PeersContainer;
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,14 @@ import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import ClipboardButton from 'react-clipboard.js';
|
import ClipboardButton from 'react-clipboard.js';
|
||||||
import * as appPropTypes from './appPropTypes';
|
import * as appPropTypes from './appPropTypes';
|
||||||
|
import * as stateActions from '../redux/stateActions';
|
||||||
import * as requestActions from '../redux/requestActions';
|
import * as requestActions from '../redux/requestActions';
|
||||||
import { Appear } from './transitions';
|
import { Appear } from './transitions';
|
||||||
import Me from './Me';
|
import Me from './Me';
|
||||||
import Peers from './Peers';
|
import Peers from './Peers';
|
||||||
import Notifications from './Notifications';
|
import Notifications from './Notifications';
|
||||||
import ChatWidget from './ChatWidget';
|
import ChatWidget from './ChatWidget';
|
||||||
|
import Settings from './Settings';
|
||||||
|
|
||||||
class Room extends React.Component
|
class Room extends React.Component
|
||||||
{
|
{
|
||||||
|
|
@ -22,8 +24,8 @@ class Room extends React.Component
|
||||||
amActiveSpeaker,
|
amActiveSpeaker,
|
||||||
screenProducer,
|
screenProducer,
|
||||||
onRoomLinkCopy,
|
onRoomLinkCopy,
|
||||||
onSetAudioMode,
|
onToggleSettings,
|
||||||
onRestartIce,
|
onLogin,
|
||||||
onShareScreen,
|
onShareScreen,
|
||||||
onUnShareScreen,
|
onUnShareScreen,
|
||||||
onNeedExtension,
|
onNeedExtension,
|
||||||
|
|
@ -140,22 +142,22 @@ class Room extends React.Component
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classnames('button', 'audio-only', {
|
className={classnames('button', 'settings', {
|
||||||
on : me.audioOnly,
|
on : room.showSettings,
|
||||||
disabled : me.audioOnlyInProgress
|
off : !room.showSettings
|
||||||
})}
|
})}
|
||||||
data-tip='Toggle audio only mode'
|
data-tip='Open settings'
|
||||||
data-type='dark'
|
data-type='dark'
|
||||||
onClick={() => onSetAudioMode(!me.audioOnly)}
|
onClick={() => onToggleSettings()}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classnames('button', 'restart-ice', {
|
className={classnames('button', 'login', 'off', {
|
||||||
disabled : me.restartIceInProgress
|
disabled : me.loginInProgress
|
||||||
})}
|
})}
|
||||||
data-tip='Restart ICE'
|
data-tip='Login'
|
||||||
data-type='dark'
|
data-type='dark'
|
||||||
onClick={() => onRestartIce()}
|
onClick={() => onLogin()}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
@ -176,6 +178,10 @@ class Room extends React.Component
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Settings
|
||||||
|
onToggleSettings={onToggleSettings}
|
||||||
|
/>
|
||||||
|
|
||||||
<ReactTooltip
|
<ReactTooltip
|
||||||
effect='solid'
|
effect='solid'
|
||||||
delayShow={100}
|
delayShow={100}
|
||||||
|
|
@ -189,18 +195,18 @@ class Room extends React.Component
|
||||||
|
|
||||||
Room.propTypes =
|
Room.propTypes =
|
||||||
{
|
{
|
||||||
room : appPropTypes.Room.isRequired,
|
room : appPropTypes.Room.isRequired,
|
||||||
me : appPropTypes.Me.isRequired,
|
me : appPropTypes.Me.isRequired,
|
||||||
amActiveSpeaker : PropTypes.bool.isRequired,
|
amActiveSpeaker : PropTypes.bool.isRequired,
|
||||||
screenProducer : appPropTypes.Producer,
|
screenProducer : appPropTypes.Producer,
|
||||||
onRoomLinkCopy : PropTypes.func.isRequired,
|
onRoomLinkCopy : PropTypes.func.isRequired,
|
||||||
onSetAudioMode : PropTypes.func.isRequired,
|
onShareScreen : PropTypes.func.isRequired,
|
||||||
onRestartIce : PropTypes.func.isRequired,
|
onUnShareScreen : PropTypes.func.isRequired,
|
||||||
onShareScreen : PropTypes.func.isRequired,
|
onNeedExtension : PropTypes.func.isRequired,
|
||||||
onUnShareScreen : PropTypes.func.isRequired,
|
onToggleSettings : PropTypes.func.isRequired,
|
||||||
onNeedExtension : PropTypes.func.isRequired,
|
onToggleHand : PropTypes.func.isRequired,
|
||||||
onToggleHand : PropTypes.func.isRequired,
|
onLeaveMeeting : PropTypes.func.isRequired,
|
||||||
onLeaveMeeting : PropTypes.func.isRequired
|
onLogin : PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
|
|
@ -227,16 +233,9 @@ const mapDispatchToProps = (dispatch) =>
|
||||||
text : 'Room link copied to the clipboard'
|
text : 'Room link copied to the clipboard'
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
onSetAudioMode : (enable) =>
|
onToggleSettings : () =>
|
||||||
{
|
{
|
||||||
if (enable)
|
dispatch(stateActions.toggleSettings());
|
||||||
dispatch(requestActions.enableAudioOnly());
|
|
||||||
else
|
|
||||||
dispatch(requestActions.disableAudioOnly());
|
|
||||||
},
|
|
||||||
onRestartIce : () =>
|
|
||||||
{
|
|
||||||
dispatch(requestActions.restartIce());
|
|
||||||
},
|
},
|
||||||
onToggleHand : (enable) =>
|
onToggleHand : (enable) =>
|
||||||
{
|
{
|
||||||
|
|
@ -260,6 +259,10 @@ const mapDispatchToProps = (dispatch) =>
|
||||||
onNeedExtension : () =>
|
onNeedExtension : () =>
|
||||||
{
|
{
|
||||||
dispatch(requestActions.installExtension());
|
dispatch(requestActions.installExtension());
|
||||||
|
},
|
||||||
|
onLogin : () =>
|
||||||
|
{
|
||||||
|
dispatch(requestActions.userLogin());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import * as appPropTypes from './appPropTypes';
|
||||||
|
import * as requestActions from '../redux/requestActions';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Appear } from './transitions';
|
||||||
|
import Dropdown from 'react-dropdown';
|
||||||
|
|
||||||
|
class Settings extends React.Component
|
||||||
|
{
|
||||||
|
constructor(props)
|
||||||
|
{
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render()
|
||||||
|
{
|
||||||
|
const {
|
||||||
|
room,
|
||||||
|
me,
|
||||||
|
handleChangeWebcam,
|
||||||
|
handleChangeAudioDevice,
|
||||||
|
onToggleSettings
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
if (!room.showSettings)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
let webcams;
|
||||||
|
let webcamText;
|
||||||
|
|
||||||
|
if (me.canChangeWebcam)
|
||||||
|
webcamText = 'Select camera';
|
||||||
|
else
|
||||||
|
webcamText = 'Unable to select camera';
|
||||||
|
|
||||||
|
if (me.webcamDevices)
|
||||||
|
webcams = Object.values(me.webcamDevices);
|
||||||
|
else
|
||||||
|
webcams = [];
|
||||||
|
|
||||||
|
let audioDevices;
|
||||||
|
let audioDevicesText;
|
||||||
|
|
||||||
|
if (me.canChangeAudioDevice)
|
||||||
|
audioDevicesText = 'Select audio input device';
|
||||||
|
else
|
||||||
|
audioDevicesText = 'Unable to select audio input device';
|
||||||
|
|
||||||
|
if (me.audioDevices)
|
||||||
|
audioDevices = Object.values(me.audioDevices);
|
||||||
|
else
|
||||||
|
audioDevices = [];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Appear duration={500}>
|
||||||
|
<div data-component='Settings'>
|
||||||
|
<div className='dialog'>
|
||||||
|
<div className='header'>
|
||||||
|
<span>Settings</span>
|
||||||
|
</div>
|
||||||
|
<div className='settings'>
|
||||||
|
<Dropdown
|
||||||
|
disabled={!me.canChangeWebcam}
|
||||||
|
options={webcams}
|
||||||
|
onChange={handleChangeWebcam}
|
||||||
|
placeholder={webcamText}
|
||||||
|
/>
|
||||||
|
<Dropdown
|
||||||
|
disabled={!me.canChangeAudioDevice}
|
||||||
|
options={audioDevices}
|
||||||
|
onChange={handleChangeAudioDevice}
|
||||||
|
placeholder={audioDevicesText}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className='footer'>
|
||||||
|
<span
|
||||||
|
className='button'
|
||||||
|
onClick={() => onToggleSettings()}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Appear>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings.propTypes =
|
||||||
|
{
|
||||||
|
me : appPropTypes.Me.isRequired,
|
||||||
|
room : appPropTypes.Room.isRequired,
|
||||||
|
onToggleSettings : PropTypes.func.isRequired,
|
||||||
|
handleChangeWebcam : PropTypes.func.isRequired,
|
||||||
|
handleChangeAudioDevice : PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = (state) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
me : state.me,
|
||||||
|
room : state.room
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
handleChangeWebcam : (device) =>
|
||||||
|
{
|
||||||
|
dispatch(requestActions.changeWebcam(device.value));
|
||||||
|
},
|
||||||
|
handleChangeAudioDevice : (device) =>
|
||||||
|
{
|
||||||
|
dispatch(requestActions.changeAudioDevice(device.value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const SettingsContainer = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(Settings);
|
||||||
|
|
||||||
|
export default SettingsContainer;
|
||||||
|
|
@ -8,9 +8,14 @@ const initialState =
|
||||||
canSendWebcam : false,
|
canSendWebcam : false,
|
||||||
canShareScreen : false,
|
canShareScreen : false,
|
||||||
needExtension : false,
|
needExtension : false,
|
||||||
|
canChangeAudioDevice : false,
|
||||||
|
audioDevices : null,
|
||||||
canChangeWebcam : false,
|
canChangeWebcam : false,
|
||||||
|
webcamDevices : null,
|
||||||
webcamInProgress : false,
|
webcamInProgress : false,
|
||||||
|
audioInProgress : false,
|
||||||
screenShareInProgress : false,
|
screenShareInProgress : false,
|
||||||
|
loginInProgress : false,
|
||||||
audioOnly : false,
|
audioOnly : false,
|
||||||
audioOnlyInProgress : false,
|
audioOnlyInProgress : false,
|
||||||
raiseHand : false,
|
raiseHand : false,
|
||||||
|
|
@ -43,6 +48,20 @@ const me = (state = initialState, action) =>
|
||||||
return { ...state, canShareScreen, needExtension };
|
return { ...state, canShareScreen, needExtension };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'SET_CAN_CHANGE_AUDIO_DEVICE':
|
||||||
|
{
|
||||||
|
const canChangeAudioDevice = action.payload;
|
||||||
|
|
||||||
|
return { ...state, canChangeAudioDevice };
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'SET_AUDIO_DEVICES':
|
||||||
|
{
|
||||||
|
const { devices } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, audioDevices: devices };
|
||||||
|
}
|
||||||
|
|
||||||
case 'SET_CAN_CHANGE_WEBCAM':
|
case 'SET_CAN_CHANGE_WEBCAM':
|
||||||
{
|
{
|
||||||
const canChangeWebcam = action.payload;
|
const canChangeWebcam = action.payload;
|
||||||
|
|
@ -50,6 +69,20 @@ const me = (state = initialState, action) =>
|
||||||
return { ...state, canChangeWebcam };
|
return { ...state, canChangeWebcam };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'SET_WEBCAM_DEVICES':
|
||||||
|
{
|
||||||
|
const { devices } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, webcamDevices: devices };
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'SET_AUDIO_IN_PROGRESS':
|
||||||
|
{
|
||||||
|
const { flag } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, audioInProgress: flag };
|
||||||
|
}
|
||||||
|
|
||||||
case 'SET_WEBCAM_IN_PROGRESS':
|
case 'SET_WEBCAM_IN_PROGRESS':
|
||||||
{
|
{
|
||||||
const { flag } = action.payload;
|
const { flag } = action.payload;
|
||||||
|
|
@ -64,6 +97,13 @@ const me = (state = initialState, action) =>
|
||||||
return { ...state, screenShareInProgress: flag };
|
return { ...state, screenShareInProgress: flag };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'SET_LOGIN_IN_PROGRESS':
|
||||||
|
{
|
||||||
|
const { flag } = action.payload;
|
||||||
|
|
||||||
|
return { ...state, loginInProgress: flag };
|
||||||
|
}
|
||||||
|
|
||||||
case 'SET_DISPLAY_NAME':
|
case 'SET_DISPLAY_NAME':
|
||||||
{
|
{
|
||||||
let { displayName } = action.payload;
|
let { displayName } = action.payload;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ const initialState =
|
||||||
state : 'new', // new/connecting/connected/disconnected/closed,
|
state : 'new', // new/connecting/connected/disconnected/closed,
|
||||||
activeSpeakerName : null,
|
activeSpeakerName : null,
|
||||||
peerHeight : 300,
|
peerHeight : 300,
|
||||||
peerWidth : 400
|
peerWidth : 400,
|
||||||
|
showSettings : false
|
||||||
};
|
};
|
||||||
|
|
||||||
const room = (state = initialState, action) =>
|
const room = (state = initialState, action) =>
|
||||||
|
|
@ -42,6 +43,13 @@ const room = (state = initialState, action) =>
|
||||||
return { ...state, peerWidth: peerWidth, peerHeight: peerHeight };
|
return { ...state, peerWidth: peerWidth, peerHeight: peerHeight };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'TOGGLE_SETTINGS':
|
||||||
|
{
|
||||||
|
const showSettings = !state.showSettings;
|
||||||
|
|
||||||
|
return { ...state, showSettings };
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,19 @@ export const disableWebcam = () =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const changeWebcam = () =>
|
export const changeWebcam = (deviceId) =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
type : 'CHANGE_WEBCAM'
|
type : 'CHANGE_WEBCAM',
|
||||||
|
payload : { deviceId }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const changeAudioDevice = (deviceId) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'CHANGE_AUDIO_DEVICE',
|
||||||
|
payload : { deviceId }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -110,6 +119,13 @@ export const resumePeerVideo = (peerName) =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const userLogin = () =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'USER_LOGIN'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const raiseHand = () =>
|
export const raiseHand = () =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,18 @@ export default ({ dispatch, getState }) => (next) =>
|
||||||
|
|
||||||
case 'CHANGE_WEBCAM':
|
case 'CHANGE_WEBCAM':
|
||||||
{
|
{
|
||||||
client.changeWebcam();
|
const { deviceId } = action.payload;
|
||||||
|
|
||||||
|
client.changeWebcam(deviceId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'CHANGE_AUDIO_DEVICE':
|
||||||
|
{
|
||||||
|
const { deviceId } = action.payload;
|
||||||
|
|
||||||
|
client.changeAudioDevice(deviceId);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -145,6 +156,13 @@ export default ({ dispatch, getState }) => (next) =>
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'USER_LOGIN':
|
||||||
|
{
|
||||||
|
client.login();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'LOWER_HAND':
|
case 'LOWER_HAND':
|
||||||
{
|
{
|
||||||
client.sendRaiseHandState(false);
|
client.sendRaiseHandState(false);
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,22 @@ export const setScreenCapabilities = ({ canShareScreen, needExtension }) =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setCanChangeAudioDevice = (flag) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'SET_CAN_CHANGE_AUDIO_DEVICE',
|
||||||
|
payload : flag
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setAudioDevices = (devices) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'SET_AUDIO_DEVICES',
|
||||||
|
payload : { devices }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const setCanChangeWebcam = (flag) =>
|
export const setCanChangeWebcam = (flag) =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
|
@ -62,6 +78,14 @@ export const setCanChangeWebcam = (flag) =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setWebcamDevices = (devices) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'SET_WEBCAM_DEVICES',
|
||||||
|
payload : { devices }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const setDisplayName = (displayName) =>
|
export const setDisplayName = (displayName) =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
|
@ -110,6 +134,21 @@ export const setMyRaiseHandState = (flag) =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setLoginInProgress = (flag) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'SET_LOGIN_IN_PROGRESS',
|
||||||
|
payload : { flag }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toggleSettings = () =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'TOGGLE_SETTINGS'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const setMyRaiseHandStateInProgress = (flag) =>
|
export const setMyRaiseHandStateInProgress = (flag) =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
|
@ -174,6 +213,14 @@ export const setProducerTrack = (producerId, track) =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const setAudioInProgress = (flag) =>
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
type : 'SET_AUDIO_IN_PROGRESS',
|
||||||
|
payload : { flag }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const setWebcamInProgress = (flag) =>
|
export const setWebcamInProgress = (flag) =>
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -591,6 +591,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-helper-bindify-decorators": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-traverse": "6.26.0",
|
||||||
|
"babel-types": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-helper-builder-binary-assignment-operator-visitor": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-explode-assignable-expression": "6.24.1",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-types": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-helper-builder-react-jsx": {
|
"babel-helper-builder-react-jsx": {
|
||||||
"version": "6.26.0",
|
"version": "6.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz",
|
||||||
|
|
@ -626,6 +648,29 @@
|
||||||
"lodash": "4.17.4"
|
"lodash": "4.17.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-helper-explode-assignable-expression": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-traverse": "6.26.0",
|
||||||
|
"babel-types": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-helper-explode-class": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-bindify-decorators": "6.24.1",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-traverse": "6.26.0",
|
||||||
|
"babel-types": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-helper-function-name": {
|
"babel-helper-function-name": {
|
||||||
"version": "6.24.1",
|
"version": "6.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
|
||||||
|
|
@ -680,6 +725,19 @@
|
||||||
"lodash": "4.17.4"
|
"lodash": "4.17.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-helper-remap-async-to-generator": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-function-name": "6.24.1",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-template": "6.26.0",
|
||||||
|
"babel-traverse": "6.26.0",
|
||||||
|
"babel-types": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-helper-replace-supers": {
|
"babel-helper-replace-supers": {
|
||||||
"version": "6.24.1",
|
"version": "6.24.1",
|
||||||
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
"resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
|
||||||
|
|
@ -722,12 +780,72 @@
|
||||||
"babel-runtime": "6.26.0"
|
"babel-runtime": "6.26.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-plugin-syntax-async-functions": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-async-generators": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-class-constructor-call": {
|
||||||
|
"version": "6.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
|
||||||
|
"integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-class-properties": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-decorators": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-do-expressions": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-dynamic-import": {
|
||||||
|
"version": "6.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
|
||||||
|
"integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-exponentiation-operator": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-syntax-export-extensions": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"babel-plugin-syntax-flow": {
|
"babel-plugin-syntax-flow": {
|
||||||
"version": "6.18.0",
|
"version": "6.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
|
||||||
"integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=",
|
"integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"babel-plugin-syntax-function-bind": {
|
||||||
|
"version": "6.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
|
||||||
|
"integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"babel-plugin-syntax-jsx": {
|
"babel-plugin-syntax-jsx": {
|
||||||
"version": "6.18.0",
|
"version": "6.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
|
||||||
|
|
@ -740,6 +858,80 @@
|
||||||
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"babel-plugin-syntax-trailing-function-commas": {
|
||||||
|
"version": "6.22.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
|
||||||
|
"integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-async-generator-functions": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-remap-async-to-generator": "6.24.1",
|
||||||
|
"babel-plugin-syntax-async-generators": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-async-to-generator": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-remap-async-to-generator": "6.24.1",
|
||||||
|
"babel-plugin-syntax-async-functions": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-class-constructor-call": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-class-constructor-call": "6.18.0",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-template": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-class-properties": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-function-name": "6.24.1",
|
||||||
|
"babel-plugin-syntax-class-properties": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-template": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-decorators": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-explode-class": "6.24.1",
|
||||||
|
"babel-plugin-syntax-decorators": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0",
|
||||||
|
"babel-template": "6.26.0",
|
||||||
|
"babel-types": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-do-expressions": {
|
||||||
|
"version": "6.22.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz",
|
||||||
|
"integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-do-expressions": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-plugin-transform-es2015-arrow-functions": {
|
"babel-plugin-transform-es2015-arrow-functions": {
|
||||||
"version": "6.22.0",
|
"version": "6.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
|
||||||
|
|
@ -974,6 +1166,27 @@
|
||||||
"regexpu-core": "2.0.0"
|
"regexpu-core": "2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-plugin-transform-exponentiation-operator": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
|
||||||
|
"babel-plugin-syntax-exponentiation-operator": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-plugin-transform-export-extensions": {
|
||||||
|
"version": "6.22.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz",
|
||||||
|
"integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-export-extensions": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-plugin-transform-flow-strip-types": {
|
"babel-plugin-transform-flow-strip-types": {
|
||||||
"version": "6.22.0",
|
"version": "6.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz",
|
||||||
|
|
@ -984,6 +1197,16 @@
|
||||||
"babel-runtime": "6.26.0"
|
"babel-runtime": "6.26.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-plugin-transform-function-bind": {
|
||||||
|
"version": "6.22.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz",
|
||||||
|
"integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-function-bind": "6.13.0",
|
||||||
|
"babel-runtime": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-plugin-transform-object-assign": {
|
"babel-plugin-transform-object-assign": {
|
||||||
"version": "6.22.0",
|
"version": "6.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-plugin-transform-object-assign/-/babel-plugin-transform-object-assign-6.22.0.tgz",
|
||||||
|
|
@ -1126,6 +1349,53 @@
|
||||||
"babel-preset-flow": "6.23.0"
|
"babel-preset-flow": "6.23.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"babel-preset-stage-0": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-transform-do-expressions": "6.22.0",
|
||||||
|
"babel-plugin-transform-function-bind": "6.22.0",
|
||||||
|
"babel-preset-stage-1": "6.24.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-preset-stage-1": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-transform-class-constructor-call": "6.24.1",
|
||||||
|
"babel-plugin-transform-export-extensions": "6.22.0",
|
||||||
|
"babel-preset-stage-2": "6.24.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-preset-stage-2": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-dynamic-import": "6.18.0",
|
||||||
|
"babel-plugin-transform-class-properties": "6.24.1",
|
||||||
|
"babel-plugin-transform-decorators": "6.24.1",
|
||||||
|
"babel-preset-stage-3": "6.24.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"babel-preset-stage-3": {
|
||||||
|
"version": "6.24.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz",
|
||||||
|
"integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-plugin-syntax-trailing-function-commas": "6.22.0",
|
||||||
|
"babel-plugin-transform-async-generator-functions": "6.24.1",
|
||||||
|
"babel-plugin-transform-async-to-generator": "6.24.1",
|
||||||
|
"babel-plugin-transform-exponentiation-operator": "6.24.1",
|
||||||
|
"babel-plugin-transform-object-rest-spread": "6.26.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"babel-register": {
|
"babel-register": {
|
||||||
"version": "6.26.0",
|
"version": "6.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
|
||||||
|
|
@ -3850,8 +4120,8 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"co": "4.6.0",
|
"co": "^4.6.0",
|
||||||
"json-stable-stringify": "1.0.1"
|
"json-stable-stringify": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
|
|
@ -3924,7 +4194,7 @@
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"inherits": "2.0.3"
|
"inherits": "~2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"boom": {
|
"boom": {
|
||||||
|
|
@ -3932,7 +4202,7 @@
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"hoek": "2.16.3"
|
"hoek": "2.x.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
|
|
@ -3994,7 +4264,7 @@
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"boom": "2.10.1"
|
"boom": "2.x.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dashdash": {
|
"dashdash": {
|
||||||
|
|
@ -4052,7 +4322,7 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"jsbn": "0.1.1"
|
"jsbn": "~0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extend": {
|
"extend": {
|
||||||
|
|
@ -4132,7 +4402,7 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"assert-plus": "1.0.0"
|
"assert-plus": "^1.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"assert-plus": {
|
"assert-plus": {
|
||||||
|
|
@ -4261,7 +4531,7 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"jsbn": "0.1.1"
|
"jsbn": "~0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jsbn": {
|
"jsbn": {
|
||||||
|
|
@ -4282,7 +4552,7 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"jsonify": "0.0.0"
|
"jsonify": "~0.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"json-stringify-safe": {
|
"json-stringify-safe": {
|
||||||
|
|
@ -8579,6 +8849,14 @@
|
||||||
"prop-types": "15.6.0"
|
"prop-types": "15.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-dropdown": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-dropdown/-/react-dropdown-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-rRv3a7NiP++yC1rzdjzkviC5ujq759i4SRa0M3C0Cr7loYT4Z3+JhSPekv1/04JiZNXX46cV3/g6A9kS7rkI4Q==",
|
||||||
|
"requires": {
|
||||||
|
"classnames": "2.2.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-redux": {
|
"react-redux": {
|
||||||
"version": "5.0.6",
|
"version": "5.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz",
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
"react": "^16.2.0",
|
"react": "^16.2.0",
|
||||||
"react-clipboard.js": "^1.1.3",
|
"react-clipboard.js": "^1.1.3",
|
||||||
"react-dom": "^16.2.0",
|
"react-dom": "^16.2.0",
|
||||||
|
"react-dropdown": "^1.5.0",
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
"react-spinner": "^0.2.7",
|
"react-spinner": "^0.2.7",
|
||||||
"react-tooltip": "^3.4.0",
|
"react-tooltip": "^3.4.0",
|
||||||
|
|
@ -38,6 +39,7 @@
|
||||||
"babel-plugin-transform-runtime": "^6.23.0",
|
"babel-plugin-transform-runtime": "^6.23.0",
|
||||||
"babel-preset-es2015": "^6.24.1",
|
"babel-preset-es2015": "^6.24.1",
|
||||||
"babel-preset-react": "^6.24.1",
|
"babel-preset-react": "^6.24.1",
|
||||||
|
"babel-preset-stage-0": "^6.24.1",
|
||||||
"babelify": "^8.0.0",
|
"babelify": "^8.0.0",
|
||||||
"browser-sync": "^2.23.6",
|
"browser-sync": "^2.23.6",
|
||||||
"browserify": "^16.1.0",
|
"browserify": "^16.1.0",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<svg fill="#FFFFFF" fill-opacity="0.65" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg">
|
<svg fill="#FFFFFF" height="48" viewBox="0 0 24 24" width="48" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>
|
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/>
|
||||||
<path d="M0 0h24v24H0z" fill="none"/>
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 372 B After Width: | Height: | Size: 352 B |
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 217 B |
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" fill="#FFFFFF"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 232 B |
|
|
@ -1,4 +1,4 @@
|
||||||
<svg fill="#FFFFFF" fill-opacity="0.65" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
<svg fill="#FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path d="M0 0h24v24H0z" fill="none"/>
|
<path d="M0 0h24v24H0z" fill="none"/>
|
||||||
<path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/>
|
<path d="M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.08 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 332 B |
|
|
@ -0,0 +1,4 @@
|
||||||
|
<svg fill="#000000" height="48" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill="none" d="M0 0h20v20H0V0z"/>
|
||||||
|
<path d="M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 790 B |
|
|
@ -0,0 +1,3 @@
|
||||||
|
<svg fill="#FFFFFF" height="24" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 746 B |
|
|
@ -170,7 +170,7 @@
|
||||||
flex: 100 100 auto;
|
flex: 100 100 auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
object-fit: contain;
|
object-fit: cover;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
transition-property: opacity;
|
transition-property: opacity;
|
||||||
transition-duration: .15s;
|
transition-duration: .15s;
|
||||||
|
|
|
||||||
|
|
@ -216,19 +216,19 @@
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.audio-only {
|
&.login {
|
||||||
background-image: url('/resources/images/icon_audio_only_white.svg');
|
&.off {
|
||||||
|
background-image: url('/resources/images/icon_login_white.svg');
|
||||||
&.on {
|
|
||||||
background-image: url('/resources/images/icon_audio_only_black.svg');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.restart-ice {
|
&.settings {
|
||||||
background-image: url('/resources/images/icon_restart_ice_white.svg');
|
&.off {
|
||||||
|
background-image: url('/resources/images/icon_settings_white.svg');
|
||||||
|
}
|
||||||
|
|
||||||
&.on {
|
&.on {
|
||||||
background-image: url('/resources/images/icon_restart_ice__black.svg');
|
background-image: url('/resources/images/icon_settings_black.svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -265,6 +265,101 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Dropdown-root {
|
||||||
|
position: relative;
|
||||||
|
padding: 0.3vmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-control {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #333;
|
||||||
|
cursor: default;
|
||||||
|
outline: none;
|
||||||
|
padding: 8px 52px 8px 10px;
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-control:hover {
|
||||||
|
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-arrow {
|
||||||
|
border-color: #999 transparent transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 5px 5px 0;
|
||||||
|
content: ' ';
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
margin-top: -ceil(2.5);
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 14px;
|
||||||
|
width: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-open .Dropdown-arrow {
|
||||||
|
border-color: transparent transparent #999;
|
||||||
|
border-width: 0 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-menu {
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-top: -1px;
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-menu .Dropdown-group > .Dropdown-title {
|
||||||
|
padding: 8px 10px;
|
||||||
|
color: rgba(51, 51, 51, 1.2);
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-option {
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: rgba(51, 51, 51, 0.8);
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-option:last-child {
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-option:hover {
|
||||||
|
background-color: #f2f9fc;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-option.is-selected {
|
||||||
|
background-color: #f2f9fc;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Dropdown-noresults {
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #ccc;
|
||||||
|
cursor: default;
|
||||||
|
display: block;
|
||||||
|
padding: 8px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes Room-info-state-connecting {
|
@keyframes Room-info-state-connecting {
|
||||||
50% { background-color: rgba(orange, 0.75); }
|
50% { background-color: rgba(orange, 0.75); }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
[data-component='Settings'] {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 19999;
|
||||||
|
background-color: rgba(000, 000, 000, 0.5);
|
||||||
|
|
||||||
|
AppearFadeIn(500ms);
|
||||||
|
|
||||||
|
> .dialog {
|
||||||
|
position: absolute;
|
||||||
|
width: 40vmin;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0px 3px 12px 2px rgba(#111, 0.4);
|
||||||
|
padding: 1vmin;
|
||||||
|
|
||||||
|
> .header {
|
||||||
|
> span {
|
||||||
|
font-size: 2vmin;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .settings {
|
||||||
|
}
|
||||||
|
|
||||||
|
> .footer {
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
> .button {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin: 1vmin;
|
||||||
|
background-color: rgba(#000, 0.8);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.5vmin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -42,13 +42,14 @@ body {
|
||||||
@import './components/PeerView';
|
@import './components/PeerView';
|
||||||
@import './components/Notifications';
|
@import './components/Notifications';
|
||||||
@import './components/Chat';
|
@import './components/Chat';
|
||||||
|
@import './components/Settings';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack to detect in JS the current media query
|
// Hack to detect in JS the current media query
|
||||||
#multiparty-meeting-media-query-detector {
|
#multiparty-meeting-media-query-detector {
|
||||||
position: relative;
|
position: absolute;
|
||||||
z-index: -1000;
|
z-index: -1000;
|
||||||
bottom: 1px;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
|
|
|
||||||