[Glitch] Add hotkeys for audio/video control
Port 04a079e723 to glitch-soc
Signed-off-by: Thibaut Girka <thib@sitedethib.com>
			
			
This commit is contained in:
		
				
					committed by
					
						
						Thibaut Girka
					
				
			
			
				
	
			
			
			
						parent
						
							48f0f3ffee
						
					
				
				
					commit
					b82aa33dea
				
			@@ -392,13 +392,59 @@ class Audio extends React.PureComponent {
 | 
			
		||||
    return this.props.foregroundColor || '#ffffff';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  seekBy (time) {
 | 
			
		||||
    const currentTime = this.audio.currentTime + time;
 | 
			
		||||
 | 
			
		||||
    if (!isNaN(currentTime)) {
 | 
			
		||||
      this.setState({ currentTime }, () => {
 | 
			
		||||
        this.audio.currentTime = currentTime;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleAudioKeyDown = e => {
 | 
			
		||||
    // On the audio element or the seek bar, we can safely use the space bar
 | 
			
		||||
    // for playback control because there are no buttons to press
 | 
			
		||||
 | 
			
		||||
    if (e.key === ' ') {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.togglePlay();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleKeyDown = e => {
 | 
			
		||||
    switch(e.key) {
 | 
			
		||||
    case 'k':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.togglePlay();
 | 
			
		||||
      break;
 | 
			
		||||
    case 'm':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.toggleMute();
 | 
			
		||||
      break;
 | 
			
		||||
    case 'j':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.seekBy(-10);
 | 
			
		||||
      break;
 | 
			
		||||
    case 'l':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.seekBy(10);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { src, intl, alt, editable, autoPlay } = this.props;
 | 
			
		||||
    const { paused, muted, volume, currentTime, duration, buffer, dragging } = this.state;
 | 
			
		||||
    const progress = Math.min((currentTime / duration) * 100, 100);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className={classNames('audio-player', { editable })} ref={this.setPlayerRef} style={{ backgroundColor: this._getBackgroundColor(), color: this._getForegroundColor(), width: '100%', height: this.props.fullscreen ? '100%' : (this.state.height || this.props.height) }} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
 | 
			
		||||
      <div className={classNames('audio-player', { editable })} ref={this.setPlayerRef} style={{ backgroundColor: this._getBackgroundColor(), color: this._getForegroundColor(), width: '100%', height: this.props.fullscreen ? '100%' : (this.state.height || this.props.height) }} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} tabIndex='0' onKeyDown={this.handleKeyDown}>
 | 
			
		||||
        <audio
 | 
			
		||||
          src={src}
 | 
			
		||||
          ref={this.setAudioRef}
 | 
			
		||||
@@ -412,12 +458,14 @@ class Audio extends React.PureComponent {
 | 
			
		||||
 | 
			
		||||
        <canvas
 | 
			
		||||
          role='button'
 | 
			
		||||
          tabIndex='0'
 | 
			
		||||
          className='audio-player__canvas'
 | 
			
		||||
          width={this.state.width}
 | 
			
		||||
          height={this.state.height}
 | 
			
		||||
          style={{ width: '100%', position: 'absolute', top: 0, left: 0 }}
 | 
			
		||||
          ref={this.setCanvasRef}
 | 
			
		||||
          onClick={this.togglePlay}
 | 
			
		||||
          onKeyDown={this.handleAudioKeyDown}
 | 
			
		||||
          title={alt}
 | 
			
		||||
          aria-label={alt}
 | 
			
		||||
        />
 | 
			
		||||
@@ -438,6 +486,7 @@ class Audio extends React.PureComponent {
 | 
			
		||||
            className={classNames('video-player__seek__handle', { active: dragging })}
 | 
			
		||||
            tabIndex='0'
 | 
			
		||||
            style={{ left: `${progress}%`, backgroundColor: this._getAccentColor() }}
 | 
			
		||||
            onKeyDown={this.handleAudioKeyDown}
 | 
			
		||||
          />
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -279,6 +279,81 @@ class Video extends React.PureComponent {
 | 
			
		||||
    }
 | 
			
		||||
  }, 15);
 | 
			
		||||
 | 
			
		||||
  seekBy (time) {
 | 
			
		||||
    const currentTime = this.video.currentTime + time;
 | 
			
		||||
 | 
			
		||||
    if (!isNaN(currentTime)) {
 | 
			
		||||
      this.setState({ currentTime }, () => {
 | 
			
		||||
        this.video.currentTime = currentTime;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleVideoKeyDown = e => {
 | 
			
		||||
    // On the video element or the seek bar, we can safely use the space bar
 | 
			
		||||
    // for playback control because there are no buttons to press
 | 
			
		||||
 | 
			
		||||
    if (e.key === ' ') {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.togglePlay();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleKeyDown = e => {
 | 
			
		||||
    const frameTime = 1 / 25;
 | 
			
		||||
 | 
			
		||||
    switch(e.key) {
 | 
			
		||||
    case 'k':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.togglePlay();
 | 
			
		||||
      break;
 | 
			
		||||
    case 'm':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.toggleMute();
 | 
			
		||||
      break;
 | 
			
		||||
    case 'f':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.toggleFullscreen();
 | 
			
		||||
      break;
 | 
			
		||||
    case 'j':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.seekBy(-10);
 | 
			
		||||
      break;
 | 
			
		||||
    case 'l':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.seekBy(10);
 | 
			
		||||
      break;
 | 
			
		||||
    case ',':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.seekBy(-frameTime);
 | 
			
		||||
      break;
 | 
			
		||||
    case '.':
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      this.seekBy(frameTime);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we are in fullscreen mode, we don't want any hotkeys
 | 
			
		||||
    // interacting with the UI that's not visible
 | 
			
		||||
 | 
			
		||||
    if (this.state.fullscreen) {
 | 
			
		||||
      e.preventDefault();
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
 | 
			
		||||
      if (e.key === 'Escape') {
 | 
			
		||||
        exitFullscreen();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  togglePlay = () => {
 | 
			
		||||
    if (this.state.paused) {
 | 
			
		||||
      this.setState({ paused: false }, () => this.video.play());
 | 
			
		||||
@@ -504,6 +579,7 @@ class Video extends React.PureComponent {
 | 
			
		||||
        onMouseEnter={this.handleMouseEnter}
 | 
			
		||||
        onMouseLeave={this.handleMouseLeave}
 | 
			
		||||
        onMouseDown={this.handleMouseDownRoot}
 | 
			
		||||
        onKeyDown={this.handleKeyDown}
 | 
			
		||||
        tabIndex={0}
 | 
			
		||||
      >
 | 
			
		||||
        <Blurhash
 | 
			
		||||
@@ -528,6 +604,7 @@ class Video extends React.PureComponent {
 | 
			
		||||
          height={height}
 | 
			
		||||
          volume={volume}
 | 
			
		||||
          onClick={this.togglePlay}
 | 
			
		||||
          onKeyDown={this.handleVideoKeyDown}
 | 
			
		||||
          onPlay={this.handlePlay}
 | 
			
		||||
          onPause={this.handlePause}
 | 
			
		||||
          onLoadedData={this.handleLoadedData}
 | 
			
		||||
@@ -550,6 +627,7 @@ class Video extends React.PureComponent {
 | 
			
		||||
              className={classNames('video-player__seek__handle', { active: dragging })}
 | 
			
		||||
              tabIndex='0'
 | 
			
		||||
              style={{ left: `${progress}%` }}
 | 
			
		||||
              onKeyDown={this.handleVideoKeyDown}
 | 
			
		||||
            />
 | 
			
		||||
          </div>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user