Started work on settings dialog. Possible to switch camera.
This commit is contained in:
+29
-23
@@ -366,9 +366,9 @@ export default class RoomClient
|
||||
});
|
||||
}
|
||||
|
||||
changeWebcam()
|
||||
changeWebcam(deviceId)
|
||||
{
|
||||
logger.debug('changeWebcam()');
|
||||
logger.debug('changeWebcam() [deviceId: %s]', deviceId);
|
||||
|
||||
this._dispatch(
|
||||
stateActions.setWebcamInProgress(true));
|
||||
@@ -376,22 +376,20 @@ export default class RoomClient
|
||||
return Promise.resolve()
|
||||
.then(() =>
|
||||
{
|
||||
return this._updateWebcams();
|
||||
logger.debug('changeWebcam() | calling enumerateDevices()');
|
||||
|
||||
return navigator.mediaDevices.enumerateDevices();
|
||||
})
|
||||
.then(() =>
|
||||
.then((devices) =>
|
||||
{
|
||||
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);
|
||||
for (const device of devices)
|
||||
{
|
||||
if (device.kind !== 'videoinput')
|
||||
continue;
|
||||
|
||||
if (idx < len - 1)
|
||||
idx++;
|
||||
else
|
||||
idx = 0;
|
||||
|
||||
this._webcam.device = this._webcams.get(array[idx]);
|
||||
if (device.deviceId == deviceId)
|
||||
this._webcam.device = device;
|
||||
}
|
||||
|
||||
logger.debug(
|
||||
'changeWebcam() | new selected webcam [device:%o]',
|
||||
@@ -1487,7 +1485,7 @@ export default class RoomClient
|
||||
logger.debug('_updateWebcams()');
|
||||
|
||||
// Reset the list.
|
||||
this._webcams = new Map();
|
||||
this._webcams = {};
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() =>
|
||||
@@ -1503,25 +1501,33 @@ export default class RoomClient
|
||||
if (device.kind !== 'videoinput')
|
||||
continue;
|
||||
|
||||
this._webcams.set(device.deviceId, device);
|
||||
this._webcams[device.deviceId] = {
|
||||
value : device.deviceId,
|
||||
label : device.label
|
||||
};
|
||||
}
|
||||
})
|
||||
.then(() =>
|
||||
{
|
||||
const array = Array.from(this._webcams.values());
|
||||
const len = array.length;
|
||||
const currentWebcamId =
|
||||
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)
|
||||
this._webcam.device = null;
|
||||
else if (!this._webcams.has(currentWebcamId))
|
||||
this._webcam.device = array[0];
|
||||
else if (!this._webcams[currentWebcamId])
|
||||
for (this._webcam.device in this._webcams)
|
||||
if (this._webcams.hasOwnProperty(this._webcam.device))
|
||||
break;
|
||||
|
||||
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,
|
||||
onUnmuteMic,
|
||||
onEnableWebcam,
|
||||
onDisableWebcam,
|
||||
onChangeWebcam
|
||||
onDisableWebcam
|
||||
} = this.props;
|
||||
|
||||
let micState;
|
||||
@@ -59,13 +58,6 @@ class Me extends React.Component
|
||||
else
|
||||
webcamState = 'off';
|
||||
|
||||
let changeWebcamState;
|
||||
|
||||
if (Boolean(webcamProducer) && me.canChangeWebcam)
|
||||
changeWebcamState = 'on';
|
||||
else
|
||||
changeWebcamState = 'unsupported';
|
||||
|
||||
const videoVisible = (
|
||||
Boolean(webcamProducer) &&
|
||||
!webcamProducer.locallyPaused &&
|
||||
@@ -104,13 +96,6 @@ class Me extends React.Component
|
||||
webcamState === 'on' ? onDisableWebcam() : onEnableWebcam();
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={classnames('button', 'change-webcam', changeWebcamState, {
|
||||
disabled : me.webcamInProgress
|
||||
})}
|
||||
onClick={() => onChangeWebcam()}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
@@ -179,8 +164,7 @@ Me.propTypes =
|
||||
onMuteMic : PropTypes.func.isRequired,
|
||||
onUnmuteMic : PropTypes.func.isRequired,
|
||||
onEnableWebcam : PropTypes.func.isRequired,
|
||||
onDisableWebcam : PropTypes.func.isRequired,
|
||||
onChangeWebcam : PropTypes.func.isRequired
|
||||
onDisableWebcam : PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
@@ -209,8 +193,7 @@ const mapDispatchToProps = (dispatch) =>
|
||||
onMuteMic : () => dispatch(requestActions.muteMic()),
|
||||
onUnmuteMic : () => dispatch(requestActions.unmuteMic()),
|
||||
onEnableWebcam : () => dispatch(requestActions.enableWebcam()),
|
||||
onDisableWebcam : () => dispatch(requestActions.disableWebcam()),
|
||||
onChangeWebcam : () => dispatch(requestActions.changeWebcam())
|
||||
onDisableWebcam : () => dispatch(requestActions.disableWebcam())
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
+34
-12
@@ -5,12 +5,14 @@ import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import ClipboardButton from 'react-clipboard.js';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as stateActions from '../redux/stateActions';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { Appear } from './transitions';
|
||||
import Me from './Me';
|
||||
import Peers from './Peers';
|
||||
import Notifications from './Notifications';
|
||||
import ChatWidget from './ChatWidget';
|
||||
import Settings from './Settings';
|
||||
|
||||
class Room extends React.Component
|
||||
{
|
||||
@@ -24,6 +26,7 @@ class Room extends React.Component
|
||||
onRoomLinkCopy,
|
||||
onSetAudioMode,
|
||||
onRestartIce,
|
||||
onToggleSettings,
|
||||
onShareScreen,
|
||||
onUnShareScreen,
|
||||
onNeedExtension,
|
||||
@@ -158,6 +161,16 @@ class Room extends React.Component
|
||||
onClick={() => onRestartIce()}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={classnames('button', 'settings', {
|
||||
on : room.showSettings,
|
||||
off : !room.showSettings
|
||||
})}
|
||||
data-tip='Open settings'
|
||||
data-type='dark'
|
||||
onClick={() => onToggleSettings()}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={classnames('button', 'raise-hand', {
|
||||
on : me.raiseHand,
|
||||
@@ -176,6 +189,10 @@ class Room extends React.Component
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Settings
|
||||
onToggleSettings={onToggleSettings}
|
||||
/>
|
||||
|
||||
<ReactTooltip
|
||||
effect='solid'
|
||||
delayShow={100}
|
||||
@@ -189,18 +206,19 @@ class Room extends React.Component
|
||||
|
||||
Room.propTypes =
|
||||
{
|
||||
room : appPropTypes.Room.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
amActiveSpeaker : PropTypes.bool.isRequired,
|
||||
screenProducer : appPropTypes.Producer,
|
||||
onRoomLinkCopy : PropTypes.func.isRequired,
|
||||
onSetAudioMode : PropTypes.func.isRequired,
|
||||
onRestartIce : PropTypes.func.isRequired,
|
||||
onShareScreen : PropTypes.func.isRequired,
|
||||
onUnShareScreen : PropTypes.func.isRequired,
|
||||
onNeedExtension : PropTypes.func.isRequired,
|
||||
onToggleHand : PropTypes.func.isRequired,
|
||||
onLeaveMeeting : PropTypes.func.isRequired
|
||||
room : appPropTypes.Room.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
amActiveSpeaker : PropTypes.bool.isRequired,
|
||||
screenProducer : appPropTypes.Producer,
|
||||
onRoomLinkCopy : PropTypes.func.isRequired,
|
||||
onSetAudioMode : PropTypes.func.isRequired,
|
||||
onRestartIce : PropTypes.func.isRequired,
|
||||
onShareScreen : PropTypes.func.isRequired,
|
||||
onUnShareScreen : PropTypes.func.isRequired,
|
||||
onNeedExtension : PropTypes.func.isRequired,
|
||||
onToggleSettings : PropTypes.func.isRequired,
|
||||
onToggleHand : PropTypes.func.isRequired,
|
||||
onLeaveMeeting : PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
@@ -238,6 +256,10 @@ const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
dispatch(requestActions.restartIce());
|
||||
},
|
||||
onToggleSettings : () =>
|
||||
{
|
||||
dispatch(stateActions.toggleSettings());
|
||||
},
|
||||
onToggleHand : (enable) =>
|
||||
{
|
||||
if (enable)
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
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 Dropdown from 'react-dropdown';
|
||||
|
||||
class Settings extends React.Component
|
||||
{
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
const {
|
||||
room,
|
||||
me,
|
||||
handleChangeWebcam,
|
||||
onToggleSettings
|
||||
} = this.props;
|
||||
|
||||
if (!room.showSettings)
|
||||
return null;
|
||||
|
||||
const webcams = Object.values(me.webcamDevices);
|
||||
|
||||
return (
|
||||
<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}
|
||||
value={webcams[0]}
|
||||
placeholder='No other cameras detected'
|
||||
/>
|
||||
</div>
|
||||
<div className='footer'>
|
||||
<span
|
||||
className='button'
|
||||
onClick={() => onToggleSettings()}
|
||||
>
|
||||
Close
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Settings.propTypes =
|
||||
{
|
||||
me : appPropTypes.Me.isRequired,
|
||||
room : appPropTypes.Room.isRequired,
|
||||
onToggleSettings : PropTypes.func.isRequired,
|
||||
handleChangeWebcam : PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
return {
|
||||
me : state.me,
|
||||
room : state.room
|
||||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
handleChangeWebcam : (device) =>
|
||||
{
|
||||
dispatch(requestActions.changeWebcam(device.value));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const SettingsContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Settings);
|
||||
|
||||
export default SettingsContainer;
|
||||
@@ -9,6 +9,7 @@ const initialState =
|
||||
canShareScreen : false,
|
||||
needExtension : false,
|
||||
canChangeWebcam : false,
|
||||
webcamDevices : null,
|
||||
webcamInProgress : false,
|
||||
screenShareInProgress : false,
|
||||
audioOnly : false,
|
||||
@@ -50,6 +51,13 @@ const me = (state = initialState, action) =>
|
||||
return { ...state, canChangeWebcam };
|
||||
}
|
||||
|
||||
case 'SET_WEBCAM_DEVICES':
|
||||
{
|
||||
const devices = action.payload;
|
||||
|
||||
return { ...state, webcamDevices: devices };
|
||||
}
|
||||
|
||||
case 'SET_WEBCAM_IN_PROGRESS':
|
||||
{
|
||||
const { flag } = action.payload;
|
||||
|
||||
@@ -4,7 +4,8 @@ const initialState =
|
||||
state : 'new', // new/connecting/connected/disconnected/closed,
|
||||
activeSpeakerName : null,
|
||||
peerHeight : 300,
|
||||
peerWidth : 400
|
||||
peerWidth : 400,
|
||||
showSettings : false
|
||||
};
|
||||
|
||||
const room = (state = initialState, action) =>
|
||||
@@ -42,6 +43,13 @@ const room = (state = initialState, action) =>
|
||||
return { ...state, peerWidth: peerWidth, peerHeight: peerHeight };
|
||||
}
|
||||
|
||||
case 'TOGGLE_SETTINGS':
|
||||
{
|
||||
const showSettings = !state.showSettings;
|
||||
|
||||
return { ...state, showSettings };
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -57,10 +57,11 @@ export const disableWebcam = () =>
|
||||
};
|
||||
};
|
||||
|
||||
export const changeWebcam = () =>
|
||||
export const changeWebcam = (deviceId) =>
|
||||
{
|
||||
return {
|
||||
type : 'CHANGE_WEBCAM'
|
||||
type : 'CHANGE_WEBCAM',
|
||||
payload : { deviceId }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +83,9 @@ export default ({ dispatch, getState }) => (next) =>
|
||||
|
||||
case 'CHANGE_WEBCAM':
|
||||
{
|
||||
client.changeWebcam();
|
||||
const { deviceId } = action.payload;
|
||||
|
||||
client.changeWebcam(deviceId);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,14 @@ export const setCanChangeWebcam = (flag) =>
|
||||
};
|
||||
};
|
||||
|
||||
export const setWebcamDevices = (devices) =>
|
||||
{
|
||||
return {
|
||||
type : 'SET_WEBCAM_DEVICES',
|
||||
payload : devices
|
||||
};
|
||||
};
|
||||
|
||||
export const setDisplayName = (displayName) =>
|
||||
{
|
||||
return {
|
||||
@@ -110,6 +118,13 @@ export const setMyRaiseHandState = (flag) =>
|
||||
};
|
||||
};
|
||||
|
||||
export const toggleSettings = () =>
|
||||
{
|
||||
return {
|
||||
type : 'TOGGLE_SETTINGS'
|
||||
};
|
||||
};
|
||||
|
||||
export const setMyRaiseHandStateInProgress = (flag) =>
|
||||
{
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user