* Volume sliders for videos #7429 * Code formatting updates * Code formatting updates
This commit is contained in:
		
					parent
					
						
							
								b6681d21ad
							
						
					
				
			
			
				commit
				
					
						f978afa487
					
				
			
		
					 2 changed files with 122 additions and 5 deletions
				
			
		|  | @ -105,6 +105,7 @@ class Video extends React.PureComponent { | |||
|   state = { | ||||
|     currentTime: 0, | ||||
|     duration: 0, | ||||
|     volume: 0.5, | ||||
|     paused: true, | ||||
|     dragging: false, | ||||
|     containerWidth: false, | ||||
|  | @ -114,6 +115,15 @@ class Video extends React.PureComponent { | |||
|     revealed: displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all', | ||||
|   }; | ||||
| 
 | ||||
|   // 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; | ||||
| 
 | ||||
|  | @ -132,6 +142,10 @@ class Video extends React.PureComponent { | |||
|     this.seek = c; | ||||
|   } | ||||
| 
 | ||||
|   setVolumeRef = c => { | ||||
|     this.volume = c; | ||||
|   } | ||||
| 
 | ||||
|   handleClickRoot = e => e.stopPropagation(); | ||||
| 
 | ||||
|   handlePlay = () => { | ||||
|  | @ -149,6 +163,43 @@ 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); | ||||
|  | @ -273,8 +324,11 @@ class Video extends React.PureComponent { | |||
| 
 | ||||
|   render () { | ||||
|     const { preview, src, inline, startTime, onOpenVideo, onCloseVideo, intl, alt, 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 volumeWidth = (muted) ? 0 : volume * this.volWidth; | ||||
|     const volumeHandleLoc = (muted) ? this.volHandleOffset(0) : this.volHandleOffset(volume); | ||||
|     const playerStyle = {}; | ||||
| 
 | ||||
|     let { width, height } = this.props; | ||||
|  | @ -326,6 +380,7 @@ class Video extends React.PureComponent { | |||
|           title={alt} | ||||
|           width={width} | ||||
|           height={height} | ||||
|           volume={volume} | ||||
|           onClick={this.togglePlay} | ||||
|           onPlay={this.handlePlay} | ||||
|           onPause={this.handlePause} | ||||
|  | @ -354,9 +409,15 @@ 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> | ||||
|  | @ -368,6 +429,7 @@ 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> | ||||
|  |  | |||
|  | @ -4658,6 +4658,19 @@ a.status-card.compact:hover { | |||
|   z-index: 5; | ||||
| } | ||||
| 
 | ||||
| .detailed, | ||||
| .fullscreen { | ||||
|   .video-player__volume__current, | ||||
|   .video-player__volume::before { | ||||
|     bottom: 27px; | ||||
|   } | ||||
| 
 | ||||
|   .video-player__volume__handle { | ||||
|     bottom: 23px; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| .video-player { | ||||
|   overflow: hidden; | ||||
|   position: relative; | ||||
|  | @ -4806,7 +4819,7 @@ a.status-card.compact:hover { | |||
| 
 | ||||
|   &__time-current { | ||||
|     color: $white; | ||||
|     margin-left: 10px; | ||||
|     margin-left: 60px; | ||||
|   } | ||||
| 
 | ||||
|   &__time-sep { | ||||
|  | @ -4819,6 +4832,48 @@ a.status-card.compact:hover { | |||
|     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 { | ||||
|     cursor: pointer; | ||||
|     height: 24px; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue