Created a simple toolbar
- Audio/Video toggling - Fullscreen - Hangout (return to homepage)
This commit is contained in:
parent
21e3040dc3
commit
ce7eed3541
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@ -0,0 +1,11 @@
|
||||
; top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
; Unix-style newlines
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
.DS_Store
|
||||
yarn.lock
|
||||
*.swp
|
||||
*.swo
|
||||
dist/
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import Alerts, { AlertPropType } from './Alerts.js'
|
||||
import * as constants from '../constants.js'
|
||||
import Toolbar from './Toolbar.js'
|
||||
import Input from './Input.js'
|
||||
import Notifications, { NotificationPropTypes } from './Notifications.js'
|
||||
import PropTypes from 'prop-types'
|
||||
@ -38,6 +39,7 @@ export default class App extends React.PureComponent {
|
||||
} = this.props
|
||||
|
||||
return (<div className="app">
|
||||
<Toolbar stream={streams[constants.ME]} />
|
||||
<Alerts alerts={alerts} dismiss={dismissAlert} />
|
||||
<Notifications notifications={notifications} />
|
||||
<Input notify={notify} sendMessage={sendMessage} />
|
||||
|
||||
100
src/client/components/Toolbar.js
Normal file
100
src/client/components/Toolbar.js
Normal file
@ -0,0 +1,100 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
import { StreamPropType } from './video.js'
|
||||
|
||||
export default class Toolbar extends React.PureComponent {
|
||||
static propTypes = {
|
||||
stream: StreamPropType
|
||||
}
|
||||
handleMicClick = e => {
|
||||
const { stream } = this.props
|
||||
stream.mediaStream.getAudioTracks().forEach(track => {
|
||||
track.enabled = !track.enabled
|
||||
});
|
||||
e.currentTarget.classList.toggle('on')
|
||||
}
|
||||
handleCamClick = e => {
|
||||
const { stream } = this.props
|
||||
stream.mediaStream.getVideoTracks().forEach(track => {
|
||||
track.enabled = !track.enabled
|
||||
});
|
||||
e.currentTarget.classList.toggle('on')
|
||||
}
|
||||
handleFullscreenClick = e => {
|
||||
const document = window.document;
|
||||
const fs = document.getElementById('container');
|
||||
if (
|
||||
!document.fullscreenElement &&
|
||||
!document.mozFullScreenElement &&
|
||||
!document.webkitFullscreenElement &&
|
||||
!document.msFullscreenElement
|
||||
) {
|
||||
if (fs.requestFullscreen) {
|
||||
fs.requestFullscreen();
|
||||
} else if (fs.msRequestFullscreen) {
|
||||
fs.msRequestFullscreen();
|
||||
} else if (fs.mozRequestFullScreen) {
|
||||
fs.mozRequestFullScreen();
|
||||
} else if (fs.webkitRequestFullscreen) {
|
||||
fs.webkitRequestFullscreen();
|
||||
}
|
||||
} else {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
} else if (document.webkitExitFullscreen) {
|
||||
document.webkitExitFullscreen();
|
||||
}
|
||||
}
|
||||
e.target.classList.toggle('on')
|
||||
}
|
||||
handleHangoutClick = e => {
|
||||
location.href = '/'
|
||||
}
|
||||
render () {
|
||||
const { stream } = this.props
|
||||
|
||||
return (
|
||||
<div className="toolbar active">
|
||||
|
||||
{stream && (
|
||||
<svg onClick={this.handleMicClick} className="mute-audio" xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 1024 1024">
|
||||
<circle cx="24" cy="24" r="34">
|
||||
<title>Mute audio</title>
|
||||
</circle>
|
||||
<path className="on" transform="scale(0.4), translate(800,800)" d="M182 149.333l714 714-54 54-178-178c-32 20-72 32-110 38v140h-84v-140c-140-20-256-140-256-286h72c0 128 108 216 226 216 34 0 68-8 98-22l-70-70c-8 2-18 4-28 4-70 0-128-58-128-128v-32l-256-256zm458 348l-256-254v-8c0-70 58-128 128-128s128 58 128 128v262zm170-6c0 50-14 98-38 140l-52-54c12-26 18-54 18-86h72z" fill="white"/>
|
||||
<path className="off" transform="scale(0.4), translate(800,800)" d="M738 491.333h72c0 146-116 266-256 286v140h-84v-140c-140-20-256-140-256-286h72c0 128 108 216 226 216s226-88 226-216zm-226 128c-70 0-128-58-128-128v-256c0-70 58-128 128-128s128 58 128 128v256c0 70-58 128-128 128z" fill="white"/>
|
||||
</svg>
|
||||
)}
|
||||
|
||||
{stream && (
|
||||
<svg onClick={this.handleCamClick} className="mute-video" xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 1024 1024">
|
||||
<circle cx="24" cy="24" r="34">
|
||||
<title>Mute video</title>
|
||||
</circle>
|
||||
<path className="on" transform="scale(0.4), translate(800,800)" d="M140 107.333l756 756-54 54-136-136c-6 4-16 8-24 8H170c-24 0-42-18-42-42v-428c0-24 18-42 42-42h32l-116-116zm756 192v456l-478-478h264c24 0 44 18 44 42v150z" fill="white"/>
|
||||
<path className="off" transform="scale(0.4), translate(800,800)" d="M726 469.333l170-170v468l-170-170v150c0 24-20 42-44 42H170c-24 0-42-18-42-42v-428c0-24 18-42 42-42h512c24 0 44 18 44 42v150z" fill="white"/>
|
||||
</svg>
|
||||
)}
|
||||
|
||||
<svg onClick={this.handleFullscreenClick} className="fullscreen" xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 1024 1024">
|
||||
<circle cx="24" cy="24" r="34">
|
||||
<title>Enter fullscreen</title>
|
||||
</circle>
|
||||
<path className="on" transform="scale(0.4), translate(800,800)" d="M682 363.333h128v84H598v-212h84v128zm-84 468v-212h212v84H682v128h-84zm-256-468v-128h84v212H214v-84h128zm-128 340v-84h212v212h-84v-128H214z" fill="white"/>
|
||||
<path className="off" transform="scale(0.4), translate(800,800)" d="M598 235.333h212v212h-84v-128H598v-84zm128 512v-128h84v212H598v-84h128zm-512-300v-212h212v84H298v128h-84zm84 172v128h128v84H214v-212h84z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
<svg onClick={this.handleHangoutClick} className="hangup" xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 1024 1024">
|
||||
<circle cx="24" cy="24" r="34">
|
||||
<title>Hangup</title>
|
||||
</circle>
|
||||
<path transform="scale(0.4), translate(800,800)" d="M512 405.333c-68 0-134 10-196 30v132c0 16-10 34-24 40-42 20-80 46-114 78-8 8-18 12-30 12s-22-4-30-12l-106-106c-8-8-12-18-12-30s4-22 12-30c130-124 306-200 500-200s370 76 500 200c8 8 12 18 12 30s-4 22-12 30l-106 106c-8 8-18 12-30 12s-22-4-30-12c-34-32-72-58-114-78-14-6-24-20-24-38v-132c-62-20-128-32-196-32z" fill="white"/>
|
||||
</svg>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -50,7 +50,7 @@ export default class Video extends React.PureComponent {
|
||||
<div className={className}>
|
||||
<video
|
||||
autoPlay
|
||||
muted={userId === ME}
|
||||
//muted={userId === ME}
|
||||
onClick={this.handleClick}
|
||||
onLoadedMetadata={this.play}
|
||||
playsInline
|
||||
|
||||
@ -278,6 +278,114 @@ body.call {
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
bottom: 80px;
|
||||
left: 6vw;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
circle {
|
||||
fill: #666;
|
||||
fill-opacity: 0.6;
|
||||
}
|
||||
|
||||
svg.on circle {
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
/* on icons are hidden by default */
|
||||
|
||||
path {
|
||||
&.on {
|
||||
display: none;
|
||||
}
|
||||
&.off {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* off icons are displayed by default */
|
||||
|
||||
/* on icons are displayed when parent svg has class 'on' */
|
||||
|
||||
svg {
|
||||
&.on path {
|
||||
&.on {
|
||||
display: block;
|
||||
}
|
||||
&.off {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
//background-color: #333;
|
||||
border-radius: 48px;
|
||||
box-shadow: 2px 2px 24px #444;
|
||||
display: block;
|
||||
margin: 0 0 3vh 0;
|
||||
transform: translateX(calc(-6vw - 96px));
|
||||
transition: all .1s;
|
||||
transition-timing-function: ease-in-out;
|
||||
&:hover {
|
||||
box-shadow: 4px 4px 48px #666;
|
||||
}
|
||||
}
|
||||
|
||||
/* off icons are hidden when parent svg has class 'on' */
|
||||
|
||||
&.active svg {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.chat {
|
||||
transition: 200ms;
|
||||
&:hover {
|
||||
background: #407cf7;
|
||||
circle {
|
||||
fill: #407cf7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mute-audio {
|
||||
transition: 40ms;
|
||||
&:hover, &.on {
|
||||
background: #407cf7;
|
||||
}
|
||||
&:hover circle {
|
||||
fill: #407cf7;
|
||||
}
|
||||
}
|
||||
|
||||
.mute-video {
|
||||
transition: 120ms;
|
||||
&:hover, &.on {
|
||||
background: #407cf7;
|
||||
}
|
||||
&:hover circle {
|
||||
fill: #407cf7;
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen {
|
||||
transition: 280ms;
|
||||
&:hover, &.on {
|
||||
background: #407cf7;
|
||||
}
|
||||
&:hover circle {
|
||||
fill: #407cf7;
|
||||
}
|
||||
}
|
||||
|
||||
.hangup {
|
||||
transition: 360ms;
|
||||
&:hover {
|
||||
background: #dd2c00;
|
||||
circle {
|
||||
fill: #dd2c00;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user