From 2c91dcfd3c417e5b2fcaf3e22755041db3e494e0 Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Tue, 3 Dec 2024 13:06:58 +0100 Subject: [PATCH 1/6] fix unstable sound level bug --- src/components/VideoPlayer/BaseVideoPlayer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/VideoPlayer/BaseVideoPlayer.tsx b/src/components/VideoPlayer/BaseVideoPlayer.tsx index 140d3f5eccc46..44b5b5dd1ade3 100644 --- a/src/components/VideoPlayer/BaseVideoPlayer.tsx +++ b/src/components/VideoPlayer/BaseVideoPlayer.tsx @@ -5,7 +5,7 @@ import debounce from 'lodash/debounce'; import type {MutableRefObject} from 'react'; import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {GestureResponderEvent} from 'react-native'; -import {View} from 'react-native'; +import {Platform, View} from 'react-native'; import {runOnJS, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import AttachmentOfflineIndicator from '@components/AttachmentOfflineIndicator'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; @@ -212,7 +212,7 @@ function BaseVideoPlayer({ } if (prevIsMutedRef.current && prevVolumeRef.current === 0 && !status.isMuted) { - updateVolume(0.25); + updateVolume(Platform.OS === 'web' ? 0.25 : 1); } if (isFullScreenRef.current && prevVolumeRef.current !== 0 && status.volume === 0 && !status.isMuted) { currentVideoPlayerRef.current?.setStatusAsync({isMuted: true}); From 10c3901834e2d9ca3282f50894bbafbcf56e5c55 Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Tue, 3 Dec 2024 18:21:38 +0100 Subject: [PATCH 2/6] working logic move to sound context --- .../VideoPlayer/BaseVideoPlayer.tsx | 22 ++++++------- .../VolumeButton/index.tsx | 8 +++-- .../VideoPlayerContexts/VolumeContext.tsx | 32 +++++++++++++++---- src/components/VideoPlayerContexts/types.ts | 3 +- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/components/VideoPlayer/BaseVideoPlayer.tsx b/src/components/VideoPlayer/BaseVideoPlayer.tsx index 44b5b5dd1ade3..82cc4e1624cd0 100644 --- a/src/components/VideoPlayer/BaseVideoPlayer.tsx +++ b/src/components/VideoPlayer/BaseVideoPlayer.tsx @@ -188,9 +188,6 @@ function BaseVideoPlayer({ [playVideo, videoResumeTryNumberRef], ); - const prevIsMutedRef = useRef(false); - const prevVolumeRef = useRef(0); - const handlePlaybackStatusUpdate = useCallback( (status: AVPlaybackStatus) => { if (!status.isLoaded) { @@ -211,15 +208,6 @@ function BaseVideoPlayer({ setIsEnded(false); } - if (prevIsMutedRef.current && prevVolumeRef.current === 0 && !status.isMuted) { - updateVolume(Platform.OS === 'web' ? 0.25 : 1); - } - if (isFullScreenRef.current && prevVolumeRef.current !== 0 && status.volume === 0 && !status.isMuted) { - currentVideoPlayerRef.current?.setStatusAsync({isMuted: true}); - } - prevIsMutedRef.current = status.isMuted; - prevVolumeRef.current = status.volume; - const isVideoPlaying = status.isPlaying; // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const currentDuration = status.durationMillis || videoDuration * 1000; @@ -266,7 +254,15 @@ function BaseVideoPlayer({ if (!('isMuted' in status)) { return; } - + // updateVolume((value) => { + // const valueToSet = value === 0 ? 0.25 : value; + // console.log("_________________________________________") + // console.log('valueToSet', valueToSet); + // console.log('status', status); + // console.log("_________________________________________") + // + // return status.isMuted ? 0 : status.volume || valueToSet; + // }); updateVolume(status.isMuted ? 0 : status.volume || 1); }); diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx index a6e44607ea62f..0899a86678eb4 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx @@ -33,7 +33,7 @@ const getVolumeIcon = (volume: number) => { function VolumeButton({style, small = false}: VolumeButtonProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const {updateVolume, volume} = useVolumeContext(); + const {updateVolume, volume, previousVolume} = useVolumeContext(); const [sliderHeight, setSliderHeight] = useState(1); const [volumeIcon, setVolumeIcon] = useState({icon: getVolumeIcon(volume.get())}); const [isSliderBeingUsed, setIsSliderBeingUsed] = useState(false); @@ -95,7 +95,11 @@ function VolumeButton({style, small = false}: VolumeButtonProps) { updateVolume(volume.get() === 0 ? 1 : 0)} + onPress={() => + updateVolume((value) => { + return value === 0 ? previousVolume.get() : 0; + }) + } src={volumeIcon.icon} small={small} shouldForceRenderingTooltipBelow diff --git a/src/components/VideoPlayerContexts/VolumeContext.tsx b/src/components/VideoPlayerContexts/VolumeContext.tsx index 1f7b3bf665515..a669990b4adc7 100644 --- a/src/components/VideoPlayerContexts/VolumeContext.tsx +++ b/src/components/VideoPlayerContexts/VolumeContext.tsx @@ -9,28 +9,46 @@ const Context = React.createContext(null); function VolumeContextProvider({children}: ChildrenProps) { const {currentVideoPlayerRef, originalParent} = usePlaybackContext(); const volume = useSharedValue(0); + const previousVolume = useSharedValue(1); const updateVolume = useCallback( - (newVolume: number) => { + (newVolume: number | ((actualValue: number) => number)) => { if (!currentVideoPlayerRef.current) { return; } - currentVideoPlayerRef.current.setStatusAsync({volume: newVolume, isMuted: newVolume === 0}); - volume.set(newVolume); + const volumeValue = typeof newVolume === 'function' ? newVolume(volume.get()) : newVolume; + + currentVideoPlayerRef.current.setStatusAsync({ + volume: volumeValue, + isMuted: volumeValue === 0, + }); + + volume.set((value: number) => { + if (value !== 0) { + previousVolume.set(value); + } + return volumeValue; + }); }, [currentVideoPlayerRef, volume], ); - // We want to update the volume when currently playing video changes. - // When originalParent changed we're sure that currentVideoPlayerRef is updated. So we can apply the new volume. useEffect(() => { if (!originalParent) { return; } - updateVolume(volume.get()); + updateVolume(() => volume.get()); }, [originalParent, updateVolume, volume]); - const contextValue = useMemo(() => ({updateVolume, volume}), [updateVolume, volume]); + const contextValue = useMemo( + () => ({ + updateVolume, + volume, + previousVolume, + }), + [updateVolume, volume, previousVolume], + ); + return {children}; } diff --git a/src/components/VideoPlayerContexts/types.ts b/src/components/VideoPlayerContexts/types.ts index bfccebb2df3f7..d5a77d4e9036d 100644 --- a/src/components/VideoPlayerContexts/types.ts +++ b/src/components/VideoPlayerContexts/types.ts @@ -23,8 +23,9 @@ type PlaybackContext = { }; type VolumeContext = { - updateVolume: (newVolume: number) => void; + updateVolume: (newVolume: number | ((value: number) => number)) => void; volume: SharedValue; + previousVolume: SharedValue; }; type VideoPopoverMenuContext = { From f98f9da13164a43515efb161b18ac5263c8d7bfd Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Wed, 4 Dec 2024 10:20:35 +0100 Subject: [PATCH 3/6] code cleaning before PR --- src/components/VideoPlayer/BaseVideoPlayer.tsx | 12 ++---------- .../VideoPlayerControls/VolumeButton/index.tsx | 4 ++-- .../VideoPlayerContexts/VolumeContext.tsx | 13 +++++++------ src/components/VideoPlayerContexts/types.ts | 2 +- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/components/VideoPlayer/BaseVideoPlayer.tsx b/src/components/VideoPlayer/BaseVideoPlayer.tsx index 82cc4e1624cd0..4e7e1dea764ec 100644 --- a/src/components/VideoPlayer/BaseVideoPlayer.tsx +++ b/src/components/VideoPlayer/BaseVideoPlayer.tsx @@ -5,7 +5,7 @@ import debounce from 'lodash/debounce'; import type {MutableRefObject} from 'react'; import React, {useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState} from 'react'; import type {GestureResponderEvent} from 'react-native'; -import {Platform, View} from 'react-native'; +import {View} from 'react-native'; import {runOnJS, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import AttachmentOfflineIndicator from '@components/AttachmentOfflineIndicator'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; @@ -254,15 +254,7 @@ function BaseVideoPlayer({ if (!('isMuted' in status)) { return; } - // updateVolume((value) => { - // const valueToSet = value === 0 ? 0.25 : value; - // console.log("_________________________________________") - // console.log('valueToSet', valueToSet); - // console.log('status', status); - // console.log("_________________________________________") - // - // return status.isMuted ? 0 : status.volume || valueToSet; - // }); + updateVolume(status.isMuted ? 0 : status.volume || 1); }); diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx index 0899a86678eb4..677f90aa5c552 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx @@ -33,7 +33,7 @@ const getVolumeIcon = (volume: number) => { function VolumeButton({style, small = false}: VolumeButtonProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const {updateVolume, volume, previousVolume} = useVolumeContext(); + const {updateVolume, volume, lastNonZeroVolume} = useVolumeContext(); const [sliderHeight, setSliderHeight] = useState(1); const [volumeIcon, setVolumeIcon] = useState({icon: getVolumeIcon(volume.get())}); const [isSliderBeingUsed, setIsSliderBeingUsed] = useState(false); @@ -97,7 +97,7 @@ function VolumeButton({style, small = false}: VolumeButtonProps) { tooltipText={volume.get() === 0 ? translate('videoPlayer.unmute') : translate('videoPlayer.mute')} onPress={() => updateVolume((value) => { - return value === 0 ? previousVolume.get() : 0; + return value === 0 ? lastNonZeroVolume.get() : 0; }) } src={volumeIcon.icon} diff --git a/src/components/VideoPlayerContexts/VolumeContext.tsx b/src/components/VideoPlayerContexts/VolumeContext.tsx index a669990b4adc7..59f0e11ac02ab 100644 --- a/src/components/VideoPlayerContexts/VolumeContext.tsx +++ b/src/components/VideoPlayerContexts/VolumeContext.tsx @@ -9,7 +9,7 @@ const Context = React.createContext(null); function VolumeContextProvider({children}: ChildrenProps) { const {currentVideoPlayerRef, originalParent} = usePlaybackContext(); const volume = useSharedValue(0); - const previousVolume = useSharedValue(1); + const lastNonZeroVolume = useSharedValue(1); const updateVolume = useCallback( (newVolume: number | ((actualValue: number) => number)) => { @@ -25,28 +25,29 @@ function VolumeContextProvider({children}: ChildrenProps) { volume.set((value: number) => { if (value !== 0) { - previousVolume.set(value); + lastNonZeroVolume.set(value); } return volumeValue; }); }, [currentVideoPlayerRef, volume], ); - + // We want to update the volume when currently playing video changes. + // When originalParent changed we're sure that currentVideoPlayerRef is updated. So we can apply the new volume. useEffect(() => { if (!originalParent) { return; } - updateVolume(() => volume.get()); + updateVolume(volume.get()); }, [originalParent, updateVolume, volume]); const contextValue = useMemo( () => ({ updateVolume, volume, - previousVolume, + lastNonZeroVolume, }), - [updateVolume, volume, previousVolume], + [updateVolume, volume, lastNonZeroVolume], ); return {children}; diff --git a/src/components/VideoPlayerContexts/types.ts b/src/components/VideoPlayerContexts/types.ts index d5a77d4e9036d..986fe48ad7431 100644 --- a/src/components/VideoPlayerContexts/types.ts +++ b/src/components/VideoPlayerContexts/types.ts @@ -25,7 +25,7 @@ type PlaybackContext = { type VolumeContext = { updateVolume: (newVolume: number | ((value: number) => number)) => void; volume: SharedValue; - previousVolume: SharedValue; + lastNonZeroVolume: SharedValue; }; type VideoPopoverMenuContext = { From b1199cee4955b0afe716e0fdf06ec1f1ebabc86f Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Wed, 4 Dec 2024 11:04:43 +0100 Subject: [PATCH 4/6] apply Blazej suggestions --- .../VideoPlayerControls/VolumeButton/index.tsx | 13 ++++++++----- .../VideoPlayerContexts/VolumeContext.tsx | 16 +++++----------- src/components/VideoPlayerContexts/types.ts | 2 +- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx index 677f90aa5c552..da9ef21af1eb1 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx @@ -73,6 +73,13 @@ function VolumeButton({style, small = false}: VolumeButtonProps) { runOnJS(updateIcon)(volume.get()); }, [volume]); + const toggleMute = () => { + if (volume.get() !== 0) { + lastNonZeroVolume.set(volume.get()); + } + updateVolume(volume.get() === 0 ? lastNonZeroVolume.get() : 0); + }; + return ( {(isHovered) => ( @@ -95,11 +102,7 @@ function VolumeButton({style, small = false}: VolumeButtonProps) { - updateVolume((value) => { - return value === 0 ? lastNonZeroVolume.get() : 0; - }) - } + onPress={toggleMute} src={volumeIcon.icon} small={small} shouldForceRenderingTooltipBelow diff --git a/src/components/VideoPlayerContexts/VolumeContext.tsx b/src/components/VideoPlayerContexts/VolumeContext.tsx index 59f0e11ac02ab..24769e8889e1d 100644 --- a/src/components/VideoPlayerContexts/VolumeContext.tsx +++ b/src/components/VideoPlayerContexts/VolumeContext.tsx @@ -9,26 +9,20 @@ const Context = React.createContext(null); function VolumeContextProvider({children}: ChildrenProps) { const {currentVideoPlayerRef, originalParent} = usePlaybackContext(); const volume = useSharedValue(0); + // We need this field to remember the last value before clicking mute const lastNonZeroVolume = useSharedValue(1); const updateVolume = useCallback( - (newVolume: number | ((actualValue: number) => number)) => { + (newVolume: number) => { if (!currentVideoPlayerRef.current) { return; } - const volumeValue = typeof newVolume === 'function' ? newVolume(volume.get()) : newVolume; - currentVideoPlayerRef.current.setStatusAsync({ - volume: volumeValue, - isMuted: volumeValue === 0, + volume: newVolume, + isMuted: newVolume === 0, }); - volume.set((value: number) => { - if (value !== 0) { - lastNonZeroVolume.set(value); - } - return volumeValue; - }); + volume.set(newVolume); }, [currentVideoPlayerRef, volume], ); diff --git a/src/components/VideoPlayerContexts/types.ts b/src/components/VideoPlayerContexts/types.ts index 986fe48ad7431..d4bb55fba406c 100644 --- a/src/components/VideoPlayerContexts/types.ts +++ b/src/components/VideoPlayerContexts/types.ts @@ -23,7 +23,7 @@ type PlaybackContext = { }; type VolumeContext = { - updateVolume: (newVolume: number | ((value: number) => number)) => void; + updateVolume: (newVolume: number) => void; volume: SharedValue; lastNonZeroVolume: SharedValue; }; From bb836caf4b3c43e17efb1086a0aebcdd2aea11ff Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Wed, 4 Dec 2024 13:07:18 +0100 Subject: [PATCH 5/6] fix full screen unmute bug --- src/components/VideoPlayer/BaseVideoPlayer.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/VideoPlayer/BaseVideoPlayer.tsx b/src/components/VideoPlayer/BaseVideoPlayer.tsx index 4e7e1dea764ec..e3d52ebf2a351 100644 --- a/src/components/VideoPlayer/BaseVideoPlayer.tsx +++ b/src/components/VideoPlayer/BaseVideoPlayer.tsx @@ -90,7 +90,7 @@ function BaseVideoPlayer({ const isCurrentlyURLSet = currentlyPlayingURL === url; const isUploading = CONST.ATTACHMENT_LOCAL_URL_PREFIX.some((prefix) => url.startsWith(prefix)); const videoStateRef = useRef(null); - const {updateVolume} = useVolumeContext(); + const {updateVolume, lastNonZeroVolume, volume} = useVolumeContext(); const {videoPopoverMenuPlayerRef, currentPlaybackSpeed, setCurrentPlaybackSpeed} = useVideoPopoverMenuContext(); const {source} = videoPopoverMenuPlayerRef.current?.props ?? {}; const shouldUseNewRate = typeof source === 'number' || !source || source.uri !== sourceURL; @@ -187,6 +187,8 @@ function BaseVideoPlayer({ }, [playVideo, videoResumeTryNumberRef], ); + const prevIsMuted = useSharedValue(true); + const prevVolume = useSharedValue(0); const handlePlaybackStatusUpdate = useCallback( (status: AVPlaybackStatus) => { @@ -208,6 +210,16 @@ function BaseVideoPlayer({ setIsEnded(false); } + if (prevIsMuted.get() && prevVolume.get() === 0 && !status.isMuted) { + updateVolume(lastNonZeroVolume.get()); + } + + if (isFullScreenRef.current && prevVolume.get() !== 0 && status.volume === 0 && !status.isMuted) { + currentVideoPlayerRef.current?.setStatusAsync({isMuted: true}); + } + prevIsMuted.set(status.isMuted); + prevVolume.set(status.volume); + const isVideoPlaying = status.isPlaying; // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const currentDuration = status.durationMillis || videoDuration * 1000; @@ -254,7 +266,6 @@ function BaseVideoPlayer({ if (!('isMuted' in status)) { return; } - updateVolume(status.isMuted ? 0 : status.volume || 1); }); From d8c55a8f7dbdabc3a7ddebcc9251caa2412d3d33 Mon Sep 17 00:00:00 2001 From: sumo_slonik Date: Thu, 5 Dec 2024 08:23:29 +0100 Subject: [PATCH 6/6] changes after code review --- .../VideoPlayer/BaseVideoPlayer.tsx | 4 +++- .../VolumeButton/index.tsx | 9 +-------- .../VideoPlayerContexts/VolumeContext.tsx | 19 ++++++++++++++----- src/components/VideoPlayerContexts/types.ts | 1 + 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/components/VideoPlayer/BaseVideoPlayer.tsx b/src/components/VideoPlayer/BaseVideoPlayer.tsx index e3d52ebf2a351..9234dc4521d06 100644 --- a/src/components/VideoPlayer/BaseVideoPlayer.tsx +++ b/src/components/VideoPlayer/BaseVideoPlayer.tsx @@ -90,7 +90,7 @@ function BaseVideoPlayer({ const isCurrentlyURLSet = currentlyPlayingURL === url; const isUploading = CONST.ATTACHMENT_LOCAL_URL_PREFIX.some((prefix) => url.startsWith(prefix)); const videoStateRef = useRef(null); - const {updateVolume, lastNonZeroVolume, volume} = useVolumeContext(); + const {updateVolume, lastNonZeroVolume} = useVolumeContext(); const {videoPopoverMenuPlayerRef, currentPlaybackSpeed, setCurrentPlaybackSpeed} = useVideoPopoverMenuContext(); const {source} = videoPopoverMenuPlayerRef.current?.props ?? {}; const shouldUseNewRate = typeof source === 'number' || !source || source.uri !== sourceURL; @@ -210,6 +210,8 @@ function BaseVideoPlayer({ setIsEnded(false); } + // These two conditions are essential for the mute and unmute functionality to work properly during + // fullscreen playback on the web if (prevIsMuted.get() && prevVolume.get() === 0 && !status.isMuted) { updateVolume(lastNonZeroVolume.get()); } diff --git a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx index da9ef21af1eb1..9b79cf57b6cf3 100644 --- a/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx +++ b/src/components/VideoPlayer/VideoPlayerControls/VolumeButton/index.tsx @@ -33,7 +33,7 @@ const getVolumeIcon = (volume: number) => { function VolumeButton({style, small = false}: VolumeButtonProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const {updateVolume, volume, lastNonZeroVolume} = useVolumeContext(); + const {updateVolume, volume, toggleMute} = useVolumeContext(); const [sliderHeight, setSliderHeight] = useState(1); const [volumeIcon, setVolumeIcon] = useState({icon: getVolumeIcon(volume.get())}); const [isSliderBeingUsed, setIsSliderBeingUsed] = useState(false); @@ -73,13 +73,6 @@ function VolumeButton({style, small = false}: VolumeButtonProps) { runOnJS(updateIcon)(volume.get()); }, [volume]); - const toggleMute = () => { - if (volume.get() !== 0) { - lastNonZeroVolume.set(volume.get()); - } - updateVolume(volume.get() === 0 ? lastNonZeroVolume.get() : 0); - }; - return ( {(isHovered) => ( diff --git a/src/components/VideoPlayerContexts/VolumeContext.tsx b/src/components/VideoPlayerContexts/VolumeContext.tsx index 24769e8889e1d..ec42c1fa78774 100644 --- a/src/components/VideoPlayerContexts/VolumeContext.tsx +++ b/src/components/VideoPlayerContexts/VolumeContext.tsx @@ -17,15 +17,23 @@ function VolumeContextProvider({children}: ChildrenProps) { if (!currentVideoPlayerRef.current) { return; } - currentVideoPlayerRef.current.setStatusAsync({ - volume: newVolume, - isMuted: newVolume === 0, - }); + currentVideoPlayerRef.current.setStatusAsync({volume: newVolume, isMuted: newVolume === 0}); volume.set(newVolume); }, [currentVideoPlayerRef, volume], ); + + // This function ensures mute and unmute functionality. Overwriting lastNonZeroValue + // only in the case of mute guarantees that a pan gesture reducing the volume to zero won’t cause + // us to lose this value. As a result, unmute restores the last non-zero value. + const toggleMute = useCallback(() => { + if (volume.get() !== 0) { + lastNonZeroVolume.set(volume.get()); + } + updateVolume(volume.get() === 0 ? lastNonZeroVolume.get() : 0); + }, [lastNonZeroVolume, updateVolume, volume]); + // We want to update the volume when currently playing video changes. // When originalParent changed we're sure that currentVideoPlayerRef is updated. So we can apply the new volume. useEffect(() => { @@ -40,8 +48,9 @@ function VolumeContextProvider({children}: ChildrenProps) { updateVolume, volume, lastNonZeroVolume, + toggleMute, }), - [updateVolume, volume, lastNonZeroVolume], + [updateVolume, volume, lastNonZeroVolume, toggleMute], ); return {children}; diff --git a/src/components/VideoPlayerContexts/types.ts b/src/components/VideoPlayerContexts/types.ts index d4bb55fba406c..b376e9dd5f146 100644 --- a/src/components/VideoPlayerContexts/types.ts +++ b/src/components/VideoPlayerContexts/types.ts @@ -26,6 +26,7 @@ type VolumeContext = { updateVolume: (newVolume: number) => void; volume: SharedValue; lastNonZeroVolume: SharedValue; + toggleMute: () => void; }; type VideoPopoverMenuContext = {