@ -105,6 +105,7 @@ class Video extends PureComponent {
static propTypes = {
static propTypes = {
preview : PropTypes . string ,
preview : PropTypes . string ,
frameRate : PropTypes . string ,
frameRate : PropTypes . string ,
aspectRatio : PropTypes . string ,
src : PropTypes . string . isRequired ,
src : PropTypes . string . isRequired ,
alt : PropTypes . string ,
alt : PropTypes . string ,
lang : PropTypes . string ,
lang : PropTypes . string ,
@ -113,7 +114,6 @@ class Video extends PureComponent {
onOpenVideo : PropTypes . func ,
onOpenVideo : PropTypes . func ,
onCloseVideo : PropTypes . func ,
onCloseVideo : PropTypes . func ,
detailed : PropTypes . bool ,
detailed : PropTypes . bool ,
inline : PropTypes . bool ,
editable : PropTypes . bool ,
editable : PropTypes . bool ,
alwaysVisible : PropTypes . bool ,
alwaysVisible : PropTypes . bool ,
visible : PropTypes . bool ,
visible : PropTypes . bool ,
@ -500,14 +500,9 @@ class Video extends PureComponent {
}
}
render ( ) {
render ( ) {
const { preview , src , inline , onOpenVideo , onCloseVideo , intl , alt , lang , detailed , sensitive , editable , blurhash , autoFocus } = this . props ;
const { preview , src , aspectRatio , onOpenVideo , onCloseVideo , intl , alt , lang , detailed , sensitive , editable , blurhash , autoFocus } = this . props ;
const { currentTime , duration , volume , buffer , dragging , paused , fullscreen , hovered , muted , revealed } = this . state ;
const { currentTime , duration , volume , buffer , dragging , paused , fullscreen , hovered , muted , revealed } = this . state ;
const progress = Math . min ( ( currentTime / duration ) * 100 , 100 ) ;
const progress = Math . min ( ( currentTime / duration ) * 100 , 100 ) ;
const playerStyle = { } ;
if ( inline ) {
playerStyle . aspectRatio = '16 / 9' ;
}
let preload ;
let preload ;
@ -527,95 +522,101 @@ class Video extends PureComponent {
warning = < FormattedMessage id = 'status.media_hidden' defaultMessage = 'Media hidden' / > ;
warning = < FormattedMessage id = 'status.media_hidden' defaultMessage = 'Media hidden' / > ;
}
}
/ / T h e o u t e r w r a p p e r i s n e c e s s a r y t o a v o i d r e f l o w i n g t h e l a y o u t w h e n g o i n g i n t o f u l l s c r e e n
return (
return (
< div
< div style = { { aspectRatio } } >
role = 'menuitem'
< div
className = { classNames ( 'video-player' , { inactive : ! revealed , detailed , inline : inline && ! fullscreen , fullscreen , editable } ) }
role = 'menuitem'
style = { playerStyle }
className = { classNames ( 'video-player' , { inactive : ! revealed , detailed , fullscreen , editable } ) }
ref = { this . setPlayerRef }
style = { { aspectRatio } }
onMouseEnter = { this . handleMouseEnter }
ref = { this . setPlayerRef }
onMouseLeave = { this . handleMouseLeave }
onMouseEnter = { this . handleMouseEnter }
onClick = { this . handleClickRoot }
onMouseLeave = { this . handleMouseLeave }
onKeyDown = { this . handleKeyDown }
onClick = { this . handleClickRoot }
tabIndex = { 0 }
onKeyDown = { this . handleKeyDown }
>
< Blurhash
hash = { blurhash }
className = { classNames ( 'media-gallery__preview' , {
'media-gallery__preview--hidden' : revealed ,
} ) }
dummy = { ! useBlurhash }
/ >
{ ( revealed || editable ) && < video
ref = { this . setVideoRef }
src = { src }
poster = { preview }
preload = { preload }
role = 'button'
tabIndex = { 0 }
tabIndex = { 0 }
aria - label = { alt }
>
title = { alt }
< Blurhash
lang = { lang }
hash = { blurhash }
volume = { volume }
className = { classNames ( 'media-gallery__preview' , {
onClick = { this . togglePlay }
'media-gallery__preview--hidden' : revealed ,
onKeyDown = { this . handleVideoKeyDown }
} ) }
onPlay = { this . handlePlay }
dummy = { ! useBlurhash }
onPause = { this . handlePause }
/ >
onLoadedData = { this . handleLoadedData }
onProgress = { this . handleProgress }
{ ( revealed || editable ) && < video
onVolumeChange = { this . handleVolumeChange }
ref = { this . setVideoRef }
style = { { ... playerStyle , width : '100%' } }
src = { src }
/ > }
poster = { preview }
preload = { preload }
< div className = { classNames ( 'spoiler-button' , { 'spoiler-button--hidden' : revealed || editable } ) } >
role = 'button'
< button type = 'button' className = 'spoiler-button__overlay' onClick = { this . toggleReveal } >
tabIndex = { 0 }
< span className = 'spoiler-button__overlay__label' > { warning } < / span >
aria - label = { alt }
< / button >
title = { alt }
< / div >
lang = { lang }
volume = { volume }
< div className = { classNames ( 'video-player__controls' , { active : paused || hovered } ) } >
onClick = { this . togglePlay }
< div className = 'video-player__seek' onMouseDown = { this . handleMouseDown } ref = { this . setSeekRef } >
onKeyDown = { this . handleVideoKeyDown }
< div className = 'video-player__seek__buffer' style = { { width : ` ${ buffer } % ` } } / >
onPlay = { this . handlePlay }
< div className = 'video-player__seek__progress' style = { { width : ` ${ progress } % ` } } / >
onPause = { this . handlePause }
onLoadedData = { this . handleLoadedData }
< span
onProgress = { this . handleProgress }
className = { classNames ( 'video-player__seek__handle' , { active : dragging } ) }
onVolumeChange = { this . handleVolumeChange }
tabIndex = { 0 }
style = { { width : '100%' } }
style = { { left : ` ${ progress } % ` } }
/ > }
onKeyDown = { this . handleVideoKeyDown }
/ >
< div className = { classNames ( 'spoiler-button' , { 'spoiler-button--hidden' : revealed || editable } ) } >
< button type = 'button' className = 'spoiler-button__overlay' onClick = { this . toggleReveal } >
< span className = 'spoiler-button__overlay__label' >
{ warning }
< span className = 'spoiler-button__overlay__action' > < FormattedMessage id = 'status.media.show' defaultMessage = 'Click to show' / > < / span >
< / span >
< / button >
< / div >
< / div >
< div className = 'video-player__buttons-bar' >
< div className = { classNames ( 'video-player__controls' , { active : paused || hovered } ) } >
< div className = 'video-player__buttons left' >
< div className = 'video-player__seek' onMouseDown = { this . handleMouseDown } ref = { this . setSeekRef } >
< button type = 'button' title = { intl . formatMessage ( paused ? messages . play : messages . pause ) } aria - label = { intl . formatMessage ( paused ? messages . play : messages . pause ) } className = 'player-button' onClick = { this . togglePlay } autoFocus = { autoFocus } > < Icon id = { paused ? 'play' : 'pause' } fixedWidth / > < / button >
< div className = 'video-player__seek__buffer' style = { { width : ` ${ buffer } % ` } } / >
< button type = 'button' title = { intl . formatMessage ( muted ? messages . unmute : messages . mute ) } aria - label = { intl . formatMessage ( muted ? messages . unmute : messages . mute ) } className = 'player-button' onClick = { this . toggleMute } > < Icon id = { muted ? 'volume-off' : 'volume-up' } fixedWidth / > < / button >
< div className = 'video-player__seek__progress' style = { { width : ` ${ progress } % ` } } / >
< div className = { classNames ( 'video-player__volume' , { active : this . state . hovered } ) } onMouseDown = { this . handleVolumeMouseDown } ref = { this . setVolumeRef } >
< span
< div className = 'video-player__volume__current' style = { { width : ` ${ volume * 100 } % ` } } / >
className = { classNames ( 'video-player__seek__handle' , { active : dragging } ) }
tabIndex = { 0 }
style = { { left : ` ${ progress } % ` } }
onKeyDown = { this . handleVideoKeyDown }
/ >
< / div >
< span
< div className = 'video-player__buttons-bar' >
className = { classNames ( 'video-player__volume__handle' ) }
< div className = 'video-player__buttons left' >
tabIndex = { 0 }
< button type = 'button' title = { intl . formatMessage ( paused ? messages . play : messages . pause ) } aria - label = { intl . formatMessage ( paused ? messages . play : messages . pause ) } className = 'player-button' onClick = { this . togglePlay } autoFocus = { autoFocus } > < Icon id = { paused ? 'play' : 'pause' } fixedWidth / > < / button >
style = { { left : ` ${ volume * 100 } % ` } }
< button type = 'button' title = { intl . formatMessage ( muted ? messages . unmute : messages . mute ) } aria - label = { intl . formatMessage ( muted ? messages . unmute : messages . mute ) } className = 'player-button' onClick = { this . toggleMute } > < Icon id = { muted ? 'volume-off' : 'volume-up' } fixedWidth / > < / button >
/ >
< div className = { classNames ( 'video-player__volume' , { active : this . state . hovered } ) } onMouseDown = { this . handleVolumeMouseDown } ref = { this . setVolumeRef } >
< div className = 'video-player__volume__current' style = { { width : ` ${ volume * 100 } % ` } } / >
< span
className = { classNames ( 'video-player__volume__handle' ) }
tabIndex = { 0 }
style = { { left : ` ${ volume * 100 } % ` } }
/ >
< / div >
{ ( detailed || fullscreen ) && (
< span className = 'video-player__time' >
< span className = 'video-player__time-current' > { formatTime ( Math . floor ( currentTime ) ) } < / span >
< span className = 'video-player__time-sep' > / < / span >
< span className = 'video-player__time-total' > { formatTime ( Math . floor ( duration ) ) } < / span >
< / span >
) }
< / div >
< / div >
{ ( detailed || fullscreen ) && (
< div className = 'video-player__buttons right' >
< span className = 'video-player__time' >
{ ( ! onCloseVideo && ! editable && ! fullscreen && ! this . props . alwaysVisible ) && < button type = 'button' title = { intl . formatMessage ( messages . hide ) } aria - label = { intl . formatMessage ( messages . hide ) } className = 'player-button' onClick = { this . toggleReveal } > < Icon id = 'eye-slash' fixedWidth / > < / button > }
< span className = 'video-player__time-current' > { formatTime ( Math . floor ( currentTime ) ) } < / span >
{ ( ! fullscreen && onOpenVideo ) && < button type = 'button' title = { intl . formatMessage ( messages . expand ) } aria - label = { intl . formatMessage ( messages . expand ) } className = 'player-button' onClick = { this . handleOpenVideo } > < Icon id = 'expand' fixedWidth / > < / button > }
< span className = 'video-player__time-sep' > / < / span >
{ onCloseVideo && < button type = 'button' title = { intl . formatMessage ( messages . close ) } aria - label = { intl . formatMessage ( messages . close ) } className = 'player-button' onClick = { this . handleCloseVideo } > < Icon id = 'compress' fixedWidth / > < / button > }
< span className = 'video-player__time-total' > { formatTime ( Math . floor ( duration ) ) } < / span >
< button type = 'button' title = { intl . formatMessage ( fullscreen ? messages . exit _fullscreen : messages . fullscreen ) } aria - label = { intl . formatMessage ( fullscreen ? messages . exit _fullscreen : messages . fullscreen ) } className = 'player-button' onClick = { this . toggleFullscreen } > < Icon id = { fullscreen ? 'compress' : 'arrows-alt' } fixedWidth / > < / button >
< / span >
< / div >
) }
< / div >
< div className = 'video-player__buttons right' >
{ ( ! onCloseVideo && ! editable && ! fullscreen && ! this . props . alwaysVisible ) && < button type = 'button' title = { intl . formatMessage ( messages . hide ) } aria - label = { intl . formatMessage ( messages . hide ) } className = 'player-button' onClick = { this . toggleReveal } > < Icon id = 'eye-slash' fixedWidth / > < / button > }
{ ( ! fullscreen && onOpenVideo ) && < button type = 'button' title = { intl . formatMessage ( messages . expand ) } aria - label = { intl . formatMessage ( messages . expand ) } className = 'player-button' onClick = { this . handleOpenVideo } > < Icon id = 'expand' fixedWidth / > < / button > }
{ onCloseVideo && < button type = 'button' title = { intl . formatMessage ( messages . close ) } aria - label = { intl . formatMessage ( messages . close ) } className = 'player-button' onClick = { this . handleCloseVideo } > < Icon id = 'compress' fixedWidth / > < / button > }
< button type = 'button' title = { intl . formatMessage ( fullscreen ? messages . exit _fullscreen : messages . fullscreen ) } aria - label = { intl . formatMessage ( fullscreen ? messages . exit _fullscreen : messages . fullscreen ) } className = 'player-button' onClick = { this . toggleFullscreen } > < Icon id = { fullscreen ? 'compress' : 'arrows-alt' } fixedWidth / > < / button >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >