Merge branch 'feat-join-dialog' into develop
commit
e7a2b8bd6d
|
|
@ -65,10 +65,6 @@ const VIDEO_ENCODINGS =
|
||||||
|
|
||||||
let store;
|
let store;
|
||||||
|
|
||||||
const AudioContext = window.AudioContext // Default
|
|
||||||
|| window.webkitAudioContext // Safari and old versions of Chrome
|
|
||||||
|| false;
|
|
||||||
|
|
||||||
export default class RoomClient
|
export default class RoomClient
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -119,11 +115,6 @@ export default class RoomClient
|
||||||
// Alert sound
|
// Alert sound
|
||||||
this._soundAlert = new Audio('/sounds/notify.mp3');
|
this._soundAlert = new Audio('/sounds/notify.mp3');
|
||||||
|
|
||||||
if (AudioContext)
|
|
||||||
{
|
|
||||||
this._audioContext = new AudioContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Socket.io peer connection
|
// Socket.io peer connection
|
||||||
this._signalingSocket = null;
|
this._signalingSocket = null;
|
||||||
|
|
||||||
|
|
@ -661,9 +652,15 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
logger.debug('muteMic()');
|
logger.debug('muteMic()');
|
||||||
|
|
||||||
|
this._micProducer.pause();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this._micProducer.pause();
|
await this.sendRequest(
|
||||||
|
'pauseProducer', { producerId: this._micProducer.id });
|
||||||
|
|
||||||
|
store.dispatch(
|
||||||
|
stateActions.setProducerPaused(this._micProducer.id));
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
|
@ -681,14 +678,21 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
logger.debug('unmuteMic()');
|
logger.debug('unmuteMic()');
|
||||||
|
|
||||||
|
if (!this._micProducer)
|
||||||
|
{
|
||||||
|
this.enableMic();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._micProducer.resume();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (this._micProducer)
|
await this.sendRequest(
|
||||||
this._micProducer.resume();
|
'resumeProducer', { producerId: this._micProducer.id });
|
||||||
else if (this._room.canSend('audio'))
|
|
||||||
await this.enableMic();
|
store.dispatch(
|
||||||
else
|
stateActions.setProducerResumed(this._micProducer.id));
|
||||||
throw new Error('cannot send audio');
|
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
|
@ -701,6 +705,7 @@ export default class RoomClient
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Updated consumers based on spotlights
|
// Updated consumers based on spotlights
|
||||||
async updateSpotlights(spotlights)
|
async updateSpotlights(spotlights)
|
||||||
|
|
@ -1056,31 +1061,13 @@ export default class RoomClient
|
||||||
stateActions.setMyRaiseHandStateInProgress(false));
|
stateActions.setMyRaiseHandStateInProgress(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
async resumeAudio()
|
async join({ joinVideo })
|
||||||
{
|
|
||||||
logger.debug('resumeAudio()');
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await this._audioContext.resume();
|
|
||||||
|
|
||||||
store.dispatch(
|
|
||||||
stateActions.setAudioSuspended({ audioSuspended: false }));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (error)
|
|
||||||
{
|
|
||||||
store.dispatch(
|
|
||||||
stateActions.setAudioSuspended({ audioSuspended: true }));
|
|
||||||
logger.error('resumeAudioJoin() failed: %o', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async join()
|
|
||||||
{
|
{
|
||||||
this._signalingSocket = io(this._signalingUrl);
|
this._signalingSocket = io(this._signalingUrl);
|
||||||
|
|
||||||
this._spotlights = new Spotlights(this._maxSpotlights, this._signalingSocket);
|
this._spotlights = new Spotlights(this._maxSpotlights, this._signalingSocket);
|
||||||
|
|
||||||
|
store.dispatch(stateActions.toggleJoined());
|
||||||
store.dispatch(stateActions.setRoomState('connecting'));
|
store.dispatch(stateActions.setRoomState('connecting'));
|
||||||
|
|
||||||
this._signalingSocket.on('connect', () =>
|
this._signalingSocket.on('connect', () =>
|
||||||
|
|
@ -1258,7 +1245,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
case 'roomReady':
|
case 'roomReady':
|
||||||
{
|
{
|
||||||
await this._joinRoom();
|
await this._joinRoom({ joinVideo });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1514,7 +1501,7 @@ export default class RoomClient
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async _joinRoom()
|
async _joinRoom({ joinVideo })
|
||||||
{
|
{
|
||||||
logger.debug('_joinRoom()');
|
logger.debug('_joinRoom()');
|
||||||
|
|
||||||
|
|
@ -1664,10 +1651,10 @@ export default class RoomClient
|
||||||
if (this._produce)
|
if (this._produce)
|
||||||
{
|
{
|
||||||
if (this._mediasoupDevice.canProduce('audio'))
|
if (this._mediasoupDevice.canProduce('audio'))
|
||||||
await this.enableMic();
|
this.enableMic();
|
||||||
|
|
||||||
if (this._mediasoupDevice.canProduce('video'))
|
if (joinVideo && this._mediasoupDevice.canProduce('video'))
|
||||||
await this.enableWebcam();
|
this.enableWebcam();
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch(stateActions.setRoomState('connected'));
|
store.dispatch(stateActions.setRoomState('connected'));
|
||||||
|
|
@ -1875,15 +1862,6 @@ export default class RoomClient
|
||||||
store.dispatch(stateActions.setPeerVolume(this._peerId, volume));
|
store.dispatch(stateActions.setPeerVolume(this._peerId, volume));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this._audioContext)
|
|
||||||
{
|
|
||||||
// We need to provoke user interaction to get permission from browser to start audio
|
|
||||||
if (this._audioContext.state === 'suspended')
|
|
||||||
{
|
|
||||||
this.resumeAudio();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,6 @@ export const setRoomLockedOut = () =>
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setAudioSuspended = ({ audioSuspended }) =>
|
|
||||||
{
|
|
||||||
return {
|
|
||||||
type : 'SET_AUDIO_SUSPENDED',
|
|
||||||
payload : { audioSuspended }
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setSettingsOpen = ({ settingsOpen }) =>
|
export const setSettingsOpen = ({ settingsOpen }) =>
|
||||||
({
|
({
|
||||||
type : 'SET_SETTINGS_OPEN',
|
type : 'SET_SETTINGS_OPEN',
|
||||||
|
|
@ -568,6 +560,11 @@ export const loggedIn = () =>
|
||||||
type : 'LOGGED_IN'
|
type : 'LOGGED_IN'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const toggleJoined = () =>
|
||||||
|
({
|
||||||
|
type : 'TOGGLE_JOINED'
|
||||||
|
});
|
||||||
|
|
||||||
export const setSelectedPeer = (selectedPeerId) =>
|
export const setSelectedPeer = (selectedPeerId) =>
|
||||||
({
|
({
|
||||||
type : 'SET_SELECTED_PEER',
|
type : 'SET_SELECTED_PEER',
|
||||||
|
|
|
||||||
|
|
@ -78,11 +78,16 @@ const Sidebar = (props) =>
|
||||||
|
|
||||||
let micTip;
|
let micTip;
|
||||||
|
|
||||||
if (!me.canSendMic || !micProducer)
|
if (!me.canSendMic)
|
||||||
{
|
{
|
||||||
micState = 'unsupported';
|
micState = 'unsupported';
|
||||||
micTip = 'Audio unsupported';
|
micTip = 'Audio unsupported';
|
||||||
}
|
}
|
||||||
|
else if (!micProducer)
|
||||||
|
{
|
||||||
|
micState = 'off';
|
||||||
|
micTip = 'Activate audio';
|
||||||
|
}
|
||||||
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
|
||||||
{
|
{
|
||||||
micState = 'on';
|
micState = 'on';
|
||||||
|
|
@ -90,7 +95,7 @@ const Sidebar = (props) =>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
micState = 'off';
|
micState = 'muted';
|
||||||
micTip = 'Unmute audio';
|
micTip = 'Unmute audio';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -152,9 +157,12 @@ const Sidebar = (props) =>
|
||||||
size={smallScreen ? 'large' : 'medium'}
|
size={smallScreen ? 'large' : 'medium'}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
micState === 'on' ?
|
if (micState === 'off')
|
||||||
roomClient.disableMic() :
|
|
||||||
roomClient.enableMic();
|
roomClient.enableMic();
|
||||||
|
else if (micState === 'on')
|
||||||
|
roomClient.muteMic();
|
||||||
|
else
|
||||||
|
roomClient.unmuteMic();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ micState === 'on' ?
|
{ micState === 'on' ?
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import { withRoomContext } from '../RoomContext';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import Dialog from '@material-ui/core/Dialog';
|
||||||
|
import Typography from '@material-ui/core/Typography';
|
||||||
|
import DialogActions from '@material-ui/core/DialogActions';
|
||||||
|
import Button from '@material-ui/core/Button';
|
||||||
|
|
||||||
|
const styles = (theme) =>
|
||||||
|
({
|
||||||
|
root :
|
||||||
|
{
|
||||||
|
},
|
||||||
|
dialogPaper :
|
||||||
|
{
|
||||||
|
width : '20vw',
|
||||||
|
padding : theme.spacing.unit * 2,
|
||||||
|
[theme.breakpoints.down('lg')] :
|
||||||
|
{
|
||||||
|
width : '30vw'
|
||||||
|
},
|
||||||
|
[theme.breakpoints.down('md')] :
|
||||||
|
{
|
||||||
|
width : '40vw'
|
||||||
|
},
|
||||||
|
[theme.breakpoints.down('sm')] :
|
||||||
|
{
|
||||||
|
width : '60vw'
|
||||||
|
},
|
||||||
|
[theme.breakpoints.down('xs')] :
|
||||||
|
{
|
||||||
|
width : '80vw'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logo :
|
||||||
|
{
|
||||||
|
display : 'block'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const JoinDialog = ({
|
||||||
|
roomClient,
|
||||||
|
classes
|
||||||
|
}) =>
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
className={classes.root}
|
||||||
|
open
|
||||||
|
classes={{
|
||||||
|
paper : classes.dialogPaper
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{ window.config.logo ?
|
||||||
|
<img alt='Logo' className={classes.logo} src={window.config.logo} />
|
||||||
|
:null
|
||||||
|
}
|
||||||
|
<Typography variant='subtitle1'>You are about to join a meeting, how would you like to join?</Typography>
|
||||||
|
<DialogActions>
|
||||||
|
<Button
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
roomClient.join({ joinVideo: false });
|
||||||
|
}}
|
||||||
|
variant='contained'
|
||||||
|
>
|
||||||
|
Audio only
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() =>
|
||||||
|
{
|
||||||
|
roomClient.join({ joinVideo: true });
|
||||||
|
}}
|
||||||
|
variant='contained'
|
||||||
|
>
|
||||||
|
Audio and Video
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
JoinDialog.propTypes =
|
||||||
|
{
|
||||||
|
roomClient : PropTypes.any.isRequired,
|
||||||
|
classes : PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withRoomContext(withStyles(styles)(JoinDialog));
|
||||||
|
|
@ -15,7 +15,6 @@ import SwipeableDrawer from '@material-ui/core/SwipeableDrawer';
|
||||||
import Hidden from '@material-ui/core/Hidden';
|
import Hidden from '@material-ui/core/Hidden';
|
||||||
import Paper from '@material-ui/core/Paper';
|
import Paper from '@material-ui/core/Paper';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import Button from '@material-ui/core/Button';
|
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
import MenuIcon from '@material-ui/icons/Menu';
|
import MenuIcon from '@material-ui/icons/Menu';
|
||||||
import Avatar from '@material-ui/core/Avatar';
|
import Avatar from '@material-ui/core/Avatar';
|
||||||
|
|
@ -33,6 +32,7 @@ import FullScreenIcon from '@material-ui/icons/Fullscreen';
|
||||||
import FullScreenExitIcon from '@material-ui/icons/FullscreenExit';
|
import FullScreenExitIcon from '@material-ui/icons/FullscreenExit';
|
||||||
import SettingsIcon from '@material-ui/icons/Settings';
|
import SettingsIcon from '@material-ui/icons/Settings';
|
||||||
import Settings from './Settings/Settings';
|
import Settings from './Settings/Settings';
|
||||||
|
import JoinDialog from './JoinDialog';
|
||||||
|
|
||||||
const TIMEOUT = 10 * 1000;
|
const TIMEOUT = 10 * 1000;
|
||||||
|
|
||||||
|
|
@ -176,10 +176,6 @@ class Room extends React.PureComponent
|
||||||
|
|
||||||
componentDidMount()
|
componentDidMount()
|
||||||
{
|
{
|
||||||
const { roomClient } = this.props;
|
|
||||||
|
|
||||||
roomClient.join();
|
|
||||||
|
|
||||||
if (this.fullscreen.fullscreenEnabled)
|
if (this.fullscreen.fullscreenEnabled)
|
||||||
{
|
{
|
||||||
this.fullscreen.addEventListener('fullscreenchange', this.handleFullscreenChange);
|
this.fullscreen.addEventListener('fullscreenchange', this.handleFullscreenChange);
|
||||||
|
|
@ -242,29 +238,7 @@ class Room extends React.PureComponent
|
||||||
democratic : Democratic
|
democratic : Democratic
|
||||||
}[room.mode];
|
}[room.mode];
|
||||||
|
|
||||||
if (room.audioSuspended)
|
if (room.lockedOut)
|
||||||
{
|
|
||||||
return (
|
|
||||||
<div className={classes.root}>
|
|
||||||
<Paper className={classes.message}>
|
|
||||||
<Typography variant='h2'>
|
|
||||||
This webpage required sound and video to play, please click to allow.
|
|
||||||
</Typography>
|
|
||||||
<Button
|
|
||||||
variant='contained'
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
roomClient.notify('Joining.');
|
|
||||||
roomClient.resumeAudio();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Allow
|
|
||||||
</Button>
|
|
||||||
</Paper>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (room.lockedOut)
|
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
|
|
@ -274,6 +248,14 @@ class Room extends React.PureComponent
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else if (!room.joined)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<div className={classes.root}>
|
||||||
|
<JoinDialog />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ const initialState =
|
||||||
state : 'new', // new/connecting/connected/disconnected/closed,
|
state : 'new', // new/connecting/connected/disconnected/closed,
|
||||||
locked : false,
|
locked : false,
|
||||||
lockedOut : false,
|
lockedOut : false,
|
||||||
audioSuspended : false,
|
|
||||||
activeSpeakerId : null,
|
activeSpeakerId : null,
|
||||||
torrentSupport : false,
|
torrentSupport : false,
|
||||||
showSettings : false,
|
showSettings : false,
|
||||||
|
|
@ -14,7 +13,8 @@ const initialState =
|
||||||
mode : 'democratic',
|
mode : 'democratic',
|
||||||
selectedPeerId : null,
|
selectedPeerId : null,
|
||||||
spotlights : [],
|
spotlights : [],
|
||||||
settingsOpen : false
|
settingsOpen : false,
|
||||||
|
joined : false
|
||||||
};
|
};
|
||||||
|
|
||||||
const room = (state = initialState, action) =>
|
const room = (state = initialState, action) =>
|
||||||
|
|
@ -53,13 +53,6 @@ const room = (state = initialState, action) =>
|
||||||
return { ...state, lockedOut: true };
|
return { ...state, lockedOut: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_AUDIO_SUSPENDED':
|
|
||||||
{
|
|
||||||
const { audioSuspended } = action.payload;
|
|
||||||
|
|
||||||
return { ...state, audioSuspended };
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'SET_SETTINGS_OPEN':
|
case 'SET_SETTINGS_OPEN':
|
||||||
{
|
{
|
||||||
const { settingsOpen } = action.payload;
|
const { settingsOpen } = action.payload;
|
||||||
|
|
@ -88,6 +81,13 @@ const room = (state = initialState, action) =>
|
||||||
return { ...state, showSettings };
|
return { ...state, showSettings };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'TOGGLE_JOINED':
|
||||||
|
{
|
||||||
|
const joined = !state.joined;
|
||||||
|
|
||||||
|
return { ...state, joined };
|
||||||
|
}
|
||||||
|
|
||||||
case 'TOGGLE_FULLSCREEN_CONSUMER':
|
case 'TOGGLE_FULLSCREEN_CONSUMER':
|
||||||
{
|
{
|
||||||
const { consumerId } = action.payload;
|
const { consumerId } = action.payload;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue