|
|
|
@ -4,6 +4,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; |
|
|
|
|
import { throttle } from 'lodash'; |
|
|
|
|
import classNames from 'classnames'; |
|
|
|
|
import { isFullscreen, requestFullscreen, exitFullscreen } from 'flavours/glitch/util/fullscreen'; |
|
|
|
|
import { displaySensitiveMedia } from 'flavours/glitch/util/initial_state'; |
|
|
|
|
|
|
|
|
|
const messages = defineMessages({ |
|
|
|
|
play: { id: 'video.play', defaultMessage: 'Play' }, |
|
|
|
@ -97,6 +98,7 @@ export default class Video extends React.PureComponent { |
|
|
|
|
letterbox: PropTypes.bool, |
|
|
|
|
fullwidth: PropTypes.bool, |
|
|
|
|
detailed: PropTypes.bool, |
|
|
|
|
inline: PropTypes.bool, |
|
|
|
|
intl: PropTypes.object.isRequired, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -105,14 +107,21 @@ export default class Video extends React.PureComponent { |
|
|
|
|
duration: 0, |
|
|
|
|
paused: true, |
|
|
|
|
dragging: false, |
|
|
|
|
containerWidth: false, |
|
|
|
|
fullscreen: false, |
|
|
|
|
hovered: false, |
|
|
|
|
muted: false, |
|
|
|
|
revealed: !this.props.sensitive, |
|
|
|
|
revealed: !this.props.sensitive || displaySensitiveMedia, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
setPlayerRef = c => { |
|
|
|
|
this.player = c; |
|
|
|
|
|
|
|
|
|
if (c) { |
|
|
|
|
this.setState({ |
|
|
|
|
containerWidth: c.offsetWidth, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setVideoRef = c => { |
|
|
|
@ -246,12 +255,23 @@ export default class Video extends React.PureComponent { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
render () { |
|
|
|
|
const { preview, src, width, height, startTime, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed } = this.props; |
|
|
|
|
const { currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state; |
|
|
|
|
const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed } = this.props; |
|
|
|
|
const { containerWidth, currentTime, duration, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state; |
|
|
|
|
const progress = (currentTime / duration) * 100; |
|
|
|
|
const playerStyle = {}; |
|
|
|
|
|
|
|
|
|
let { width, height } = this.props; |
|
|
|
|
|
|
|
|
|
if (inline && containerWidth) { |
|
|
|
|
width = containerWidth; |
|
|
|
|
height = containerWidth / (16/9); |
|
|
|
|
|
|
|
|
|
playerStyle.width = width; |
|
|
|
|
playerStyle.height = height; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
<div className={classNames('video-player', { inactive: !revealed, detailed, inline: width && height && !fullscreen, fullscreen, letterbox, 'full-width': fullwidth })} style={{ width, height }} ref={this.setPlayerRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> |
|
|
|
|
<div className={classNames('video-player', { inactive: !revealed, detailed, inline: width && height && !fullscreen, fullscreen, letterbox, 'full-width': fullwidth })} style={playerStyle} ref={this.setPlayerRef} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> |
|
|
|
|
<video |
|
|
|
|
ref={this.setVideoRef} |
|
|
|
|
src={src} |
|
|
|
@ -271,7 +291,7 @@ export default class Video extends React.PureComponent { |
|
|
|
|
onProgress={this.handleProgress} |
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
<button className={classNames('video-player__spoiler', { active: !revealed })} onClick={this.toggleReveal}> |
|
|
|
|
<button type='button' className={classNames('video-player__spoiler', { active: !revealed })} onClick={this.toggleReveal}> |
|
|
|
|
<span className='video-player__spoiler__title'><FormattedMessage id='status.sensitive_warning' defaultMessage='Sensitive content' /></span> |
|
|
|
|
<span className='video-player__spoiler__subtitle'><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span> |
|
|
|
|
</button> |
|
|
|
@ -290,10 +310,10 @@ export default class Video extends React.PureComponent { |
|
|
|
|
|
|
|
|
|
<div className='video-player__buttons-bar'> |
|
|
|
|
<div className='video-player__buttons left'> |
|
|
|
|
<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 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> |
|
|
|
|
<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 aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><i className='fa fa-fw fa-eye' /></button>} |
|
|
|
|
{!onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><i className='fa fa-fw fa-eye' /></button>} |
|
|
|
|
|
|
|
|
|
{(detailed || fullscreen) && |
|
|
|
|
<span> |
|
|
|
@ -305,9 +325,9 @@ export default class Video extends React.PureComponent { |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div className='video-player__buttons right'> |
|
|
|
|
{(!fullscreen && onOpenVideo) && <button aria-label={intl.formatMessage(messages.expand)} onClick={this.handleOpenVideo}><i className='fa fa-fw fa-expand' /></button>} |
|
|
|
|
{onCloseVideo && <button aria-label={intl.formatMessage(messages.close)} onClick={this.handleCloseVideo}><i className='fa fa-fw fa-compress' /></button>} |
|
|
|
|
<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> |
|
|
|
|
{(!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> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|
</div> |
|
|
|
|