summaryrefslogtreecommitdiff
path: root/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js
diff options
context:
space:
mode:
Diffstat (limited to 'animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js')
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js
new file mode 100644
index 0000000..7bbbc07
--- /dev/null
+++ b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js
@@ -0,0 +1,82 @@
+import React, { Component } from 'react'
+import { connect } from 'react-redux'
+
+import actions from 'app/actions'
+import { clamp, timestamp } from 'app/utils'
+import { PlayButton, VolumeControl } from 'app/views/viewer/nav/viewer.icons'
+
+class VideoScrubber extends Component {
+ constructor(props) {
+ super(props)
+ this.scrubberRef = React.createRef()
+ this.handleScrubDotMouseDown = this.handleScrubDotMouseDown.bind(this)
+ this.handleScrubDotMouseMove = this.handleScrubDotMouseMove.bind(this)
+ this.handleScrubDotMouseUp = this.handleScrubDotMouseUp.bind(this)
+ }
+ componentDidMount() {
+ window.addEventListener('mousemove', this.handleScrubDotMouseMove)
+ window.addEventListener('mouseup', this.handleScrubDotMouseUp)
+ }
+ componentWillUnmount() {
+ window.removeEventListener('mousemove', this.handleScrubDotMouseMove)
+ window.removeEventListener('mouseup', this.handleScrubDotMouseUp)
+ }
+ scrub(x, scrubbing) {
+ const { timing, start_ts, onScrub } = this.props
+ const bounds = this.scrubberRef.current.getBoundingClientRect()
+ const percent = clamp((x - bounds.left) / bounds.width, 0, 1)
+ const seconds = percent * timing.duration
+ actions.audio.seek(start_ts + seconds)
+ onScrub({
+ seek: seconds,
+ percent, seconds, scrubbing
+ })
+ }
+ handleScrubDotMouseDown(e) {
+ e.stopPropagation()
+ this.scrub(e.pageX, true)
+ }
+ handleScrubDotMouseMove(e) {
+ e.stopPropagation()
+ if (!this.props.timing.scrubbing) return
+ this.scrub(e.pageX, true)
+ }
+ handleScrubDotMouseUp(e) {
+ e.stopPropagation()
+ this.props.onScrub({ scrubbing: false })
+ }
+ render() {
+ const { playing, volume, timing } = this.props
+ return (
+ <div className='video-scrubber'>
+ <div className='start-controls'>
+ <PlayButton playing={playing} />
+ </div>
+ <div
+ className='scrub-bar-container'
+ onMouseDown={this.handleScrubDotMouseDown}
+ ref={this.scrubberRef}
+ >
+ <div className='scrub-bar' />
+ <div
+ className='scrub-dot'
+ style={{ left: (100 * timing.percent) + "%" }}
+ />
+ </div>
+ <div className='end-controls'>
+ <div className='playerTime'>
+ {timestamp(clamp(timing.seconds, 0, timing.duration))}
+ </div>
+ <VolumeControl volume={volume} />
+ </div>
+ </div>
+ )
+ }
+}
+
+const mapStateToProps = state => ({
+ playing: state.audio.playing,
+ volume: state.audio.volume,
+})
+
+export default connect(mapStateToProps)(VideoScrubber)