Only show Peer controls when hovering

master
Torjus 2018-07-16 12:56:50 +02:00
parent 79376b3a50
commit 55c1506281
7 changed files with 207 additions and 170 deletions

View File

@ -1,4 +1,4 @@
import React from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import classnames from 'classnames'; import classnames from 'classnames';
@ -8,130 +8,118 @@ import * as stateActions from '../redux/stateActions';
import PeerView from './PeerView'; import PeerView from './PeerView';
import ScreenView from './ScreenView'; import ScreenView from './ScreenView';
const Peer = (props) => class Peer extends Component
{ {
const { state = {
advancedMode, controlsVisible : false
peer, };
micConsumer,
webcamConsumer,
screenConsumer,
onMuteMic,
onUnmuteMic,
onDisableWebcam,
onEnableWebcam,
onDisableScreen,
onEnableScreen,
toggleConsumerFullscreen,
style
} = props;
const micEnabled = ( handleMouseOver = () =>
Boolean(micConsumer) && {
!micConsumer.locallyPaused && this.setState({
!micConsumer.remotelyPaused controlsVisible : true
); });
};
const videoVisible = ( handleMouseOut = () =>
Boolean(webcamConsumer) && {
!webcamConsumer.locallyPaused && this.setState({
!webcamConsumer.remotelyPaused controlsVisible : false
); });
};
const screenVisible = ( render()
Boolean(screenConsumer) && {
!screenConsumer.locallyPaused && const {
!screenConsumer.remotelyPaused advancedMode,
); peer,
micConsumer,
webcamConsumer,
screenConsumer,
onMuteMic,
onUnmuteMic,
onDisableWebcam,
onEnableWebcam,
onDisableScreen,
onEnableScreen,
toggleConsumerFullscreen,
style
} = this.props;
let videoProfile; const micEnabled = (
Boolean(micConsumer) &&
!micConsumer.locallyPaused &&
!micConsumer.remotelyPaused
);
if (webcamConsumer) const videoVisible = (
videoProfile = webcamConsumer.profile; Boolean(webcamConsumer) &&
!webcamConsumer.locallyPaused &&
!webcamConsumer.remotelyPaused
);
let screenProfile; const screenVisible = (
Boolean(screenConsumer) &&
!screenConsumer.locallyPaused &&
!screenConsumer.remotelyPaused
);
if (screenConsumer) let videoProfile;
screenProfile = screenConsumer.profile;
return ( if (webcamConsumer)
<div videoProfile = webcamConsumer.profile;
data-component='Peer'
className={classnames({
screen : screenConsumer
})}
>
{videoVisible && !webcamConsumer.supported ?
<div className='incompatible-video'>
<p>incompatible video</p>
</div>
:null
}
<div className={classnames('view-container', 'webcam')} style={style}> let screenProfile;
<div className='controls'>
if (screenConsumer)
screenProfile = screenConsumer.profile;
return (
<div
data-component='Peer'
className={classnames({
screen : screenConsumer
})}
onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
>
{videoVisible && !webcamConsumer.supported ?
<div className='incompatible-video'>
<p>incompatible video</p>
</div>
:null
}
<div className={classnames('view-container', 'webcam')} style={style}>
<div <div
className={classnames('button', 'mic', { className={classnames('controls', {
on : micEnabled, visible : this.state.controlsVisible
off : !micEnabled,
disabled : peer.peerAudioInProgress
})} })}
onClick={(e) => >
{
e.stopPropagation();
micEnabled ? onMuteMic(peer.name) : onUnmuteMic(peer.name);
}}
/>
<div
className={classnames('button', 'webcam', {
on : videoVisible,
off : !videoVisible,
disabled : peer.peerVideoInProgress
})}
onClick={(e) =>
{
e.stopPropagation();
videoVisible ?
onDisableWebcam(peer.name) : onEnableWebcam(peer.name);
}}
/>
<div
className={classnames('button', 'fullscreen')}
onClick={(e) =>
{
e.stopPropagation();
toggleConsumerFullscreen(webcamConsumer);
}}
/>
</div>
<PeerView
advancedMode={advancedMode}
peer={peer}
audioTrack={micConsumer ? micConsumer.track : null}
videoTrack={webcamConsumer ? webcamConsumer.track : null}
videoVisible={videoVisible}
videoProfile={videoProfile}
audioCodec={micConsumer ? micConsumer.codec : null}
videoCodec={webcamConsumer ? webcamConsumer.codec : null}
/>
</div>
{screenConsumer ?
<div className={classnames('view-container', 'screen')} style={style}>
<div className='controls'>
<div <div
className={classnames('button', 'screen', { className={classnames('button', 'mic', {
on : screenVisible, on : micEnabled,
off : !screenVisible, off : !micEnabled,
disabled : peer.peerScreenInProgress disabled : peer.peerAudioInProgress
})} })}
onClick={(e) => onClick={(e) =>
{ {
e.stopPropagation(); e.stopPropagation();
screenVisible ? micEnabled ? onMuteMic(peer.name) : onUnmuteMic(peer.name);
onDisableScreen(peer.name) : onEnableScreen(peer.name); }}
/>
<div
className={classnames('button', 'webcam', {
on : videoVisible,
off : !videoVisible,
disabled : peer.peerVideoInProgress
})}
onClick={(e) =>
{
e.stopPropagation();
videoVisible ?
onDisableWebcam(peer.name) : onEnableWebcam(peer.name);
}} }}
/> />
@ -140,23 +128,62 @@ const Peer = (props) =>
onClick={(e) => onClick={(e) =>
{ {
e.stopPropagation(); e.stopPropagation();
toggleConsumerFullscreen(screenConsumer); toggleConsumerFullscreen(webcamConsumer);
}} }}
/> />
</div> </div>
<ScreenView <PeerView
advancedMode={advancedMode} advancedMode={advancedMode}
screenTrack={screenConsumer ? screenConsumer.track : null} peer={peer}
screenVisible={screenVisible} audioTrack={micConsumer ? micConsumer.track : null}
screenProfile={screenProfile} videoTrack={webcamConsumer ? webcamConsumer.track : null}
screenCodec={screenConsumer ? screenConsumer.codec : null} videoVisible={videoVisible}
videoProfile={videoProfile}
audioCodec={micConsumer ? micConsumer.codec : null}
videoCodec={webcamConsumer ? webcamConsumer.codec : null}
/> />
</div> </div>
:null
} {screenConsumer ?
</div> <div className={classnames('view-container', 'screen')} style={style}>
); <div className='controls'>
}; <div
className={classnames('button', 'screen', {
on : screenVisible,
off : !screenVisible,
disabled : peer.peerScreenInProgress
})}
onClick={(e) =>
{
e.stopPropagation();
screenVisible ?
onDisableScreen(peer.name) : onEnableScreen(peer.name);
}}
/>
<div
className={classnames('button', 'fullscreen')}
onClick={(e) =>
{
e.stopPropagation();
toggleConsumerFullscreen(screenConsumer);
}}
/>
</div>
<ScreenView
advancedMode={advancedMode}
screenTrack={screenConsumer ? screenConsumer.track : null}
screenVisible={screenVisible}
screenProfile={screenProfile}
screenCodec={screenConsumer ? screenConsumer.codec : null}
/>
</div>
:null
}
</div>
);
}
}
Peer.propTypes = Peer.propTypes =
{ {

View File

@ -15,30 +15,11 @@ import ToolAreaButton from './ToolArea/ToolAreaButton';
import ToolArea from './ToolArea/ToolArea'; import ToolArea from './ToolArea/ToolArea';
import FullScreenView from './FullScreenView'; import FullScreenView from './FullScreenView';
import Draggable from 'react-draggable'; import Draggable from 'react-draggable';
import { idle } from '../utils';
// Hide toolbars after 10 seconds of inactivity. // Hide toolbars after 10 seconds of inactivity.
const TIMEOUT = 10 * 1000; const TIMEOUT = 10 * 1000;
/**
* Create a function which will call the callback function
* after the given amount of milliseconds has passed since
* the last time the callback function was called.
*/
const idle = (callback, delay) =>
{
let handle;
return () =>
{
if (handle)
{
clearTimeout(handle);
}
handle = setTimeout(callback, delay);
};
};
class Room extends React.Component class Room extends React.Component
{ {
/** /**

View File

@ -43,3 +43,23 @@ export function getBrowserType()
return 'N/A'; return 'N/A';
} }
/**
* Create a function which will call the callback function
* after the given amount of milliseconds has passed since
* the last time the callback function was called.
*/
export const idle = (callback, delay) =>
{
let handle;
return () =>
{
if (handle)
{
clearTimeout(handle);
}
handle = setTimeout(callback, delay);
};
};

View File

@ -41,6 +41,15 @@
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
padding: 0.4vmin; padding: 0.4vmin;
visibility: hidden;
opacity: 0;
animation: fade-out 0.3s;
&.visible {
visibility: visible;
opacity: 1;
animation: fade-in 0.3s;
}
> .button { > .button {
flex: 0 0 auto; flex: 0 0 auto;

View File

@ -440,27 +440,3 @@
@keyframes Room-info-state-connecting { @keyframes Room-info-state-connecting {
50% { background-color: rgba(orange, 0.75); } 50% { background-color: rgba(orange, 0.75); }
} }
@keyframes fade-in {
from {
opacity: 0;
visibility: hidden;
}
to {
opacity: 1;
visibility: visible;
}
}
@keyframes fade-out {
from {
opacity: 1;
visibility: visible;
}
to {
opacity: 0;
visibility: hidden;
}
}

View File

@ -5,6 +5,7 @@ global-reset();
@import './mixins'; @import './mixins';
@import './fonts'; @import './fonts';
@import './reset'; @import './reset';
@import './keyframes';
html { html {
height: 100%; height: 100%;

View File

@ -0,0 +1,23 @@
@keyframes fade-in {
from {
opacity: 0;
visibility: hidden;
}
to {
opacity: 1;
visibility: visible;
}
}
@keyframes fade-out {
from {
opacity: 1;
visibility: visible;
}
to {
opacity: 0;
visibility: hidden;
}
}