Skip to content

Commit

Permalink
Merge pull request #37094 from software-mansion-labs/video-player-fol…
Browse files Browse the repository at this point in the history
…lowups/fix-not-adjusting-volume-on-press

Fix unable to adjust volume by clicking on any part of the volume slider
  • Loading branch information
roryabraham authored Feb 28, 2024
2 parents 5fbcbb5 + f3cdd23 commit 3acf39f
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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 = {
Expand Down Expand Up @@ -38,27 +39,35 @@ 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 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(() => {
.onBegin((event) => {
runOnJS(setIsSliderBeingUsed)(true);
changeVolumeOnPan(event);
})
.onChange((event) => {
const val = Math.floor((1 - event.y / sliderHeight) * 100) / 100;
volume.value = Math.min(Math.max(val, 0), 1);
changeVolumeOnPan(event);
})
.onEnd(() => {
.onFinalize(() => {
runOnJS(setIsSliderBeingUsed)(false);
});

const progressBarStyle = useAnimatedStyle(() => ({height: `${volume.value * 100}%`}));

const updateIcon = (vol) => {
const updateIcon = useCallback((vol) => {
setVolumeIcon({icon: getVolumeIcon(vol)});
};
}, []);

useDerivedValue(() => {
runOnJS(updateVolume)(volume.value);
Expand Down
2 changes: 1 addition & 1 deletion src/components/VideoPlayerContexts/VolumeContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
18 changes: 17 additions & 1 deletion src/libs/NumberUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,20 @@ function roundDownToLargestMultiple(p: number, q: number) {
return Math.floor(p / q) * q;
}

export {rand64, generateHexadecimalValue, generateRandomInt, parseFloatAnyLocale, roundDownToLargestMultiple};
/**
* Rounds a number to two decimal places.
* @returns the rounded value
*/
function roundToTwoDecimalPlaces(value: number): number {
return Math.round(value * 100) / 100;
}

/**
* Clamps a value between a minimum and 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, roundDownToLargestMultiple, roundToTwoDecimalPlaces, clamp};

0 comments on commit 3acf39f

Please sign in to comment.