From 21be35da369fabb68de5590ebc676b5e4173b2a8 Mon Sep 17 00:00:00 2001 From: Kamil Owczarz Date: Thu, 22 Feb 2024 18:09:52 +0100 Subject: [PATCH 1/4] Add on begin pan gesture event --- .../VideoPlayerControls/VolumeButton/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js index 1c1d042d3893..4cba4506dc0e 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js @@ -42,15 +42,20 @@ function VolumeButton({style, small}) { setSliderHeight(e.nativeEvent.layout.height); }; + const gestureEventHandler = (event) => { + const val = Math.floor((1 - event.y / sliderHeight) * 100) / 100; + volume.value = Math.min(Math.max(val, 0), 1); + }; + const pan = Gesture.Pan() - .onBegin(() => { + .onBegin((event) => { runOnJS(setIsSliderBeingUsed)(true); + gestureEventHandler(event); }) .onChange((event) => { - const val = Math.floor((1 - event.y / sliderHeight) * 100) / 100; - volume.value = Math.min(Math.max(val, 0), 1); + gestureEventHandler(event); }) - .onEnd(() => { + .onFinished(() => { runOnJS(setIsSliderBeingUsed)(false); }); From 47264892cf3ca09bceb5e2550dc84e8673e95d3f Mon Sep 17 00:00:00 2001 From: Kamil Owczarz Date: Thu, 22 Feb 2024 18:20:46 +0100 Subject: [PATCH 2/4] Cleanup --- .../VideoPlayer/VideoPlayerControls/VolumeButton/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js index 4cba4506dc0e..b0757eb7df68 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js @@ -55,7 +55,7 @@ function VolumeButton({style, small}) { .onChange((event) => { gestureEventHandler(event); }) - .onFinished(() => { + .onFinalize(() => { runOnJS(setIsSliderBeingUsed)(false); }); From 9112cceb6fbadcd7d1de94867dd878f32e4bc901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ska=C5=82ka?= Date: Mon, 26 Feb 2024 17:13:43 +0100 Subject: [PATCH 3/4] Add review changes --- .../VideoPlayerControls/VolumeButton/index.js | 26 +++++++++++-------- src/libs/NumberUtils.ts | 23 +++++++++++++++- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js index b0757eb7df68..45f47eb87c36 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React, {memo, useState} from 'react'; +import React, {memo, useCallback, useState} from 'react'; import {View} from 'react-native'; import {Gesture, GestureDetector} from 'react-native-gesture-handler'; import Animated, {runOnJS, useAnimatedStyle, useDerivedValue} from 'react-native-reanimated'; @@ -9,6 +9,7 @@ import IconButton from '@components/VideoPlayer/IconButton'; import {useVolumeContext} from '@components/VideoPlayerContexts/VolumeContext'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as NumberUtils from '@libs/NumberUtils'; import stylePropTypes from '@styles/stylePropTypes'; const propTypes = { @@ -38,22 +39,25 @@ function VolumeButton({style, small}) { const [volumeIcon, setVolumeIcon] = useState({icon: getVolumeIcon(volume.value)}); const [isSliderBeingUsed, setIsSliderBeingUsed] = useState(false); - const onSliderLayout = (e) => { + const onSliderLayout = useCallback((e) => { setSliderHeight(e.nativeEvent.layout.height); - }; + }, []); - const gestureEventHandler = (event) => { - const val = Math.floor((1 - event.y / sliderHeight) * 100) / 100; - volume.value = Math.min(Math.max(val, 0), 1); - }; + const changeVolumeOnPan = useCallback( + (event) => { + const val = NumberUtils.roundToTwoDecimalPlaces(1 - event.y / sliderHeight); + volume.value = NumberUtils.clamp(val, 0, 1); + }, + [sliderHeight, volume], + ); const pan = Gesture.Pan() .onBegin((event) => { runOnJS(setIsSliderBeingUsed)(true); - gestureEventHandler(event); + changeVolumeOnPan(event); }) .onChange((event) => { - gestureEventHandler(event); + changeVolumeOnPan(event); }) .onFinalize(() => { runOnJS(setIsSliderBeingUsed)(false); @@ -61,9 +65,9 @@ function VolumeButton({style, small}) { const progressBarStyle = useAnimatedStyle(() => ({height: `${volume.value * 100}%`})); - const updateIcon = (vol) => { + const updateIcon = useCallback((vol) => { setVolumeIcon({icon: getVolumeIcon(vol)}); - }; + }, []); useDerivedValue(() => { runOnJS(updateVolume)(volume.value); diff --git a/src/libs/NumberUtils.ts b/src/libs/NumberUtils.ts index d7eb87a2ed1e..b9814487bf3f 100644 --- a/src/libs/NumberUtils.ts +++ b/src/libs/NumberUtils.ts @@ -69,4 +69,25 @@ function parseFloatAnyLocale(value: string): number { return parseFloat(value ? value.replace(',', '.') : value); } -export {rand64, generateHexadecimalValue, generateRandomInt, parseFloatAnyLocale}; +/** + * Rounds a number to two decimal places. + * @param value the value to round + * @returns the rounded value + */ +function roundToTwoDecimalPlaces(value: number): number { + return Math.round(value * 100) / 100; +} + +/** + * Clamps a value between a minimum and maximum value. + * + * @param value the value to clamp + * @param min the minimum value + * @param max the maximum value + * @returns the clamped value + */ +function clamp(value: number, min: number, max: number): number { + return Math.min(Math.max(value, min), max); +} + +export {rand64, generateHexadecimalValue, generateRandomInt, parseFloatAnyLocale, roundToTwoDecimalPlaces, clamp}; From f3cdd232b6d1f1c32537030a99040d68f5df8c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Ska=C5=82ka?= Date: Wed, 28 Feb 2024 09:05:13 +0100 Subject: [PATCH 4/4] Fix volume button on iOS/Safari --- src/components/VideoPlayerContexts/VolumeContext.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/VideoPlayerContexts/VolumeContext.js b/src/components/VideoPlayerContexts/VolumeContext.js index 2df463654075..a0b972d37a0d 100644 --- a/src/components/VideoPlayerContexts/VolumeContext.js +++ b/src/components/VideoPlayerContexts/VolumeContext.js @@ -14,7 +14,7 @@ function VolumeContextProvider({children}) { if (!currentVideoPlayerRef.current) { return; } - currentVideoPlayerRef.current.setStatusAsync({volume: newVolume}); + currentVideoPlayerRef.current.setStatusAsync({volume: newVolume, isMuted: newVolume === 0}); volume.value = newVolume; }, [currentVideoPlayerRef, volume],