Basic placeholder UI for scrubbing preview
This commit is contained in:
@@ -158,6 +158,18 @@ module.exports = class PlaybackController {
|
|||||||
else this.state.playing.jumpToTime = time
|
else this.state.playing.jumpToTime = time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preview (time, x) {
|
||||||
|
if (!Number.isFinite(time)) {
|
||||||
|
console.error('Tried to skip to a non-finite time ' + time)
|
||||||
|
return console.trace()
|
||||||
|
}
|
||||||
|
this.state.playing.preview = { time, x }
|
||||||
|
}
|
||||||
|
|
||||||
|
clearPreview () {
|
||||||
|
this.state.playing.preview = null
|
||||||
|
}
|
||||||
|
|
||||||
// Change playback speed. 1 = faster, -1 = slower
|
// Change playback speed. 1 = faster, -1 = slower
|
||||||
// Playback speed ranges from 16 (fast forward) to 1 (normal playback)
|
// Playback speed ranges from 16 (fast forward) to 1 (normal playback)
|
||||||
// to 0.25 (quarter-speed playback), then goes to -0.25, -0.5, -1, -2, etc
|
// to 0.25 (quarter-speed playback), then goes to -0.25, -0.5, -1, -2, etc
|
||||||
|
|||||||
@@ -277,6 +277,8 @@ const dispatchHandlers = {
|
|||||||
previousTrack: () => controllers.playback().previousTrack(),
|
previousTrack: () => controllers.playback().previousTrack(),
|
||||||
skip: (time) => controllers.playback().skip(time),
|
skip: (time) => controllers.playback().skip(time),
|
||||||
skipTo: (time) => controllers.playback().skipTo(time),
|
skipTo: (time) => controllers.playback().skipTo(time),
|
||||||
|
preview: (time, x) => controllers.playback().preview(time, x),
|
||||||
|
clearPreview: () => controllers.playback().clearPreview(),
|
||||||
changePlaybackRate: (dir) => controllers.playback().changePlaybackRate(dir),
|
changePlaybackRate: (dir) => controllers.playback().changePlaybackRate(dir),
|
||||||
changeVolume: (delta) => controllers.playback().changeVolume(delta),
|
changeVolume: (delta) => controllers.playback().changeVolume(delta),
|
||||||
setVolume: (vol) => controllers.playback().setVolume(vol),
|
setVolume: (vol) => controllers.playback().setVolume(vol),
|
||||||
|
|||||||
@@ -536,6 +536,8 @@ function renderPlayerControls (state) {
|
|||||||
const nextClass = Playlist.hasNext(state) ? '' : 'disabled'
|
const nextClass = Playlist.hasNext(state) ? '' : 'disabled'
|
||||||
|
|
||||||
const elements = [
|
const elements = [
|
||||||
|
renderPreview(state),
|
||||||
|
|
||||||
<div key='playback-bar' className='playback-bar'>
|
<div key='playback-bar' className='playback-bar'>
|
||||||
{renderLoadingBar(state)}
|
{renderLoadingBar(state)}
|
||||||
<div
|
<div
|
||||||
@@ -547,6 +549,8 @@ function renderPlayerControls (state) {
|
|||||||
key='scrub-bar'
|
key='scrub-bar'
|
||||||
className='scrub-bar'
|
className='scrub-bar'
|
||||||
draggable
|
draggable
|
||||||
|
onMouseOver={handleScrubPreview}
|
||||||
|
onMouseOut={clearPreview}
|
||||||
onDragStart={handleDragStart}
|
onDragStart={handleDragStart}
|
||||||
onClick={handleScrub}
|
onClick={handleScrub}
|
||||||
onDrag={handleScrub}
|
onDrag={handleScrub}
|
||||||
@@ -722,6 +726,20 @@ function renderPlayerControls (state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handles a scrub hover (preview another position in the video)
|
||||||
|
function handleScrubPreview (e) {
|
||||||
|
if (!e.clientX) return
|
||||||
|
dispatch('mediaMouseMoved')
|
||||||
|
const windowWidth = document.querySelector('body').clientWidth
|
||||||
|
const fraction = e.clientX / windowWidth
|
||||||
|
const position = fraction * state.playing.duration /* seconds */
|
||||||
|
dispatch('preview', position, e.clientX)
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearPreview (e) {
|
||||||
|
dispatch('clearPreview')
|
||||||
|
}
|
||||||
|
|
||||||
// Handles a click or drag to scrub (jump to another position in the video)
|
// Handles a click or drag to scrub (jump to another position in the video)
|
||||||
function handleScrub (e) {
|
function handleScrub (e) {
|
||||||
if (!e.clientX) return
|
if (!e.clientX) return
|
||||||
@@ -760,6 +778,23 @@ function renderPlayerControls (state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderPreview (state) {
|
||||||
|
if (!state.playing.preview) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const width = 118
|
||||||
|
|
||||||
|
const xPos = Math.max(state.playing.preview.x - (width / 2), 5)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ position: 'absolute', bottom: 50, left: xPos }}>
|
||||||
|
<div style={{ width, height: 70, backgroundColor: 'blue', border: '2px solid lightgrey', borderRadius: 2 }} />
|
||||||
|
<p style={{ textAlign: 'center', margin: 5 }}>{formatTime(state.playing.preview.time, state.playing.duration)}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Renders the loading bar. Shows which parts of the torrent are loaded, which
|
// Renders the loading bar. Shows which parts of the torrent are loaded, which
|
||||||
// can be 'spongey' / non-contiguous
|
// can be 'spongey' / non-contiguous
|
||||||
function renderLoadingBar (state) {
|
function renderLoadingBar (state) {
|
||||||
|
|||||||
Reference in New Issue
Block a user