From 843f9925f5d0773db321e617c1bd0be6a308ef7f Mon Sep 17 00:00:00 2001 From: Hailey Date: Fri, 13 Sep 2024 14:07:13 -0700 Subject: [Video] Remember mute state while scrolling (#5331) --- src/App.native.tsx | 72 +++++++++++---------- src/App.web.tsx | 75 +++++++++++----------- .../VideoEmbedInner/VideoEmbedInnerNative.tsx | 15 ++--- .../com/util/post-embeds/VideoVolumeContext.tsx | 32 +++++++++ 4 files changed, 116 insertions(+), 78 deletions(-) create mode 100644 src/view/com/util/post-embeds/VideoVolumeContext.tsx (limited to 'src') diff --git a/src/App.native.tsx b/src/App.native.tsx index 04fea126c..2ec666e2c 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -52,6 +52,7 @@ import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed' import {Provider as StarterPackProvider} from '#/state/shell/starter-pack' import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies' import {TestCtrls} from '#/view/com/testing/TestCtrls' +import {Provider as VideoVolumeProvider} from '#/view/com/util/post-embeds/VideoVolumeContext' import * as Toast from '#/view/com/util/Toast' import {Shell} from '#/view/shell' import {ThemeProvider as Alf} from '#/alf' @@ -109,40 +110,43 @@ function InnerApp() { - - - - - {/* LabelDefsProvider MUST come before ModerationOptsProvider */} - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + {/* LabelDefsProvider MUST come before ModerationOptsProvider */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/App.web.tsx b/src/App.web.tsx index ff9944fa4..bef320826 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -41,6 +41,7 @@ import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed' import {Provider as StarterPackProvider} from '#/state/shell/starter-pack' import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies' import {Provider as ActiveVideoProvider} from '#/view/com/util/post-embeds/ActiveVideoWebContext' +import {Provider as VideoVolumeProvider} from '#/view/com/util/post-embeds/VideoVolumeContext' import * as Toast from '#/view/com/util/Toast' import {ToastContainer} from '#/view/com/util/Toast.web' import {Shell} from '#/view/shell/index' @@ -95,42 +96,44 @@ function InnerApp() { - - - - - - {/* LabelDefsProvider MUST come before ModerationOptsProvider */} - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + {/* LabelDefsProvider MUST come before ModerationOptsProvider */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx index 39ed990ab..ee71daa83 100644 --- a/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx +++ b/src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx @@ -9,6 +9,7 @@ import {useLingui} from '@lingui/react' import {HITSLOP_30} from '#/lib/constants' import {clamp} from '#/lib/numbers' import {useAutoplayDisabled} from '#/state/preferences' +import {useVideoVolumeState} from 'view/com/util/post-embeds/VideoVolumeContext' import {atoms as a, useTheme} from '#/alf' import {useIsWithinMessage} from '#/components/dms/MessageContext' import {Mute_Stroke2_Corner0_Rounded as MuteIcon} from '#/components/icons/Mute' @@ -37,8 +38,8 @@ export const VideoEmbedInnerNative = React.forwardRef( const videoRef = useRef(null) const autoplayDisabled = useAutoplayDisabled() const isWithinMessage = useIsWithinMessage() + const {muted, setMuted} = useVideoVolumeState() - const [isMuted, setIsMuted] = React.useState(true) const [isPlaying, setIsPlaying] = React.useState(false) const [timeRemaining, setTimeRemaining] = React.useState(0) const [error, setError] = React.useState() @@ -66,7 +67,7 @@ export const VideoEmbedInnerNative = React.forwardRef( { setIsActive(e.nativeEvent.isActive) @@ -75,7 +76,7 @@ export const VideoEmbedInnerNative = React.forwardRef( setIsLoading(e.nativeEvent.isLoading) }} onMutedChange={e => { - setIsMuted(e.nativeEvent.isMuted) + setMuted(e.nativeEvent.isMuted) }} onStatusChange={e => { setStatus(e.nativeEvent.status) @@ -103,7 +104,6 @@ export const VideoEmbedInnerNative = React.forwardRef( togglePlayback={() => { videoRef.current?.togglePlayback() }} - isMuted={isMuted} isPlaying={isPlaying} timeRemaining={timeRemaining} /> @@ -119,17 +119,16 @@ function VideoControls({ togglePlayback, timeRemaining, isPlaying, - isMuted, }: { enterFullscreen: () => void toggleMuted: () => void togglePlayback: () => void timeRemaining: number isPlaying: boolean - isMuted: boolean }) { const {_} = useLingui() const t = useTheme() + const {muted} = useVideoVolumeState() // show countdown when: // 1. timeRemaining is a number - was seeing NaNs @@ -161,10 +160,10 @@ function VideoControls({ - {isMuted ? ( + {muted ? ( ) : ( diff --git a/src/view/com/util/post-embeds/VideoVolumeContext.tsx b/src/view/com/util/post-embeds/VideoVolumeContext.tsx new file mode 100644 index 000000000..cccb93ba8 --- /dev/null +++ b/src/view/com/util/post-embeds/VideoVolumeContext.tsx @@ -0,0 +1,32 @@ +import React from 'react' + +const Context = React.createContext( + {} as { + muted: boolean + setMuted: (muted: boolean) => void + }, +) + +export function Provider({children}: {children: React.ReactNode}) { + const [muted, setMuted] = React.useState(true) + + const value = React.useMemo( + () => ({ + muted, + setMuted, + }), + [muted, setMuted], + ) + + return {children} +} + +export function useVideoVolumeState() { + const context = React.useContext(Context) + if (!context) { + throw new Error( + 'useVideoVolumeState must be used within a VideoVolumeProvider', + ) + } + return context +} -- cgit 1.4.1