From e979b185b0d12292b52bc63610a3ac7c32a95101 Mon Sep 17 00:00:00 2001 From: Botzy Date: Tue, 25 Feb 2025 17:26:20 +0200 Subject: [PATCH 1/3] feat(Player): handle touch events when sliding volume slider on mobile --- src/components/Slider/Slider.js | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/components/Slider/Slider.js b/src/components/Slider/Slider.js index 0e5c96c97..d0d4721b8 100644 --- a/src/components/Slider/Slider.js +++ b/src/components/Slider/Slider.js @@ -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 ( -
+
From eb192997d97853d36d87cc727568e38754994944 Mon Sep 17 00:00:00 2001 From: Botzy Date: Wed, 26 Feb 2025 15:24:17 +0200 Subject: [PATCH 2/3] feat(Player): prevent immersing while volume slider is in use --- src/routes/Player/ControlBar/ControlBar.js | 6 +++++- src/routes/Player/Player.js | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js index 745e2bd49..956425973 100644 --- a/src/routes/Player/ControlBar/ControlBar.js +++ b/src/routes/Player/ControlBar/ControlBar.js @@ -40,6 +40,7 @@ const ControlBar = ({ onToggleSideDrawer, onToggleOptionsMenu, onToggleStatisticsMenu, + onTouchEnd, ...props }) => { const { chromecast } = useServices(); @@ -103,7 +104,7 @@ const ControlBar = ({ }; }, []); return ( -
+
{ onToggleSideDrawer={toggleSideDrawer} onMouseMove={onBarMouseMove} onMouseOver={onBarMouseMove} + onTouchEnd={onContainerMouseLeave} /> { nextVideoPopupOpen ? From 54b0afb075523e5998d55b7ba5e1ad52412be682 Mon Sep 17 00:00:00 2001 From: Botzy Date: Thu, 13 Mar 2025 18:43:20 +0200 Subject: [PATCH 3/3] fix(Player): remove volume slider on mobile device --- src/routes/Player/ControlBar/ControlBar.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js index 956425973..1db82338c 100644 --- a/src/routes/Player/ControlBar/ControlBar.js +++ b/src/routes/Player/ControlBar/ControlBar.js @@ -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 = ({ @@ -44,6 +44,7 @@ const ControlBar = ({ ...props }) => { const { chromecast } = useServices(); + const platform = usePlatform(); const [chromecastServiceActive, setChromecastServiceActive] = React.useState(() => chromecast.active); const [buttonsMenuOpen, , , toggleButtonsMenu] = useBinaryState(false); const onSubtitlesButtonMouseDown = React.useCallback((event) => { @@ -136,12 +137,16 @@ const ControlBar = ({ } /> - + { + !platform.isMobile ? + + : null + }