about summary refs log tree commit diff
path: root/src/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens')
-rw-r--r--src/screens/Messages/ChatList.tsx15
-rw-r--r--src/screens/Messages/Conversation.tsx61
-rw-r--r--src/screens/Messages/components/RequestButtons.tsx34
-rw-r--r--src/screens/Messages/components/RequestListItem.tsx2
-rw-r--r--src/screens/Profile/ProfileFeed/index.tsx21
-rw-r--r--src/screens/Settings/AccountSettings.tsx33
-rw-r--r--src/screens/Settings/components/Email2FAToggle.tsx65
-rw-r--r--src/screens/VideoFeed/index.tsx40
8 files changed, 150 insertions, 121 deletions
diff --git a/src/screens/Messages/ChatList.tsx b/src/screens/Messages/ChatList.tsx
index 2846ed828..9fd54f1b0 100644
--- a/src/screens/Messages/ChatList.tsx
+++ b/src/screens/Messages/ChatList.tsx
@@ -9,6 +9,7 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
 
 import {useAppState} from '#/lib/hooks/useAppState'
 import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
+import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
 import {type MessagesTabNavigatorParams} from '#/lib/routes/types'
 import {cleanError} from '#/lib/strings/errors'
 import {logger} from '#/logger'
@@ -321,6 +322,18 @@ export function MessagesScreen({navigation, route}: Props) {
 function Header({newChatControl}: {newChatControl: DialogControlProps}) {
   const {_} = useLingui()
   const {gtMobile} = useBreakpoints()
+  const requireEmailVerification = useRequireEmailVerification()
+
+  const openChatControl = useCallback(() => {
+    newChatControl.open()
+  }, [newChatControl])
+  const wrappedOpenChatControl = requireEmailVerification(openChatControl, {
+    instructions: [
+      <Trans key="new-chat">
+        Before you can message another user, you must first verify your email.
+      </Trans>,
+    ],
+  })
 
   const settingsLink = (
     <Link
@@ -352,7 +365,7 @@ function Header({newChatControl}: {newChatControl: DialogControlProps}) {
               color="primary"
               size="small"
               variant="solid"
-              onPress={newChatControl.open}>
+              onPress={wrappedOpenChatControl}>
               <ButtonIcon icon={PlusIcon} position="left" />
               <ButtonText>
                 <Trans>New chat</Trans>
diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx
index 2222084ce..90547a8d4 100644
--- a/src/screens/Messages/Conversation.tsx
+++ b/src/screens/Messages/Conversation.tsx
@@ -1,11 +1,11 @@
-import React, {useCallback} from 'react'
+import React, {useCallback, useEffect} from 'react'
 import {View} from 'react-native'
 import {
   type AppBskyActorDefs,
   moderateProfile,
   type ModerationDecision,
 } from '@atproto/api'
-import {msg} from '@lingui/macro'
+import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {
   type RouteProp,
@@ -17,6 +17,7 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
 
 import {useEmail} from '#/lib/hooks/useEmail'
 import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
+import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
 import {
   type CommonNavigatorParams,
   type NavigationProp,
@@ -31,8 +32,10 @@ import {useProfileQuery} from '#/state/queries/profile'
 import {useSetMinimalShellMode} from '#/state/shell'
 import {MessagesList} from '#/screens/Messages/components/MessagesList'
 import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
-import {useDialogControl} from '#/components/Dialog'
-import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog'
+import {
+  EmailDialogScreenID,
+  useEmailDialogControl,
+} from '#/components/dialogs/EmailDialog'
 import {MessagesListBlockedFooter} from '#/components/dms/MessagesListBlockedFooter'
 import {MessagesListHeader} from '#/components/dms/MessagesListHeader'
 import {Error} from '#/components/Error'
@@ -183,19 +186,50 @@ function InnerReady({
   hasScrolled: boolean
   setHasScrolled: React.Dispatch<React.SetStateAction<boolean>>
 }) {
-  const {_} = useLingui()
   const convoState = useConvo()
   const navigation = useNavigation<NavigationProp>()
   const {params} =
     useRoute<RouteProp<CommonNavigatorParams, 'MessagesConversation'>>()
-  const verifyEmailControl = useDialogControl()
   const {needsEmailVerification} = useEmail()
+  const emailDialogControl = useEmailDialogControl()
 
-  React.useEffect(() => {
+  /**
+   * Must be non-reactive, otherwise the update to open the global dialog will
+   * cause a re-render loop.
+   */
+  const maybeBlockForEmailVerification = useNonReactiveCallback(() => {
     if (needsEmailVerification) {
-      verifyEmailControl.open()
+      /*
+       * HACKFIX
+       *
+       * Load bearing timeout, to bump this state update until the after the
+       * `navigator.addListener('state')` handler closes elements from
+       * `shell/index.*.tsx`  - sfn & esb
+       */
+      setTimeout(() =>
+        emailDialogControl.open({
+          id: EmailDialogScreenID.Verify,
+          instructions: [
+            <Trans key="pre-compose">
+              Before you can message another user, you must first verify your
+              email.
+            </Trans>,
+          ],
+          onCloseWithoutVerifying: () => {
+            if (navigation.canGoBack()) {
+              navigation.goBack()
+            } else {
+              navigation.navigate('Messages', {animation: 'pop'})
+            }
+          },
+        }),
+      )
     }
-  }, [needsEmailVerification, verifyEmailControl])
+  })
+
+  useEffect(() => {
+    maybeBlockForEmailVerification()
+  }, [maybeBlockForEmailVerification])
 
   return (
     <>
@@ -216,15 +250,6 @@ function InnerReady({
           }
         />
       )}
-      <VerifyEmailDialog
-        reasonText={_(
-          msg`Before you may message another user, you must first verify your email.`,
-        )}
-        control={verifyEmailControl}
-        onCloseWithoutVerifying={() => {
-          navigation.navigate('Home')
-        }}
-      />
     </>
   )
 }
diff --git a/src/screens/Messages/components/RequestButtons.tsx b/src/screens/Messages/components/RequestButtons.tsx
index 62db09600..3490bec0d 100644
--- a/src/screens/Messages/components/RequestButtons.tsx
+++ b/src/screens/Messages/components/RequestButtons.tsx
@@ -1,11 +1,12 @@
 import {useCallback} from 'react'
-import {ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
+import {type ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {StackActions, useNavigation} from '@react-navigation/native'
 import {useQueryClient} from '@tanstack/react-query'
 
-import {NavigationProp} from '#/lib/routes/types'
+import {useEmail} from '#/lib/hooks/useEmail'
+import {type NavigationProp} from '#/lib/routes/types'
 import {useProfileShadow} from '#/state/cache/profile-shadow'
 import {useAcceptConversation} from '#/state/queries/messages/accept-conversation'
 import {precacheConvoQuery} from '#/state/queries/messages/conversation'
@@ -13,8 +14,17 @@ import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
 import {useProfileBlockMutationQueue} from '#/state/queries/profile'
 import * as Toast from '#/view/com/util/Toast'
 import {atoms as a} from '#/alf'
-import {Button, ButtonIcon, ButtonProps, ButtonText} from '#/components/Button'
+import {
+  Button,
+  ButtonIcon,
+  type ButtonProps,
+  ButtonText,
+} from '#/components/Button'
 import {useDialogControl} from '#/components/Dialog'
+import {
+  EmailDialogScreenID,
+  useEmailDialogControl,
+} from '#/components/dialogs/EmailDialog'
 import {ReportDialog} from '#/components/dms/ReportDialog'
 import {CircleX_Stroke2_Corner0_Rounded} from '#/components/icons/CircleX'
 import {Flag_Stroke2_Corner0_Rounded as FlagIcon} from '#/components/icons/Flag'
@@ -186,6 +196,8 @@ export function AcceptChatButton({
   const {_} = useLingui()
   const queryClient = useQueryClient()
   const navigation = useNavigation<NavigationProp>()
+  const {needsEmailVerification} = useEmail()
+  const emailDialogControl = useEmailDialogControl()
 
   const {mutate: acceptConvo, isPending} = useAcceptConversation(convo.id, {
     onMutate: () => {
@@ -216,8 +228,20 @@ export function AcceptChatButton({
   })
 
   const onPressAccept = useCallback(() => {
-    acceptConvo()
-  }, [acceptConvo])
+    if (needsEmailVerification) {
+      emailDialogControl.open({
+        id: EmailDialogScreenID.Verify,
+        instructions: [
+          <Trans key="request-btn">
+            Before you can accept this chat request, you must first verify your
+            email.
+          </Trans>,
+        ],
+      })
+    } else {
+      acceptConvo()
+    }
+  }, [acceptConvo, needsEmailVerification, emailDialogControl])
 
   return (
     <Button
diff --git a/src/screens/Messages/components/RequestListItem.tsx b/src/screens/Messages/components/RequestListItem.tsx
index 654691a01..5e09dd2e3 100644
--- a/src/screens/Messages/components/RequestListItem.tsx
+++ b/src/screens/Messages/components/RequestListItem.tsx
@@ -1,5 +1,5 @@
 import {View} from 'react-native'
-import {ChatBskyConvoDefs} from '@atproto/api'
+import {type ChatBskyConvoDefs} from '@atproto/api'
 import {Trans} from '@lingui/macro'
 
 import {useModerationOpts} from '#/state/preferences/moderation-opts'
diff --git a/src/screens/Profile/ProfileFeed/index.tsx b/src/screens/Profile/ProfileFeed/index.tsx
index 3f517d334..2f4b87015 100644
--- a/src/screens/Profile/ProfileFeed/index.tsx
+++ b/src/screens/Profile/ProfileFeed/index.tsx
@@ -5,36 +5,39 @@ import {AppBskyFeedDefs} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useIsFocused, useNavigation} from '@react-navigation/native'
-import {NativeStackScreenProps} from '@react-navigation/native-stack'
+import {type NativeStackScreenProps} from '@react-navigation/native-stack'
 import {useQueryClient} from '@tanstack/react-query'
 
 import {VIDEO_FEED_URIS} from '#/lib/constants'
+import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
 import {usePalette} from '#/lib/hooks/usePalette'
 import {useSetTitle} from '#/lib/hooks/useSetTitle'
 import {ComposeIcon2} from '#/lib/icons'
-import {CommonNavigatorParams} from '#/lib/routes/types'
-import {NavigationProp} from '#/lib/routes/types'
+import {type CommonNavigatorParams} from '#/lib/routes/types'
+import {type NavigationProp} from '#/lib/routes/types'
 import {makeRecordUri} from '#/lib/strings/url-helpers'
 import {s} from '#/lib/styles'
 import {isNative} from '#/platform/detection'
 import {listenSoftReset} from '#/state/events'
 import {FeedFeedbackProvider, useFeedFeedback} from '#/state/feed-feedback'
-import {FeedSourceFeedInfo, useFeedSourceInfoQuery} from '#/state/queries/feed'
-import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
+import {
+  type FeedSourceFeedInfo,
+  useFeedSourceInfoQuery,
+} from '#/state/queries/feed'
+import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed'
 import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
 import {
   usePreferencesQuery,
-  UsePreferencesQueryResponse,
+  type UsePreferencesQueryResponse,
 } from '#/state/queries/preferences'
 import {useResolveUriQuery} from '#/state/queries/resolve-uri'
 import {truncateAndInvalidate} from '#/state/queries/util'
 import {useSession} from '#/state/session'
-import {useComposerControls} from '#/state/shell/composer'
 import {PostFeed} from '#/view/com/posts/PostFeed'
 import {EmptyState} from '#/view/com/util/EmptyState'
 import {FAB} from '#/view/com/util/fab/FAB'
 import {Button} from '#/view/com/util/forms/Button'
-import {ListRef} from '#/view/com/util/List'
+import {type ListRef} from '#/view/com/util/List'
 import {LoadLatestBtn} from '#/view/com/util/load-latest/LoadLatestBtn'
 import {PostFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
 import {Text} from '#/view/com/util/text/Text'
@@ -156,7 +159,7 @@ export function ProfileFeedScreenInner({
 }) {
   const {_} = useLingui()
   const {hasSession} = useSession()
-  const {openComposer} = useComposerControls()
+  const {openComposer} = useOpenComposer()
   const isScreenFocused = useIsFocused()
 
   useSetTitle(feedInfo?.displayName)
diff --git a/src/screens/Settings/AccountSettings.tsx b/src/screens/Settings/AccountSettings.tsx
index 7c50bd8df..393bad2f8 100644
--- a/src/screens/Settings/AccountSettings.tsx
+++ b/src/screens/Settings/AccountSettings.tsx
@@ -9,8 +9,10 @@ import * as SettingsList from '#/screens/Settings/components/SettingsList'
 import {atoms as a, useTheme} from '#/alf'
 import {useDialogControl} from '#/components/Dialog'
 import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings'
-import {ChangeEmailDialog} from '#/components/dialogs/ChangeEmailDialog'
-import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog'
+import {
+  EmailDialogScreenID,
+  useEmailDialogControl,
+} from '#/components/dialogs/EmailDialog'
 import {At_Stroke2_Corner2_Rounded as AtIcon} from '#/components/icons/At'
 import {BirthdayCake_Stroke2_Corner2_Rounded as BirthdayCakeIcon} from '#/components/icons/BirthdayCake'
 import {Car_Stroke2_Corner2_Rounded as CarIcon} from '#/components/icons/Car'
@@ -31,8 +33,7 @@ export function AccountSettingsScreen({}: Props) {
   const {_} = useLingui()
   const {currentAccount} = useSession()
   const {openModal} = useModalControls()
-  const verifyEmailControl = useDialogControl()
-  const changeEmailControl = useDialogControl()
+  const emailDialogControl = useEmailDialogControl()
   const birthdayControl = useDialogControl()
   const changeHandleControl = useDialogControl()
   const exportCarControl = useDialogControl()
@@ -75,7 +76,11 @@ export function AccountSettingsScreen({}: Props) {
           {currentAccount && !currentAccount.emailConfirmed && (
             <SettingsList.PressableItem
               label={_(msg`Verify your email`)}
-              onPress={() => verifyEmailControl.open()}
+              onPress={() =>
+                emailDialogControl.open({
+                  id: EmailDialogScreenID.Verify,
+                })
+              }
               style={[
                 a.my_xs,
                 a.mx_lg,
@@ -96,11 +101,15 @@ export function AccountSettingsScreen({}: Props) {
             </SettingsList.PressableItem>
           )}
           <SettingsList.PressableItem
-            label={_(msg`Change email`)}
-            onPress={() => changeEmailControl.open()}>
+            label={_(msg`Update email`)}
+            onPress={() =>
+              emailDialogControl.open({
+                id: EmailDialogScreenID.Update,
+              })
+            }>
             <SettingsList.ItemIcon icon={PencilIcon} />
             <SettingsList.ItemText>
-              <Trans>Change email</Trans>
+              <Trans>Update email</Trans>
             </SettingsList.ItemText>
             <SettingsList.Chevron />
           </SettingsList.PressableItem>
@@ -167,14 +176,6 @@ export function AccountSettingsScreen({}: Props) {
         </SettingsList.Container>
       </Layout.Content>
 
-      <ChangeEmailDialog
-        control={changeEmailControl}
-        verifyEmailControl={verifyEmailControl}
-      />
-      <VerifyEmailDialog
-        control={verifyEmailControl}
-        changeEmailControl={changeEmailControl}
-      />
       <BirthDateSettingsDialog control={birthdayControl} />
       <ChangeHandleDialog control={changeHandleControl} />
       <ExportCarDialog control={exportCarControl} />
diff --git a/src/screens/Settings/components/Email2FAToggle.tsx b/src/screens/Settings/components/Email2FAToggle.tsx
index 3e341cd73..584026298 100644
--- a/src/screens/Settings/components/Email2FAToggle.tsx
+++ b/src/screens/Settings/components/Email2FAToggle.tsx
@@ -2,11 +2,12 @@ import React from 'react'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 
-import {useAgent, useSession} from '#/state/session'
+import {useSession} from '#/state/session'
 import {useDialogControl} from '#/components/Dialog'
-import {ChangeEmailDialog} from '#/components/dialogs/ChangeEmailDialog'
-import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog'
-import * as Prompt from '#/components/Prompt'
+import {
+  EmailDialogScreenID,
+  useEmailDialogControl,
+} from '#/components/dialogs/EmailDialog'
 import {DisableEmail2FADialog} from './DisableEmail2FADialog'
 import * as SettingsList from './SettingsList'
 
@@ -14,63 +15,17 @@ export function Email2FAToggle() {
   const {_} = useLingui()
   const {currentAccount} = useSession()
   const disableDialogControl = useDialogControl()
-  const enableDialogControl = useDialogControl()
-  const verifyEmailDialogControl = useDialogControl()
-  const changeEmailDialogControl = useDialogControl()
-  const agent = useAgent()
-
-  const enableEmailAuthFactor = React.useCallback(async () => {
-    if (currentAccount?.email) {
-      await agent.com.atproto.server.updateEmail({
-        email: currentAccount.email,
-        emailAuthFactor: true,
-      })
-      await agent.resumeSession(agent.session!)
-    }
-  }, [currentAccount, agent])
+  const emailDialogControl = useEmailDialogControl()
 
   const onToggle = React.useCallback(() => {
-    if (!currentAccount) {
-      return
-    }
-    if (currentAccount.emailAuthFactor) {
-      disableDialogControl.open()
-    } else {
-      if (!currentAccount.emailConfirmed) {
-        verifyEmailDialogControl.open()
-        return
-      }
-      enableDialogControl.open()
-    }
-  }, [
-    currentAccount,
-    enableDialogControl,
-    verifyEmailDialogControl,
-    disableDialogControl,
-  ])
+    emailDialogControl.open({
+      id: EmailDialogScreenID.Manage2FA,
+    })
+  }, [emailDialogControl])
 
   return (
     <>
       <DisableEmail2FADialog control={disableDialogControl} />
-      <Prompt.Basic
-        control={enableDialogControl}
-        title={_(msg`Enable Email 2FA`)}
-        description={_(msg`Require an email code to sign in to your account.`)}
-        onConfirm={enableEmailAuthFactor}
-        confirmButtonCta={_(msg`Enable`)}
-      />
-      <VerifyEmailDialog
-        control={verifyEmailDialogControl}
-        changeEmailControl={changeEmailDialogControl}
-        onCloseAfterVerifying={enableDialogControl.open}
-        reasonText={_(
-          msg`You need to verify your email address before you can enable email 2FA.`,
-        )}
-      />
-      <ChangeEmailDialog
-        control={changeEmailDialogControl}
-        verifyEmailControl={verifyEmailDialogControl}
-      />
       <SettingsList.BadgeButton
         label={
           currentAccount?.emailAuthFactor ? _(msg`Change`) : _(msg`Enable`)
diff --git a/src/screens/VideoFeed/index.tsx b/src/screens/VideoFeed/index.tsx
index 344b93429..aabfe4b20 100644
--- a/src/screens/VideoFeed/index.tsx
+++ b/src/screens/VideoFeed/index.tsx
@@ -1,18 +1,18 @@
 import {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'
 import {
   LayoutAnimation,
-  ListRenderItem,
+  type ListRenderItem,
   Pressable,
   ScrollView,
   View,
-  ViewabilityConfig,
-  ViewToken,
+  type ViewabilityConfig,
+  type ViewToken,
 } from 'react-native'
 import {SystemBars} from 'react-native-edge-to-edge'
 import {
   Gesture,
   GestureDetector,
-  NativeGesture,
+  type NativeGesture,
 } from 'react-native-gesture-handler'
 import Animated, {
   useAnimatedStyle,
@@ -24,38 +24,46 @@ import {
 } from 'react-native-safe-area-context'
 import {useEvent} from 'expo'
 import {useEventListener} from 'expo'
-import {Image, ImageStyle} from 'expo-image'
+import {Image, type ImageStyle} from 'expo-image'
 import {LinearGradient} from 'expo-linear-gradient'
-import {createVideoPlayer, VideoPlayer, VideoView} from 'expo-video'
+import {createVideoPlayer, type VideoPlayer, VideoView} from 'expo-video'
 import {
   AppBskyEmbedVideo,
-  AppBskyFeedDefs,
+  type AppBskyFeedDefs,
   AppBskyFeedPost,
   AtUri,
-  ModerationDecision,
+  type ModerationDecision,
   RichText as RichTextAPI,
 } from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {
-  RouteProp,
+  type RouteProp,
   useFocusEffect,
   useIsFocused,
   useNavigation,
   useRoute,
 } from '@react-navigation/native'
-import {NativeStackScreenProps} from '@react-navigation/native-stack'
+import {type NativeStackScreenProps} from '@react-navigation/native-stack'
 
 import {HITSLOP_20} from '#/lib/constants'
 import {useHaptics} from '#/lib/haptics'
 import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
-import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
+import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
+import {
+  type CommonNavigatorParams,
+  type NavigationProp,
+} from '#/lib/routes/types'
 import {sanitizeDisplayName} from '#/lib/strings/display-names'
 import {cleanError} from '#/lib/strings/errors'
 import {sanitizeHandle} from '#/lib/strings/handles'
 import {isAndroid} from '#/platform/detection'
 import {useA11y} from '#/state/a11y'
-import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow'
+import {
+  POST_TOMBSTONE,
+  type Shadow,
+  usePostShadow,
+} from '#/state/cache/post-shadow'
 import {useProfileShadow} from '#/state/cache/profile-shadow'
 import {
   FeedFeedbackProvider,
@@ -64,13 +72,13 @@ import {
 import {useFeedFeedback} from '#/state/feed-feedback'
 import {usePostLikeMutationQueue} from '#/state/queries/post'
 import {
-  AuthorFilter,
-  FeedPostSliceItem,
+  type AuthorFilter,
+  type FeedPostSliceItem,
   usePostFeedQuery,
 } from '#/state/queries/post-feed'
 import {useProfileFollowMutationQueue} from '#/state/queries/profile'
 import {useSession} from '#/state/session'
-import {useComposerControls, useSetMinimalShellMode} from '#/state/shell'
+import {useSetMinimalShellMode} from '#/state/shell'
 import {useSetLightStatusBar} from '#/state/shell/light-status-bar'
 import {PostThreadComposePrompt} from '#/view/com/post-thread/PostThreadComposePrompt'
 import {List} from '#/view/com/util/List'
@@ -685,7 +693,7 @@ function Overlay({
 }) {
   const {_} = useLingui()
   const t = useTheme()
-  const {openComposer} = useComposerControls()
+  const {openComposer} = useOpenComposer()
   const {currentAccount} = useSession()
   const navigation = useNavigation<NavigationProp>()
   const seekingAnimationSV = useSharedValue(0)