@@ -108,6 +108,7 @@ export default class Video extends React.PureComponent {
 | 
				
			|||||||
  state = {
 | 
					  state = {
 | 
				
			||||||
    currentTime: 0,
 | 
					    currentTime: 0,
 | 
				
			||||||
    duration: 0,
 | 
					    duration: 0,
 | 
				
			||||||
 | 
					    volume: 0.5,
 | 
				
			||||||
    paused: true,
 | 
					    paused: true,
 | 
				
			||||||
    dragging: false,
 | 
					    dragging: false,
 | 
				
			||||||
    containerWidth: 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,
 | 
					    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 => {
 | 
					  setPlayerRef = c => {
 | 
				
			||||||
    this.player = c;
 | 
					    this.player = c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -135,6 +145,10 @@ export default class Video extends React.PureComponent {
 | 
				
			|||||||
    this.seek = c;
 | 
					    this.seek = c;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setVolumeRef = c => {
 | 
				
			||||||
 | 
					    this.volume = c;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  handleMouseDownRoot = e => {
 | 
					  handleMouseDownRoot = e => {
 | 
				
			||||||
    e.preventDefault();
 | 
					    e.preventDefault();
 | 
				
			||||||
    e.stopPropagation();
 | 
					    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 => {
 | 
					  handleMouseDown = e => {
 | 
				
			||||||
    document.addEventListener('mousemove', this.handleMouseMove, true);
 | 
					    document.addEventListener('mousemove', this.handleMouseMove, true);
 | 
				
			||||||
    document.addEventListener('mouseup', this.handleMouseUp, true);
 | 
					    document.addEventListener('mouseup', this.handleMouseUp, true);
 | 
				
			||||||
@@ -290,10 +341,13 @@ export default class Video extends React.PureComponent {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
    const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed, sensitive } = this.props;
 | 
					    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 progress = (currentTime / duration) * 100;
 | 
				
			||||||
    const playerStyle = {};
 | 
					    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 });
 | 
					    const computedClass = classNames('video-player', { inactive: !revealed, detailed, inline: inline && !fullscreen, fullscreen, letterbox, 'full-width': fullwidth });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let { width, height } = this.props;
 | 
					    let { width, height } = this.props;
 | 
				
			||||||
@@ -346,6 +400,7 @@ export default class Video extends React.PureComponent {
 | 
				
			|||||||
          title={alt}
 | 
					          title={alt}
 | 
				
			||||||
          width={width}
 | 
					          width={width}
 | 
				
			||||||
          height={height}
 | 
					          height={height}
 | 
				
			||||||
 | 
					          volume={volume}
 | 
				
			||||||
          onClick={this.togglePlay}
 | 
					          onClick={this.togglePlay}
 | 
				
			||||||
          onPlay={this.handlePlay}
 | 
					          onPlay={this.handlePlay}
 | 
				
			||||||
          onPause={this.handlePause}
 | 
					          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-bar'>
 | 
				
			||||||
            <div className='video-player__buttons left'>
 | 
					            <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(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>
 | 
					              <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}>
 | 
				
			||||||
              {!onCloseVideo && <button type='button' aria-label={intl.formatMessage(messages.hide)} onClick={this.toggleReveal}><i className='fa fa-fw fa-eye' /></button>}
 | 
					                <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) &&
 | 
					              {(detailed || fullscreen) &&
 | 
				
			||||||
                <span>
 | 
					                <span>
 | 
				
			||||||
@@ -388,6 +449,7 @@ export default class Video extends React.PureComponent {
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div className='video-player__buttons right'>
 | 
					            <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>}
 | 
					              {(!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>}
 | 
					              {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>
 | 
					              <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>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -277,6 +277,19 @@
 | 
				
			|||||||
  z-index: 100;
 | 
					  z-index: 100;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.detailed,
 | 
				
			||||||
 | 
					.fullscreen {
 | 
				
			||||||
 | 
					  .video-player__volume__current,
 | 
				
			||||||
 | 
					  .video-player__volume::before {
 | 
				
			||||||
 | 
					    bottom: 27px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .video-player__volume__handle {
 | 
				
			||||||
 | 
					    bottom: 23px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.video-player {
 | 
					.video-player {
 | 
				
			||||||
  overflow: hidden;
 | 
					  overflow: hidden;
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
@@ -432,7 +445,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  &__time-current {
 | 
					  &__time-current {
 | 
				
			||||||
    color: $white;
 | 
					    color: $white;
 | 
				
			||||||
    margin-left: 10px;
 | 
					    margin-left: 60px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &__time-sep {
 | 
					  &__time-sep {
 | 
				
			||||||
@@ -445,6 +458,48 @@
 | 
				
			|||||||
    color: $white;
 | 
					    color: $white;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &__volume {
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    height: 24px;
 | 
				
			||||||
 | 
					    display: inline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &::before {
 | 
				
			||||||
 | 
					      content: "";
 | 
				
			||||||
 | 
					      width: 50px;
 | 
				
			||||||
 | 
					      background: rgba($white, 0.35);
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					      position: absolute;
 | 
				
			||||||
 | 
					      height: 4px;
 | 
				
			||||||
 | 
					      left: 70px;
 | 
				
			||||||
 | 
					      bottom: 20px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &__current {
 | 
				
			||||||
 | 
					      display: block;
 | 
				
			||||||
 | 
					      position: absolute;
 | 
				
			||||||
 | 
					      height: 4px;
 | 
				
			||||||
 | 
					      border-radius: 4px;
 | 
				
			||||||
 | 
					      left: 70px;
 | 
				
			||||||
 | 
					      bottom: 20px;
 | 
				
			||||||
 | 
					      background: lighten($ui-highlight-color, 8%);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &__handle {
 | 
				
			||||||
 | 
					      position: absolute;
 | 
				
			||||||
 | 
					      z-index: 3;
 | 
				
			||||||
 | 
					      border-radius: 50%;
 | 
				
			||||||
 | 
					      width: 12px;
 | 
				
			||||||
 | 
					      height: 12px;
 | 
				
			||||||
 | 
					      bottom: 16px;
 | 
				
			||||||
 | 
					      left: 70px;
 | 
				
			||||||
 | 
					      transition: opacity .1s ease;
 | 
				
			||||||
 | 
					      background: lighten($ui-highlight-color, 8%);
 | 
				
			||||||
 | 
					      box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
 | 
				
			||||||
 | 
					      pointer-events: none;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &__seek {
 | 
					  &__seek {
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
    height: 24px;
 | 
					    height: 24px;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user