Merge branch 'feat-join-dialog' into develop

master
Håvar Aambø Fosstveit 2019-06-13 13:57:01 +02:00
commit e7a2b8bd6d
6 changed files with 162 additions and 107 deletions

View File

@ -65,10 +65,6 @@ const VIDEO_ENCODINGS =
let store;
const AudioContext = window.AudioContext // Default
|| window.webkitAudioContext // Safari and old versions of Chrome
|| false;
export default class RoomClient
{
/**
@ -119,11 +115,6 @@ export default class RoomClient
// Alert sound
this._soundAlert = new Audio('/sounds/notify.mp3');
if (AudioContext)
{
this._audioContext = new AudioContext();
}
// Socket.io peer connection
this._signalingSocket = null;
@ -661,9 +652,15 @@ export default class RoomClient
{
logger.debug('muteMic()');
this._micProducer.pause();
try
{
this._micProducer.pause();
await this.sendRequest(
'pauseProducer', { producerId: this._micProducer.id });
store.dispatch(
stateActions.setProducerPaused(this._micProducer.id));
}
catch (error)
{
@ -681,24 +678,32 @@ export default class RoomClient
{
logger.debug('unmuteMic()');
try
if (!this._micProducer)
{
if (this._micProducer)
this._micProducer.resume();
else if (this._room.canSend('audio'))
await this.enableMic();
else
throw new Error('cannot send audio');
this.enableMic();
}
catch (error)
else
{
logger.error('unmuteMic() | failed: %o', error);
this._micProducer.resume();
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'An error occured while accessing your microphone.'
}));
try
{
await this.sendRequest(
'resumeProducer', { producerId: this._micProducer.id });
store.dispatch(
stateActions.setProducerResumed(this._micProducer.id));
}
catch (error)
{
logger.error('unmuteMic() | failed: %o', error);
store.dispatch(requestActions.notify(
{
type : 'error',
text : 'An error occured while accessing your microphone.'
}));
}
}
}
@ -1056,31 +1061,13 @@ export default class RoomClient
stateActions.setMyRaiseHandStateInProgress(false));
}
async resumeAudio()
{
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()
async join({ joinVideo })
{
this._signalingSocket = io(this._signalingUrl);
this._spotlights = new Spotlights(this._maxSpotlights, this._signalingSocket);
store.dispatch(stateActions.toggleJoined());
store.dispatch(stateActions.setRoomState('connecting'));
this._signalingSocket.on('connect', () =>
@ -1258,7 +1245,7 @@ export default class RoomClient
{
case 'roomReady':
{
await this._joinRoom();
await this._joinRoom({ joinVideo });
break;
}
@ -1514,7 +1501,7 @@ export default class RoomClient
});
}
async _joinRoom()
async _joinRoom({ joinVideo })
{
logger.debug('_joinRoom()');
@ -1664,10 +1651,10 @@ export default class RoomClient
if (this._produce)
{
if (this._mediasoupDevice.canProduce('audio'))
await this.enableMic();
this.enableMic();
if (this._mediasoupDevice.canProduce('video'))
await this.enableWebcam();
if (joinVideo && this._mediasoupDevice.canProduce('video'))
this.enableWebcam();
}
store.dispatch(stateActions.setRoomState('connected'));
@ -1875,15 +1862,6 @@ export default class RoomClient
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)
{

View File

@ -43,14 +43,6 @@ export const setRoomLockedOut = () =>
};
};
export const setAudioSuspended = ({ audioSuspended }) =>
{
return {
type : 'SET_AUDIO_SUSPENDED',
payload : { audioSuspended }
};
};
export const setSettingsOpen = ({ settingsOpen }) =>
({
type : 'SET_SETTINGS_OPEN',
@ -568,6 +560,11 @@ export const loggedIn = () =>
type : 'LOGGED_IN'
});
export const toggleJoined = () =>
({
type : 'TOGGLE_JOINED'
});
export const setSelectedPeer = (selectedPeerId) =>
({
type : 'SET_SELECTED_PEER',

View File

@ -78,11 +78,16 @@ const Sidebar = (props) =>
let micTip;
if (!me.canSendMic || !micProducer)
if (!me.canSendMic)
{
micState = 'unsupported';
micTip = 'Audio unsupported';
}
else if (!micProducer)
{
micState = 'off';
micTip = 'Activate audio';
}
else if (!micProducer.locallyPaused && !micProducer.remotelyPaused)
{
micState = 'on';
@ -90,7 +95,7 @@ const Sidebar = (props) =>
}
else
{
micState = 'off';
micState = 'muted';
micTip = 'Unmute audio';
}
@ -152,9 +157,12 @@ const Sidebar = (props) =>
size={smallScreen ? 'large' : 'medium'}
onClick={() =>
{
micState === 'on' ?
roomClient.disableMic() :
if (micState === 'off')
roomClient.enableMic();
else if (micState === 'on')
roomClient.muteMic();
else
roomClient.unmuteMic();
}}
>
{ micState === 'on' ?

View File

@ -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));

View File

@ -15,7 +15,6 @@ import SwipeableDrawer from '@material-ui/core/SwipeableDrawer';
import Hidden from '@material-ui/core/Hidden';
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
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 SettingsIcon from '@material-ui/icons/Settings';
import Settings from './Settings/Settings';
import JoinDialog from './JoinDialog';
const TIMEOUT = 10 * 1000;
@ -176,10 +176,6 @@ class Room extends React.PureComponent
componentDidMount()
{
const { roomClient } = this.props;
roomClient.join();
if (this.fullscreen.fullscreenEnabled)
{
this.fullscreen.addEventListener('fullscreenchange', this.handleFullscreenChange);
@ -242,29 +238,7 @@ class Room extends React.PureComponent
democratic : Democratic
}[room.mode];
if (room.audioSuspended)
{
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)
if (room.lockedOut)
{
return (
<div className={classes.root}>
@ -274,6 +248,14 @@ class Room extends React.PureComponent
</div>
);
}
else if (!room.joined)
{
return (
<div className={classes.root}>
<JoinDialog />
</div>
);
}
else
{
return (

View File

@ -4,7 +4,6 @@ const initialState =
state : 'new', // new/connecting/connected/disconnected/closed,
locked : false,
lockedOut : false,
audioSuspended : false,
activeSpeakerId : null,
torrentSupport : false,
showSettings : false,
@ -14,7 +13,8 @@ const initialState =
mode : 'democratic',
selectedPeerId : null,
spotlights : [],
settingsOpen : false
settingsOpen : false,
joined : false
};
const room = (state = initialState, action) =>
@ -53,13 +53,6 @@ const room = (state = initialState, action) =>
return { ...state, lockedOut: true };
}
case 'SET_AUDIO_SUSPENDED':
{
const { audioSuspended } = action.payload;
return { ...state, audioSuspended };
}
case 'SET_SETTINGS_OPEN':
{
const { settingsOpen } = action.payload;
@ -88,6 +81,13 @@ const room = (state = initialState, action) =>
return { ...state, showSettings };
}
case 'TOGGLE_JOINED':
{
const joined = !state.joined;
return { ...state, joined };
}
case 'TOGGLE_FULLSCREEN_CONSUMER':
{
const { consumerId } = action.payload;