mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 10:42:12 +00:00
Merge pull request #851 from Stremio/feat/player-mobile-slide-volume
Player: Improve volume UX on mobile and tablets
This commit is contained in:
commit
1bd56e0f3a
3 changed files with 53 additions and 9 deletions
|
|
@ -31,14 +31,18 @@ const Slider = ({ className, value, buffered, minimumValue, maximumValue, disabl
|
|||
const retainThumb = React.useCallback(() => {
|
||||
window.addEventListener('blur', onBlur);
|
||||
window.addEventListener('mouseup', onMouseUp);
|
||||
window.addEventListener('touchend', onTouchEnd);
|
||||
window.addEventListener('mousemove', onMouseMove);
|
||||
window.addEventListener('touchmove', onTouchMove);
|
||||
document.documentElement.className = classnames(document.documentElement.className, styles['active-slider-within']);
|
||||
}, []);
|
||||
const releaseThumb = React.useCallback(() => {
|
||||
cancelThumbAnimation();
|
||||
window.removeEventListener('blur', onBlur);
|
||||
window.removeEventListener('mouseup', onMouseUp);
|
||||
window.removeEventListener('touchend', onTouchEnd);
|
||||
window.removeEventListener('mousemove', onMouseMove);
|
||||
window.removeEventListener('touchmove', onTouchMove);
|
||||
const classList = document.documentElement.className.split(' ');
|
||||
const classIndex = classList.indexOf(styles['active-slider-within']);
|
||||
if (classIndex !== -1) {
|
||||
|
|
@ -85,6 +89,36 @@ const Slider = ({ className, value, buffered, minimumValue, maximumValue, disabl
|
|||
|
||||
retainThumb();
|
||||
}, []);
|
||||
const onTouchStart = React.useCallback((event) => {
|
||||
const touch = event.touches[0];
|
||||
const value = calculateValueForMouseX(touch.clientX);
|
||||
if (typeof onSlideRef.current === 'function') {
|
||||
onSlideRef.current(value);
|
||||
}
|
||||
|
||||
retainThumb();
|
||||
event.preventDefault();
|
||||
}, []);
|
||||
const onTouchMove = React.useCallback((event) => {
|
||||
requestThumbAnimation(() => {
|
||||
const touch = event.touches[0];
|
||||
const value = calculateValueForMouseX(touch.clientX);
|
||||
if (typeof onSlideRef.current === 'function') {
|
||||
onSlideRef.current(value);
|
||||
}
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
}, []);
|
||||
const onTouchEnd = React.useCallback((event) => {
|
||||
const touch = event.changedTouches[0];
|
||||
const value = calculateValueForMouseX(touch.clientX);
|
||||
if (typeof onCompleteRef.current === 'function') {
|
||||
onCompleteRef.current(value);
|
||||
}
|
||||
|
||||
releaseThumb();
|
||||
}, []);
|
||||
React.useLayoutEffect(() => {
|
||||
if (!routeFocused || disabled) {
|
||||
releaseThumb();
|
||||
|
|
@ -98,7 +132,7 @@ const Slider = ({ className, value, buffered, minimumValue, maximumValue, disabl
|
|||
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 ref={sliderContainerRef} className={classnames(className, styles['slider-container'], { 'disabled': disabled })} onMouseDown={onMouseDown} onTouchStart={onTouchStart}>
|
||||
<div className={styles['layer']}>
|
||||
<div className={classnames(styles['track'], { [styles['audio-boost']]: audioBoost })} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const { useServices } = require('stremio/services');
|
|||
const SeekBar = require('./SeekBar');
|
||||
const VolumeSlider = require('./VolumeSlider');
|
||||
const styles = require('./styles');
|
||||
const { useBinaryState } = require('stremio/common');
|
||||
const { useBinaryState, usePlatform } = require('stremio/common');
|
||||
const { t } = require('i18next');
|
||||
|
||||
const ControlBar = ({
|
||||
|
|
@ -40,9 +40,11 @@ const ControlBar = ({
|
|||
onToggleSideDrawer,
|
||||
onToggleOptionsMenu,
|
||||
onToggleStatisticsMenu,
|
||||
onTouchEnd,
|
||||
...props
|
||||
}) => {
|
||||
const { chromecast } = useServices();
|
||||
const platform = usePlatform();
|
||||
const [chromecastServiceActive, setChromecastServiceActive] = React.useState(() => chromecast.active);
|
||||
const [buttonsMenuOpen, , , toggleButtonsMenu] = useBinaryState(false);
|
||||
const onSubtitlesButtonMouseDown = React.useCallback((event) => {
|
||||
|
|
@ -103,7 +105,7 @@ const ControlBar = ({
|
|||
};
|
||||
}, []);
|
||||
return (
|
||||
<div {...props} className={classnames(className, styles['control-bar-container'])}>
|
||||
<div {...props} onTouchStart={props.onMouseOver} onTouchMove={props.onMouseMove} onTouchEnd={onTouchEnd} className={classnames(className, styles['control-bar-container'])}>
|
||||
<SeekBar
|
||||
className={styles['seek-bar']}
|
||||
time={time}
|
||||
|
|
@ -135,12 +137,16 @@ const ControlBar = ({
|
|||
}
|
||||
/>
|
||||
</Button>
|
||||
<VolumeSlider
|
||||
className={styles['volume-slider']}
|
||||
volume={volume}
|
||||
muted={muted}
|
||||
onVolumeChangeRequested={onVolumeChangeRequested}
|
||||
/>
|
||||
{
|
||||
!platform.isMobile ?
|
||||
<VolumeSlider
|
||||
className={styles['volume-slider']}
|
||||
volume={volume}
|
||||
muted={muted}
|
||||
onVolumeChangeRequested={onVolumeChangeRequested}
|
||||
/>
|
||||
: null
|
||||
}
|
||||
<div className={styles['spacing']} />
|
||||
<Button className={styles['control-bar-buttons-menu-button']} onClick={toggleButtonsMenu}>
|
||||
<Icon className={styles['icon']} name={'more-vertical'} />
|
||||
|
|
@ -206,6 +212,9 @@ ControlBar.propTypes = {
|
|||
onToggleSideDrawer: PropTypes.func,
|
||||
onToggleOptionsMenu: PropTypes.func,
|
||||
onToggleStatisticsMenu: PropTypes.func,
|
||||
onMouseOver: PropTypes.func,
|
||||
onMouseMove: PropTypes.func,
|
||||
onTouchEnd: PropTypes.func,
|
||||
};
|
||||
|
||||
module.exports = ControlBar;
|
||||
|
|
|
|||
|
|
@ -717,6 +717,7 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
onToggleSideDrawer={toggleSideDrawer}
|
||||
onMouseMove={onBarMouseMove}
|
||||
onMouseOver={onBarMouseMove}
|
||||
onTouchEnd={onContainerMouseLeave}
|
||||
/>
|
||||
{
|
||||
nextVideoPopupOpen ?
|
||||
|
|
|
|||
Loading…
Reference in a new issue