From e979b185b0d12292b52bc63610a3ac7c32a95101 Mon Sep 17 00:00:00 2001 From: Botzy Date: Tue, 25 Feb 2025 17:26:20 +0200 Subject: [PATCH] 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 ( -
+