about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.native.tsx72
-rw-r--r--src/App.web.tsx75
-rw-r--r--src/view/com/util/post-embeds/VideoEmbedInner/VideoEmbedInnerNative.tsx15
-rw-r--r--src/view/com/util/post-embeds/VideoVolumeContext.tsx32
4 files changed, 116 insertions, 78 deletions
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() {
       <ThemeProvider theme={theme}>
         <Splash isReady={isReady && hasCheckedReferrer}>
           <RootSiblingParent>
-            <React.Fragment
-              // Resets the entire tree below when it changes:
-              key={currentAccount?.did}>
-              <QueryProvider currentDid={currentAccount?.did}>
-                <StatsigProvider>
-                  <MessagesProvider>
-                    {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
-                    <LabelDefsProvider>
-                      <ModerationOptsProvider>
-                        <LoggedOutViewProvider>
-                          <SelectedFeedProvider>
-                            <HiddenRepliesProvider>
-                              <UnreadNotifsProvider>
-                                <BackgroundNotificationPreferencesProvider>
-                                  <MutedThreadsProvider>
-                                    <ProgressGuideProvider>
-                                      <GestureHandlerRootView style={s.h100pct}>
-                                        <TestCtrls />
-                                        <Shell />
-                                        <NuxDialogs />
-                                      </GestureHandlerRootView>
-                                    </ProgressGuideProvider>
-                                  </MutedThreadsProvider>
-                                </BackgroundNotificationPreferencesProvider>
-                              </UnreadNotifsProvider>
-                            </HiddenRepliesProvider>
-                          </SelectedFeedProvider>
-                        </LoggedOutViewProvider>
-                      </ModerationOptsProvider>
-                    </LabelDefsProvider>
-                  </MessagesProvider>
-                </StatsigProvider>
-              </QueryProvider>
-            </React.Fragment>
+            <VideoVolumeProvider>
+              <React.Fragment
+                // Resets the entire tree below when it changes:
+                key={currentAccount?.did}>
+                <QueryProvider currentDid={currentAccount?.did}>
+                  <StatsigProvider>
+                    <MessagesProvider>
+                      {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
+                      <LabelDefsProvider>
+                        <ModerationOptsProvider>
+                          <LoggedOutViewProvider>
+                            <SelectedFeedProvider>
+                              <HiddenRepliesProvider>
+                                <UnreadNotifsProvider>
+                                  <BackgroundNotificationPreferencesProvider>
+                                    <MutedThreadsProvider>
+                                      <ProgressGuideProvider>
+                                        <GestureHandlerRootView
+                                          style={s.h100pct}>
+                                          <TestCtrls />
+                                          <Shell />
+                                          <NuxDialogs />
+                                        </GestureHandlerRootView>
+                                      </ProgressGuideProvider>
+                                    </MutedThreadsProvider>
+                                  </BackgroundNotificationPreferencesProvider>
+                                </UnreadNotifsProvider>
+                              </HiddenRepliesProvider>
+                            </SelectedFeedProvider>
+                          </LoggedOutViewProvider>
+                        </ModerationOptsProvider>
+                      </LabelDefsProvider>
+                    </MessagesProvider>
+                  </StatsigProvider>
+                </QueryProvider>
+              </React.Fragment>
+            </VideoVolumeProvider>
           </RootSiblingParent>
         </Splash>
       </ThemeProvider>
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() {
       <Alf theme={theme}>
         <ThemeProvider theme={theme}>
           <RootSiblingParent>
-            <ActiveVideoProvider>
-              <React.Fragment
-                // Resets the entire tree below when it changes:
-                key={currentAccount?.did}>
-                <QueryProvider currentDid={currentAccount?.did}>
-                  <StatsigProvider>
-                    <MessagesProvider>
-                      {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
-                      <LabelDefsProvider>
-                        <ModerationOptsProvider>
-                          <LoggedOutViewProvider>
-                            <SelectedFeedProvider>
-                              <HiddenRepliesProvider>
-                                <UnreadNotifsProvider>
-                                  <BackgroundNotificationPreferencesProvider>
-                                    <MutedThreadsProvider>
-                                      <SafeAreaProvider>
-                                        <ProgressGuideProvider>
-                                          <Shell />
-                                          <NuxDialogs />
-                                        </ProgressGuideProvider>
-                                      </SafeAreaProvider>
-                                    </MutedThreadsProvider>
-                                  </BackgroundNotificationPreferencesProvider>
-                                </UnreadNotifsProvider>
-                              </HiddenRepliesProvider>
-                            </SelectedFeedProvider>
-                          </LoggedOutViewProvider>
-                        </ModerationOptsProvider>
-                      </LabelDefsProvider>
-                    </MessagesProvider>
-                  </StatsigProvider>
-                </QueryProvider>
-              </React.Fragment>
-              <ToastContainer />
-            </ActiveVideoProvider>
+            <VideoVolumeProvider>
+              <ActiveVideoProvider>
+                <React.Fragment
+                  // Resets the entire tree below when it changes:
+                  key={currentAccount?.did}>
+                  <QueryProvider currentDid={currentAccount?.did}>
+                    <StatsigProvider>
+                      <MessagesProvider>
+                        {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
+                        <LabelDefsProvider>
+                          <ModerationOptsProvider>
+                            <LoggedOutViewProvider>
+                              <SelectedFeedProvider>
+                                <HiddenRepliesProvider>
+                                  <UnreadNotifsProvider>
+                                    <BackgroundNotificationPreferencesProvider>
+                                      <MutedThreadsProvider>
+                                        <SafeAreaProvider>
+                                          <ProgressGuideProvider>
+                                            <Shell />
+                                            <NuxDialogs />
+                                          </ProgressGuideProvider>
+                                        </SafeAreaProvider>
+                                      </MutedThreadsProvider>
+                                    </BackgroundNotificationPreferencesProvider>
+                                  </UnreadNotifsProvider>
+                                </HiddenRepliesProvider>
+                              </SelectedFeedProvider>
+                            </LoggedOutViewProvider>
+                          </ModerationOptsProvider>
+                        </LabelDefsProvider>
+                      </MessagesProvider>
+                    </StatsigProvider>
+                  </QueryProvider>
+                </React.Fragment>
+                <ToastContainer />
+              </ActiveVideoProvider>
+            </VideoVolumeProvider>
           </RootSiblingParent>
         </ThemeProvider>
       </Alf>
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<BlueskyVideoView>(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<string>()
@@ -66,7 +67,7 @@ export const VideoEmbedInnerNative = React.forwardRef(
         <BlueskyVideoView
           url={embed.playlist}
           autoplay={!autoplayDisabled && !isWithinMessage}
-          beginMuted={true}
+          beginMuted={autoplayDisabled ? false : muted}
           style={[a.rounded_sm]}
           onActiveChange={e => {
             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({
 
       <ControlButton
         onPress={toggleMuted}
-        label={isMuted ? _(msg`Unmute`) : _(msg`Mute`)}
+        label={muted ? _(msg`Unmute`) : _(msg`Mute`)}
         accessibilityHint={_(msg`Tap to toggle sound`)}
         style={{right: 6}}>
-        {isMuted ? (
+        {muted ? (
           <MuteIcon width={13} fill={t.palette.white} />
         ) : (
           <UnmuteIcon width={13} fill={t.palette.white} />
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 <Context.Provider value={value}>{children}</Context.Provider>
+}
+
+export function useVideoVolumeState() {
+  const context = React.useContext(Context)
+  if (!context) {
+    throw new Error(
+      'useVideoVolumeState must be used within a VideoVolumeProvider',
+    )
+  }
+  return context
+}