popup used for volume slider

This commit is contained in:
NikolaBorislavovHristov 2018-11-16 16:01:38 +02:00
parent c2a44a5a9b
commit 45f93ed3f6
3 changed files with 109 additions and 87 deletions

View file

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import classnames from 'classnames';
import debounce from 'lodash.debounce';
import Icon from 'stremio-icons/dom';
import { Slider } from 'stremio-common';
import { Slider, Popup } from 'stremio-common';
import styles from './styles';
class ControlBar extends Component {
@ -11,7 +11,8 @@ class ControlBar extends Component {
super(props);
this.state = {
seekTime: -1
time: -1,
volume: -1
};
}
@ -21,31 +22,53 @@ class ControlBar extends Component {
nextProps.time !== this.props.time ||
nextProps.duration !== this.props.duration ||
nextProps.volume !== this.props.volume ||
nextState.seekTime !== this.state.seekTime;
nextState.time !== this.state.time ||
nextState.volume !== this.state.volume;
}
componentWillUnmount() {
this.resetSeekTime.cancel();
this.resetTime.cancel();
this.resetVolume.cancel();
}
resetSeekTime = debounce(() => {
this.setState({ seekTime: -1 });
}, 3000)
resetTime = debounce(() => {
this.setState({ time: -1 });
}, 1500)
onSliding = (seekTime) => {
this.resetSeekTime.cancel();
this.setState({ seekTime });
resetVolume = debounce(() => {
this.setState({ volume: -1 });
}, 100)
onTimeSliding = (time) => {
this.resetTime.cancel();
this.setState({ time });
}
onSlidingCompleted = (seekTime) => {
this.setState({ seekTime });
this.props.seek(seekTime);
this.resetSeekTime();
onTimeSlidingCompleted = (time) => {
this.setState({ time });
this.props.setTime(time);
this.resetTime();
}
onSlidingAborted = () => {
this.resetSeekTime.cancel();
this.setState({ seekTime: -1 });
onTimeSlidingAborted = () => {
this.resetTime.cancel();
this.setState({ time: -1 });
}
onVolumeSliding = (volume) => {
this.resetVolume.cancel();
this.setState({ volume });
}
onVolumeSlidingCompleted = (volume) => {
this.setState({ volume });
this.props.setVolume(volume);
this.resetVolume();
}
onVolumeSlidingAborted = () => {
this.resetVolume.cancel();
this.setState({ volume: -1 });
}
onPlayPauseButtonClicked = () => {
@ -59,22 +82,22 @@ class ControlBar extends Component {
return `${('0' + hours).slice(-2)}:${('0' + minutes).slice(-2)}:${('0' + seconds).slice(-2)}`;
}
renderSeekSlider() {
renderTimeSlider() {
if (this.props.time === null || this.props.duration === null) {
return null;
}
return (
<Slider
containerClassName={styles['seek-slider']}
thumbClassName={styles['seek-thumb']}
value={this.state.seekTime !== -1 ? this.state.seekTime : this.props.time}
containerClassName={styles['time-slider']}
thumbClassName={styles['time-thumb']}
value={this.state.time !== -1 ? this.state.time : this.props.time}
maxValue={this.props.duration}
minValue={0}
orientation={'horizontal'}
onSliding={this.onSliding}
onSlidingAborted={this.onSlidingAborted}
onSlidingCompleted={this.onSlidingCompleted}
onSliding={this.onTimeSliding}
onSlidingAborted={this.onTimeSlidingAborted}
onSlidingCompleted={this.onTimeSlidingCompleted}
/>
);
}
@ -99,8 +122,8 @@ class ControlBar extends Component {
return null;
}
const currentTime = this.state.seekTime !== -1 ?
this.formatTime(this.state.seekTime)
const currentTime = this.state.time !== -1 ?
this.formatTime(this.state.time)
:
this.formatTime(this.props.time);
@ -114,38 +137,45 @@ class ControlBar extends Component {
return null;
}
const volumeIcon = this.props.volume === 0 ? 'ic_volume0' :
this.props.volume < 50 ? 'ic_volume1' :
this.props.volume < 100 ? 'ic_volume2' :
const volume = this.state.volume !== -1 ? this.state.volume : this.props.volume;
const volumeIcon = volume === 0 ? 'ic_volume0' :
volume < 50 ? 'ic_volume1' :
volume < 100 ? 'ic_volume2' :
'ic_volume3';
return (
<div className={classnames(styles['button'], styles['volume-button'])}>
<Icon
className={styles['icon']}
icon={volumeIcon}
/>
<div className={styles['volume-slider-container']}>
<Slider
containerClassName={styles['volume-slider']}
thumbClassName={styles['volume-thumb']}
value={50}
maxValue={110}
minValue={0}
orientation={'vertical'}
// onSliding={this.onSliding}
// onSlidingAborted={this.onSlidingAborted}
// onSlidingCompleted={this.onSlidingCompleted}
/>
</div>
</div>
<Popup>
<Popup.Label>
<div className={styles['button']}>
<Icon
className={styles['icon']}
icon={volumeIcon}
/>
</div>
</Popup.Label>
<Popup.Menu>
<div className={styles['volume-slider-container']}>
<Slider
containerClassName={styles['volume-slider']}
thumbClassName={styles['volume-thumb']}
value={volume}
maxValue={100}
minValue={0}
orientation={'vertical'}
onSliding={this.onVolumeSliding}
onSlidingAborted={this.onVolumeSlidingAborted}
onSlidingCompleted={this.onVolumeSlidingCompleted}
/>
</div>
</Popup.Menu>
</Popup>
);
}
render() {
return (
<div className={classnames(styles['control-bar-container'], this.props.className)}>
{this.renderSeekSlider()}
{this.renderTimeSlider()}
<div className={styles['buttons-bar-container']}>
{this.renderPlayPauseButton()}
<div className={styles['separator']} />
@ -166,7 +196,8 @@ ControlBar.propTypes = {
volume: PropTypes.number,
play: PropTypes.func.isRequired,
pause: PropTypes.func.isRequired,
seek: PropTypes.func.isRequired
setTime: PropTypes.func.isRequired,
setVolume: PropTypes.func.isRequired
};
export default ControlBar;

View file

@ -13,12 +13,12 @@
padding-left: 2%;
padding-right: 2%;
.seek-slider {
.time-slider {
width: 100%;
height: @seek-slider-height;
z-index: 1;
.seek-thumb {
.time-thumb {
width: @seek-slider-height;
height: @seek-slider-height;
}
@ -51,42 +51,11 @@
fill: @colorwhite;
}
}
&.volume-button {
position: relative;
.volume-slider-container {
display: none;
justify-content: center;
width: 100%;
height: 300%;
position: absolute;
bottom: 100%;
.volume-slider {
width: round((@buttons-bar-height * 0.4));
height: 100%;
.volume-thumb {
width: round((@buttons-bar-height * 0.4));
height: round((@buttons-bar-height * 0.4));
}
}
}
&:hover {
.volume-slider-container {
display: flex;
}
}
}
}
.separator {
margin-left: round((@buttons-bar-height * 0.25));
margin-right: round((@buttons-bar-height * 0.25));
margin-left: floor((@buttons-bar-height * 0.25));
margin-right: floor((@buttons-bar-height * 0.25));
width: 1px;
height: 70%;
background-color: @colorneutrallight80;
@ -101,4 +70,21 @@
flex: 1
}
}
}
.volume-slider-container {
padding: ceil((@buttons-bar-height * 0.2)) 0;
width: @buttons-bar-height;
display: flex;
justify-content: center;
.volume-slider {
width: floor((@buttons-bar-height * 0.4));
height: floor((@buttons-bar-height * 3));
.volume-thumb {
width: floor((@buttons-bar-height * 0.4));
height: floor((@buttons-bar-height * 0.4));
}
}
}

View file

@ -87,10 +87,14 @@ class Player extends Component {
this.videoRef.current && this.videoRef.current.dispatch('setProp', 'paused', true);
}
seek = (time) => {
setTime = (time) => {
this.videoRef.current && this.videoRef.current.dispatch('setProp', 'time', time);
}
setVolume = (volume) => {
this.videoRef.current && this.videoRef.current.dispatch('setProp', 'volume', volume);
}
renderVideo() {
if (this.state.videoComponent === null) {
return null;
@ -126,7 +130,8 @@ class Player extends Component {
volume={this.state.volume}
play={this.play}
pause={this.pause}
seek={this.seek}
setTime={this.setTime}
setVolume={this.setVolume}
/>
);
}