Volume slider implemented with hooks

This commit is contained in:
NikolaBorislavovHristov 2019-10-03 15:03:06 +03:00
parent d05d430523
commit 10d7b2194f
3 changed files with 43 additions and 80 deletions

View file

@ -5,68 +5,43 @@ const debounce = require('lodash.debounce');
const { Slider } = require('stremio/common');
const styles = require('./styles');
class VolumeSlider extends React.Component {
constructor(props) {
super(props);
this.state = {
volume: null
const VolumeSlider = ({ className, volume, dispatch }) => {
const [slidingVolume, setSlidingVolume] = React.useState(null);
const resetVolumeDebounced = React.useCallback(debounce(() => {
setSlidingVolume(null);
}, 100), []);
const onSlide = React.useCallback((volume) => {
resetVolumeDebounced.cancel();
setSlidingVolume(volume);
}, []);
const onComplete = React.useCallback((volume) => {
resetVolumeDebounced();
setSlidingVolume(volume);
if (typeof dispatch === 'function') {
dispatch({ propName: 'volume', propValue: volume });
}
}, []);
React.useEffect(() => {
return () => {
resetVolumeDebounced.cancel();
};
}
shouldComponentUpdate(nextProps, nextState) {
return nextState.volume !== this.state.volume ||
nextProps.className !== this.props.className ||
nextProps.volume !== this.props.volume;
}
componentWillUnmount() {
this.resetVolumeDebounced.cancel();
}
resetVolumeDebounced = debounce(() => {
this.setState({ volume: null });
}, 100)
onSlide = (volume) => {
this.resetVolumeDebounced.cancel();
this.setState({ volume });
}
onComplete = (volume) => {
this.resetVolumeDebounced();
this.setState({ volume });
this.props.dispatch({ propName: 'volume', propValue: volume });
}
onCancel = () => {
this.resetVolumeDebounced.cancel();
this.setState({ volume: null });
}
render() {
const volume = this.state.volume !== null ? this.state.volume : this.props.volume;
return (
<div className={classnames(this.props.className, styles['volume-slider-container'], { 'active': this.state.volume !== null })}>
<Slider
className={styles['volume-slider']}
value={volume}
minimumValue={0}
maximumValue={100}
orientation={'horizontal'}
onSlide={this.onSlide}
onComplete={this.onComplete}
onCancel={this.onCancel}
/>
</div>
);
}
}
}, []);
return (
<Slider
className={classnames(className, styles['volume-slider'], { 'active': slidingVolume !== null }, { 'disabled': volume === null || isNaN(volume) })}
value={slidingVolume !== null ? slidingVolume : volume !== null ? volume : 100}
minimumValue={0}
maximumValue={100}
onSlide={onSlide}
onComplete={onComplete}
/>
);
};
VolumeSlider.propTypes = {
className: PropTypes.string,
volume: PropTypes.number,
dispatch: PropTypes.func.isRequired
dispatch: PropTypes.func
};
module.exports = VolumeSlider;

View file

@ -1,24 +1,11 @@
.volume-slider-container {
padding: 0 calc(var(--volume-slider-thumb-size) / 2);
.volume-slider {
--thumb-size: var(--volume-slider-thumb-size);
--track-size: var(--volume-slider-track-size);
--track-before-color: var(--color-primary);
--track-color: var(--color-backgroundlighter);
--thumb-color: transparent;
width: 100%;
height: 100%;
&:global(.disabled) {
--track-color: var(--color-surfacedark);
}
}
:import('~stremio/common/Slider/styles.less') {
slider-track-before: track-before;
}
.volume-slider {
&:hover, &:global(.active) {
.volume-slider {
--track-before-color: var(--color-primarylight);
--thumb-color: var(--color-surfacelighter);
.slider-track-before {
background-color: var(--color-primarylight);
}
}
}

View file

@ -51,10 +51,11 @@
}
.volume-slider {
--volume-slider-thumb-size: calc(var(--control-bar-button-size) * 0.36);
--volume-slider-track-size: calc(var(--control-bar-button-size) * 0.10);
width: calc(var(--control-bar-button-size) * 4);
height: var(--control-bar-button-size);
--thumb-size: 1.25rem;
flex: none;
width: 16rem;
height: 4rem;
margin: 0 1rem;
}
.spacing {