|
|
@ -108,6 +108,7 @@ export default class Video extends React.PureComponent { |
|
|
|
state = { |
|
|
|
currentTime: 0, |
|
|
|
duration: 0, |
|
|
|
volume: 0.5, |
|
|
|
paused: true, |
|
|
|
dragging: false, |
|
|
|
containerWidth: false, |
|
|
@ -117,6 +118,15 @@ export default class Video extends React.PureComponent { |
|
|
|
revealed: this.props.revealed === undefined ? (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all') : this.props.revealed, |
|
|
|
}; |
|
|
|
|
|
|
|
// hard coded in components.scss
|
|
|
|
// any way to get ::before values programatically?
|
|
|
|
volWidth = 50; |
|
|
|
volOffset = 70; |
|
|
|
volHandleOffset = v => { |
|
|
|
const offset = v * this.volWidth + this.volOffset; |
|
|
|
return (offset > 110) ? 110 : offset; |
|
|
|
} |
|
|
|
|
|
|
|
setPlayerRef = c => { |
|
|
|
this.player = c; |
|
|
|
|
|
|
@ -135,6 +145,10 @@ export default class Video extends React.PureComponent { |
|
|
|
this.seek = c; |
|
|
|
} |
|
|
|
|
|
|
|
setVolumeRef = c => { |
|
|
|
this.volume = c; |
|
|
|
} |
|
|
|
|
|
|
|
handleMouseDownRoot = e => { |
|
|
|
e.preventDefault(); |
|
|
|
e.stopPropagation(); |
|
|
@ -155,6 +169,43 @@ export default class Video extends React.PureComponent { |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
handleVolumeMouseDown = e => { |
|
|
|
|
|
|
|
document.addEventListener('mousemove', this.handleMouseVolSlide, true); |
|
|
|
document.addEventListener('mouseup', this.handleVolumeMouseUp, true); |
|
|
|
document.addEventListener('touchmove', this.handleMouseVolSlide, true); |
|
|
|
document.addEventListener('touchend', this.handleVolumeMouseUp, true); |
|
|
|
|
|
|
|
this.handleMouseVolSlide(e); |
|
|
|
|
|
|
|
e.preventDefault(); |
|
|
|
e.stopPropagation(); |
|
|
|
} |
|
|
|
|
|
|
|
handleVolumeMouseUp = () => { |
|
|
|
document.removeEventListener('mousemove', this.handleMouseVolSlide, true); |
|
|
|
document.removeEventListener('mouseup', this.handleVolumeMouseUp, true); |
|
|
|
document.removeEventListener('touchmove', this.handleMouseVolSlide, true); |
|
|
|
document.removeEventListener('touchend', this.handleVolumeMouseUp, true); |
|
|
|
} |
|
|
|
|
|
|
|
handleMouseVolSlide = throttle(e => { |
|
|
|
|
|
|
|
const rect = this.volume.getBoundingClientRect(); |
|
|
|
const x = (e.clientX - rect.left) / this.volWidth; //x position within the element.
|
|
|
|
|
|
|
|
if(!isNaN(x)) { |
|
|
|
var slideamt = x; |
|
|
|
if(x > 1) { |
|
|
|
slideamt = 1; |
|
|
|
} else if(x < 0) { |
|
|
|
slideamt = 0; |
|
|
|
} |
|
|
|
this.video.volume = slideamt; |
|
|
|
this.setState({ volume: slideamt }); |
|
|
|
} |
|
|
|
}, 60); |
|
|
|
|
|
|
|
handleMouseDown = e => { |
|
|
|
document.addEventListener('mousemove', this.handleMouseMove, true); |
|
|
|
document.addEventListener('mouseup', this.handleMouseUp, true); |
|
|
@ -290,10 +341,13 @@ export default class Video extends React.PureComponent { |
|
|
|
|
|
|
|
render () { |
|
|
|
const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed, sensitive } = this.props; |
|
|
|
const { containerWidth, currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state; |
|
|
|
const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state; |
|
|
|
const progress = (currentTime / duration) * 100; |
|
|
|
const playerStyle = {}; |
|
|
|
|
|
|
|
const volumeWidth = (muted) ? 0 : volume * this.volWidth; |
|
|
|
const volumeHandleLoc = (muted) ? this.volHandleOffset(0) : this.volHandleOffset(volume); |
|
|
|
|
|
|
|
const computedClass = classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen, letterbox, 'full-width': fullwidth }); |
|
|
|
|
|
|
|
let { width, height } = this.props; |
|
|
@ -346,6 +400,7 @@ export default class Video extends React.PureComponent { |
|
|
|
title={alt} |
|
|
|
width={width} |
|
|
|
height={height} |
|
|
|
volume={volume} |
|
|
|
onClick={this.togglePlay} |
|
|
|
onPlay={this.handlePlay} |
|
|
|
onPause={this.handlePause} |
|
|
@ -374,9 +429,15 @@ export default class Video extends React.PureComponent { |
|
|
|
<div className='video-player__buttons-bar'> |
|
|
|
<div className='video-player__buttons left'> |
|
|
|
<button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><i className={classNames('fa fa-fw', { 'fa-play': paused, 'fa-pause': !paused })} /></button> |
|
|
|
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><i className={classNames('fa fa-fw', { 'fa-volume-off': muted, 'fa-volume-up': !muted })} /></button> |
|
|
|
|
|
|
|
{!onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><i className='fa fa-fw fa-eye' /></button>} |
|
|
|
<button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onMouseEnter={this.volumeSlider} onMouseLeave={this.volumeSlider} onClick={this.toggleMute}><i className={classNames('fa fa-fw', { 'fa-volume-off': muted, 'fa-volume-up': !muted })} /></button> |
|
|
|
<div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}> |
|
|
|
<div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} /> |
|
|
|
<span |
|
|
|
className={classNames('video-player__volume__handle')} |
|
|
|
tabIndex='0' |
|
|
|
style={{ left: `${volumeHandleLoc}px` }} |
|
|
|
/> |
|
|
|
</div> |
|
|
|
|
|
|
|
{(detailed || fullscreen) && |
|
|
|
<span> |
|
|
@ -388,6 +449,7 @@ export default class Video extends React.PureComponent { |
|
|
|
</div> |
|
|
|
|
|
|
|
<div className='video-player__buttons right'> |
|
|
|
{!onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><i className='fa fa-fw fa-eye' /></button>} |
|
|
|
{(!fullscreen && onOpenVideo) && <button type='button' aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><i className='fa fa-fw fa-expand' /></button>} |
|
|
|
{onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><i className='fa fa-fw fa-compress' /></button>} |
|
|
|
<button type='button' aria-label={intl.formatMessage(fullscreen ? messages.exit_fullscreen : messages.fullscreen)} onClick={this.toggleFullscreen}><i className={classNames('fa fa-fw', { 'fa-arrows-alt': !fullscreen, 'fa-compress': fullscreen })} /></button> |
|
|
|