Merge pull request #392 from Stremio/feat/player-buffered-seekbar

feat: display buffered amount on player seek bar
This commit is contained in:
Alexandru Branza 2023-06-09 19:04:01 +02:00 committed by GitHub
commit 19e1fe4e3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 34 additions and 11 deletions

View file

@ -8,10 +8,11 @@ const useAnimationFrame = require('stremio/common/useAnimationFrame');
const useLiveRef = require('stremio/common/useLiveRef');
const styles = require('./styles');
const Slider = ({ className, value, minimumValue, maximumValue, disabled, onSlide, onComplete }) => {
const Slider = ({ className, value, buffered, minimumValue, maximumValue, disabled, onSlide, onComplete }) => {
const minimumValueRef = useLiveRef(minimumValue !== null && !isNaN(minimumValue) ? minimumValue : 0);
const maximumValueRef = useLiveRef(maximumValue !== null && !isNaN(maximumValue) ? maximumValue : 100);
const valueRef = useLiveRef(value !== null && !isNaN(value) ? Math.min(maximumValueRef.current, Math.max(minimumValueRef.current, value)) : 0);
const bufferedRef = useLiveRef(buffered !== null && !isNaN(buffered) ? Math.min(maximumValueRef.current, Math.max(minimumValueRef.current, buffered)) : 0);
const onSlideRef = useLiveRef(onSlide);
const onCompleteRef = useLiveRef(onComplete);
const sliderContainerRef = React.useRef(null);
@ -95,13 +96,17 @@ const Slider = ({ className, value, minimumValue, maximumValue, disabled, onSlid
};
}, []);
const thumbPosition = Math.max(0, Math.min(1, (valueRef.current - minimumValueRef.current) / (maximumValueRef.current - minimumValueRef.current)));
const bufferedPosition = Math.max(0, Math.min(1, (bufferedRef.current - minimumValueRef.current) / (maximumValueRef.current - minimumValueRef.current)));
return (
<div ref={sliderContainerRef} className={classnames(className, styles['slider-container'], { 'disabled': disabled })} onMouseDown={onMouseDown}>
<div className={styles['layer']}>
<div className={styles['track']} />
</div>
<div className={styles['layer']}>
<div className={styles['track-before']} style={{ width: `calc(100% * ${thumbPosition})` }} />
<div className={styles['track-before']} style={{ width: `calc(100% * ${bufferedPosition})` }} />
</div>
<div className={styles['layer']}>
<div className={styles['track-after']} style={{ width: `calc(100% * ${thumbPosition})` }} />
</div>
<div className={styles['layer']}>
<svg className={styles['thumb']} style={{ marginLeft: `calc(100% * ${thumbPosition})` }} viewBox={'0 0 10 10'}>
@ -115,6 +120,7 @@ const Slider = ({ className, value, minimumValue, maximumValue, disabled, onSlid
Slider.propTypes = {
className: PropTypes.string,
value: PropTypes.number,
buffered: PropTypes.number,
minimumValue: PropTypes.number,
maximumValue: PropTypes.number,
disabled: PropTypes.bool,

View file

@ -17,7 +17,7 @@ html.active-slider-within {
cursor: pointer;
&:hover, &:global(.active) {
.track-before {
.track-after {
background-color: @color-primary-light5;
}
}
@ -29,7 +29,7 @@ html.active-slider-within {
background-color: @color-surface-dark5;
}
.track-before {
.track-after {
background-color: @color-surface;
}
@ -52,18 +52,28 @@ html.active-slider-within {
}
.track {
z-index: 0;
flex: 1;
height: var(--track-size);
background-color: @color-primary-dark3;
background-color: @color-surface-light5-20;
}
.track-before {
z-index: 1;
flex: none;
height: var(--track-size);
background-color: @color-surface-light5-10;
}
.track-after {
z-index: 2;
flex: none;
height: var(--track-size);
background-color: @color-primary-light3;
}
.thumb {
z-index: 3;
flex: none;
width: var(--thumb-size);
height: var(--thumb-size);

View file

@ -17,6 +17,7 @@ const ControlBar = ({
paused,
time,
duration,
buffered,
volume,
muted,
playbackSpeed,
@ -140,6 +141,7 @@ const ControlBar = ({
className={styles['seek-bar']}
time={time}
duration={duration}
buffered={buffered}
onSeekRequested={onSeekRequested}
/>
<div className={styles['control-bar-buttons-container']}>
@ -213,6 +215,7 @@ ControlBar.propTypes = {
paused: PropTypes.bool,
time: PropTypes.number,
duration: PropTypes.number,
buffered: PropTypes.number,
volume: PropTypes.number,
muted: PropTypes.bool,
playbackSpeed: PropTypes.number,

View file

@ -9,7 +9,7 @@ const { Slider } = require('stremio/common');
const formatTime = require('./formatTime');
const styles = require('./styles');
const SeekBar = ({ className, time, duration, onSeekRequested }) => {
const SeekBar = ({ className, time, duration, buffered, onSeekRequested }) => {
const disabled = time === null || isNaN(time) || duration === null || isNaN(duration);
const routeFocused = useRouteFocused();
const [seekTime, setSeekTime] = React.useState(null);
@ -49,6 +49,7 @@ const SeekBar = ({ className, time, duration, onSeekRequested }) => {
:
0
}
buffered={buffered}
minimumValue={0}
maximumValue={duration}
disabled={disabled}
@ -64,6 +65,7 @@ SeekBar.propTypes = {
className: PropTypes.string,
time: PropTypes.number,
duration: PropTypes.number,
buffered: PropTypes.number,
onSeekRequested: PropTypes.func
};

View file

@ -3,7 +3,7 @@
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
:import('~stremio/common/Slider/styles.less') {
slider-track-before: track-before;
slider-track-after: track-after;
slider-thumb: thumb;
}
@ -22,7 +22,7 @@
&:hover {
.slider:not(:global(.disabled)) {
.slider-track-before {
.slider-track-after {
transition: background-color 0s 100ms;
}

View file

@ -4,7 +4,7 @@
:import('~stremio/common/Slider/styles.less') {
slider-track: track;
slider-track-before: track-before;
slider-track-after: track-after;
}
.volume-slider:not(:global(.disabled)) {
@ -12,12 +12,12 @@
background-color: @color-surface-dark5;
}
.slider-track-before {
.slider-track-after {
background-color: @color-surface-light3;
}
&:hover, &:global(.active) {
.slider-track-before {
.slider-track-after {
background-color: @color-surface-light5;
}
}

View file

@ -42,6 +42,7 @@ const Player = ({ urlParams, queryParams }) => {
time: null,
duration: null,
buffering: null,
buffered: null,
volume: null,
muted: null,
playbackSpeed: null,
@ -668,6 +669,7 @@ const Player = ({ urlParams, queryParams }) => {
paused={videoState.paused}
time={videoState.time}
duration={videoState.duration}
buffered={videoState.buffered}
volume={videoState.volume}
muted={videoState.muted}
playbackSpeed={videoState.playbackSpeed}