summaryrefslogtreecommitdiff
path: root/animism-align/frontend
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-09-23 16:08:26 +0200
committerJules Laplace <julescarbon@gmail.com>2020-09-23 16:08:26 +0200
commit9f707dfa8c0b2d38d4d81c1cf0df38df494a49b2 (patch)
tree2c8af745d62fcfd7002bc66939b31b408bc85c3c /animism-align/frontend
parent41052dd5b95cf2813662d8201b206ad2af78da40 (diff)
new video UI
Diffstat (limited to 'animism-align/frontend')
-rw-r--r--animism-align/frontend/app/views/viewer/nav/nav.css4
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js64
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/index.js2
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/media.css51
-rw-r--r--animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js82
-rw-r--r--animism-align/frontend/app/views/viewer/player/player.fullscreen.css1
6 files changed, 136 insertions, 68 deletions
diff --git a/animism-align/frontend/app/views/viewer/nav/nav.css b/animism-align/frontend/app/views/viewer/nav/nav.css
index daa90e1..a5c19d0 100644
--- a/animism-align/frontend/app/views/viewer/nav/nav.css
+++ b/animism-align/frontend/app/views/viewer/nav/nav.css
@@ -197,13 +197,11 @@
stroke: #000;
stroke-width: 0.5;
}
-.fullscreen-element.video .volume path,
.viewer-nav.hovering-nav .volume path,
.viewer-nav.black .volume path,
.nav-open .volume path {
fill: #fff;
}
-.fullscreen-element.video .volume.muted path,
.viewer-nav.hovering-nav .volume.muted path,
.viewer-nav.black .volume.muted path,
.nav-open .volume.muted path {
@@ -222,8 +220,6 @@
.playToggle polygon {
fill: #000;
}
-.fullscreen-element.video .playToggle path,
-.fullscreen-element.video .playToggle polygon,
.viewer-nav.hovering-nav .playToggle path,
.viewer-nav.hovering-nav .playToggle polygon,
.viewer-nav.black .playToggle path,
diff --git a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js
index a196ee5..929daef 100644
--- a/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js
+++ b/animism-align/frontend/app/views/viewer/player/components.fullscreen/fullscreen.video.js
@@ -3,7 +3,7 @@ import { connect } from 'react-redux'
import VimeoPlayer from 'app/utils/vendor/vimeo'
import actions from 'app/actions'
-import { PlayButton, PlayerTime, VolumeControl } from 'app/views/viewer/nav/viewer.icons'
+import { VideoScrubber } from '../components.media'
class FullscreenVideo extends Component {
state = {
@@ -15,24 +15,10 @@ class FullscreenVideo extends Component {
}
constructor(props) {
super(props)
- this.scrubberRef = React.createRef()
this.handlePlay = this.handlePlay.bind(this)
this.handlePause = this.handlePause.bind(this)
this.handleTimeUpdate = this.handleTimeUpdate.bind(this)
this.handleEnd = this.handleEnd.bind(this)
- this.handleScrubBarClick = this.handleScrubBarClick.bind(this)
- 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)
- this.setState({ scrubbing: false })
}
componentDidUpdate(prevProps) {
if (Math.abs(this.props.play_ts - prevProps.play_ts) > 2.0) {
@@ -51,31 +37,13 @@ class FullscreenVideo extends Component {
}
handleTimeUpdate(timing) {
- this.setState(timing)
- }
- handleScrubBarClick(e) {
- e.stopPropagation()
- const bounds = this.scrubberRef.current.getBoundingClientRect()
- const percent = (e.pageX - bounds.left) / bounds.width
- const seconds = percent * this.state.duration
- actions.audio.seek(this.props.element.start_ts + seconds)
- this.setState({ percent, seconds })
- // actions.audio.seek(clamp(play_ts - 5.0, start_ts, end_ts))
- }
- handleScrubDotMouseDown(e) {
- e.stopPropagation()
- this.setState({ scrubbing: true })
- }
- handleScrubDotMouseMove(e) {
- e.stopPropagation()
- if (!this.state.scrubbing) return
- }
- handleScrubDotMouseUp(e) {
- e.stopPropagation()
- this.setState({ scrubbing: false })
+ if (!this.state.scrubbing || ('scrubbing' in timing)) {
+ this.setState(timing)
+ }
}
+
render() {
- const { element, media, transitionDuration, playing, volume } = this.props
+ const { element, media, transitionDuration, playing } = this.props
const { duration, percent, seconds } = this.state
const { color } = element
const item = media.lookup[element.settings.media_id]
@@ -84,7 +52,6 @@ class FullscreenVideo extends Component {
color: color.textColor,
transitionDuration,
}
- // console.log(item)
return (
<div
className='fullscreen-element video'
@@ -106,18 +73,12 @@ class FullscreenVideo extends Component {
onEnd={this.handleEnd}
/>
</div>
- <div
- className='video-scrubber'
- onClick={this.handleScrubBarClick}
- ref={this.scrubberRef}
- >
- <div className='scrub-bar' />
- <div
- className='scrub-dot'
- style={{ left: (100 * this.state.percent) + "%" }}
- onMouseDown={this.handleScrubDotMouseDown}
- />
- </div>
+ <VideoScrubber
+ start_ts={element.start_ts}
+ playing={playing}
+ timing={this.state}
+ onScrub={this.handleTimeUpdate}
+ />
</div>
)
}
@@ -127,7 +88,6 @@ const mapStateToProps = state => ({
viewer: state.viewer,
play_ts: state.audio.play_ts,
playing: state.audio.playing,
- volume: state.audio.volume,
})
export default connect(mapStateToProps)(FullscreenVideo)
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/index.js b/animism-align/frontend/app/views/viewer/player/components.media/index.js
index 37f6f64..04b7f03 100644
--- a/animism-align/frontend/app/views/viewer/player/components.media/index.js
+++ b/animism-align/frontend/app/views/viewer/player/components.media/index.js
@@ -13,6 +13,7 @@ import {
} from './media.gallery'
import Carousel from './media.carousel'
+import VideoScrubber from './video.scrubber'
import {
Grid
@@ -24,4 +25,5 @@ export {
Gallery,
Carousel,
Grid,
+ VideoScrubber,
} \ No newline at end of file
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/media.css b/animism-align/frontend/app/views/viewer/player/components.media/media.css
index 32d35d0..653a53b 100644
--- a/animism-align/frontend/app/views/viewer/player/components.media/media.css
+++ b/animism-align/frontend/app/views/viewer/player/components.media/media.css
@@ -302,29 +302,56 @@
.video-scrubber {
position: absolute;
- bottom: 5rem;
- left: 50%;
- width: 300px;
- height: 16px;
- margin-left: -150px;
+ bottom: 4rem;
+ left: 1rem;
+ width: calc(100% - 2rem);
+ height: 3rem;
+ background: white;
+ border-radius: 1.5rem;
+ display: flex;
+ align-items: center;
+}
+.video-scrubber .start-controls {
+ width: 3rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+.video-scrubber .scrub-bar-container {
+ flex: 1;
+ height: 3rem;
+ display: flex;
+ align-items: center;
+ position: relative;
cursor: pointer;
}
.video-scrubber .scrub-bar {
- position: absolute;
- top: 7px;
- left: 0;
+ position: relative;
width: 100%;
height: 2px;
- background: white;
+ margin-top: 1px;
+ background: black;
}
.video-scrubber .scrub-dot {
position: absolute;
- top: 0;
+ top: 50%;
left: 0;
width: 16px;
height: 16px;
+ margin-top: -7px;
margin-left: -8px;
border-radius: 50%;
- background: white;
- cursor: pointer;
+ background: black;
+ pointer-events: none;
+}
+.video-scrubber .end-controls {
+ width: 7rem;
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ color: black;
}
+.video-scrubber .playerTime {
+ display: flex;
+ align-items: center;
+} \ No newline at end of file
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)
diff --git a/animism-align/frontend/app/views/viewer/player/player.fullscreen.css b/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
index 36e4a76..c9a1e48 100644
--- a/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
+++ b/animism-align/frontend/app/views/viewer/player/player.fullscreen.css
@@ -59,6 +59,7 @@
.viewer-fullscreen .video {
position: relative;
align-items: flex-start;
+ user-select: none;
}
iframe {