about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authordan <dan.abramov@gmail.com>2024-02-08 23:41:02 +0000
committerGitHub <noreply@github.com>2024-02-08 23:41:02 +0000
commitd9b62955b5424046b19fe4b8761f820774656f3f (patch)
tree27c4c739462760ef97c61b0a5f75dae829b1c4f9 /src
parent06f81d69486f2e6e8ffd65da5a4bfdcd7d8a2655 (diff)
downloadvoidsky-d9b62955b5424046b19fe4b8761f820774656f3f.tar.zst
Remove Profile Preview modal (#2790)
Diffstat (limited to 'src')
-rw-r--r--src/Navigation.tsx1
-rw-r--r--src/state/modals/index.tsx6
-rw-r--r--src/view/com/modals/Modal.tsx37
-rw-r--r--src/view/com/modals/Modal.web.tsx3
-rw-r--r--src/view/com/modals/ProfilePreview.tsx134
-rw-r--r--src/view/com/util/UserPreviewLink.tsx44
6 files changed, 14 insertions, 211 deletions
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
index 35d8dff74..897d86e40 100644
--- a/src/Navigation.tsx
+++ b/src/Navigation.tsx
@@ -144,7 +144,6 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) {
         getComponent={() => ProfileScreen}
         options={({route}) => ({
           title: bskyTitle(`@${route.params.name}`, unreadCountLabel),
-          animation: 'none',
         })}
       />
       <Stack.Screen
diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx
index e3a4ccd8c..096211bd4 100644
--- a/src/state/modals/index.tsx
+++ b/src/state/modals/index.tsx
@@ -26,11 +26,6 @@ export interface EditProfileModal {
   onUpdate?: () => void
 }
 
-export interface ProfilePreviewModal {
-  name: 'profile-preview'
-  did: string
-}
-
 export interface ServerInputModal {
   name: 'server-input'
   initialService: string
@@ -202,7 +197,6 @@ export type Modal =
   | ChangeHandleModal
   | DeleteAccountModal
   | EditProfileModal
-  | ProfilePreviewModal
   | BirthDateSettingsModal
   | VerifyEmailModal
   | ChangeEmailModal
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx
index 4aa10d75b..decdc6535 100644
--- a/src/view/com/modals/Modal.tsx
+++ b/src/view/com/modals/Modal.tsx
@@ -1,18 +1,13 @@
 import React, {useRef, useEffect} from 'react'
 import {StyleSheet} from 'react-native'
-import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'
+import {SafeAreaView} from 'react-native-safe-area-context'
 import BottomSheet from '@gorhom/bottom-sheet'
 import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop'
 import {usePalette} from 'lib/hooks/usePalette'
-import {timeout} from 'lib/async/timeout'
-import {navigate} from '../../../Navigation'
-import once from 'lodash.once'
 
 import {useModals, useModalControls} from '#/state/modals'
-import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
 import * as ConfirmModal from './Confirm'
 import * as EditProfileModal from './EditProfile'
-import * as ProfilePreviewModal from './ProfilePreview'
 import * as ServerInputModal from './ServerInput'
 import * as RepostModal from './Repost'
 import * as SelfLabelModal from './SelfLabel'
@@ -50,34 +45,14 @@ export function ModalsContainer() {
   const {closeModal} = useModalControls()
   const bottomSheetRef = useRef<BottomSheet>(null)
   const pal = usePalette('default')
-  const safeAreaInsets = useSafeAreaInsets()
-
   const activeModal = activeModals[activeModals.length - 1]
 
-  const navigateOnce = once(navigate)
-
-  // It seems like the bottom sheet bugs out when this callback changes.
-  const onBottomSheetAnimate = useNonReactiveCallback(
-    (_fromIndex: number, toIndex: number) => {
-      if (activeModal?.name === 'profile-preview' && toIndex === 1) {
-        // begin loading the profile screen behind the scenes
-        navigateOnce('Profile', {name: activeModal.did})
-      }
-    },
-  )
   const onBottomSheetChange = async (snapPoint: number) => {
     if (snapPoint === -1) {
       closeModal()
-    } else if (activeModal?.name === 'profile-preview' && snapPoint === 1) {
-      await navigateOnce('Profile', {name: activeModal.did})
-      // There is no particular callback for when the view has actually been presented.
-      // This delay gives us a decent chance the navigation has flushed *and* images have loaded.
-      // It's acceptable because the data is already being fetched + it usually takes longer anyway.
-      // TODO: Figure out why avatar/cover don't always show instantly from cache.
-      await timeout(200)
-      closeModal()
     }
   }
+
   const onClose = () => {
     bottomSheetRef.current?.close()
     closeModal()
@@ -91,7 +66,6 @@ export function ModalsContainer() {
     }
   }, [isModalActive, bottomSheetRef, activeModal?.name])
 
-  let needsSafeTopInset = false
   let snapPoints: (string | number)[] = DEFAULT_SNAPPOINTS
   let element
   if (activeModal?.name === 'confirm') {
@@ -100,10 +74,6 @@ export function ModalsContainer() {
   } else if (activeModal?.name === 'edit-profile') {
     snapPoints = EditProfileModal.snapPoints
     element = <EditProfileModal.Component {...activeModal} />
-  } else if (activeModal?.name === 'profile-preview') {
-    snapPoints = ProfilePreviewModal.snapPoints
-    element = <ProfilePreviewModal.Component {...activeModal} />
-    needsSafeTopInset = true // Need to align with the target profile screen.
   } else if (activeModal?.name === 'server-input') {
     snapPoints = ServerInputModal.snapPoints
     element = <ServerInputModal.Component {...activeModal} />
@@ -200,12 +170,10 @@ export function ModalsContainer() {
     )
   }
 
-  const topInset = needsSafeTopInset ? safeAreaInsets.top - HANDLE_HEIGHT : 0
   return (
     <BottomSheet
       ref={bottomSheetRef}
       snapPoints={snapPoints}
-      topInset={topInset}
       handleHeight={HANDLE_HEIGHT}
       index={isModalActive ? 0 : -1}
       enablePanDownToClose
@@ -216,7 +184,6 @@ export function ModalsContainer() {
       }
       handleIndicatorStyle={{backgroundColor: pal.text.color}}
       handleStyle={[styles.handle, pal.view]}
-      onAnimate={onBottomSheetAnimate}
       onChange={onBottomSheetChange}>
       {element}
     </BottomSheet>
diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx
index 384a4772a..cb6f5bead 100644
--- a/src/view/com/modals/Modal.web.tsx
+++ b/src/view/com/modals/Modal.web.tsx
@@ -9,7 +9,6 @@ import {useModals, useModalControls} from '#/state/modals'
 import type {Modal as ModalIface} from '#/state/modals'
 import * as ConfirmModal from './Confirm'
 import * as EditProfileModal from './EditProfile'
-import * as ProfilePreviewModal from './ProfilePreview'
 import * as ServerInputModal from './ServerInput'
 import * as ReportModal from './report/Modal'
 import * as AppealLabelModal from './AppealLabel'
@@ -85,8 +84,6 @@ function Modal({modal}: {modal: ModalIface}) {
     element = <ConfirmModal.Component {...modal} />
   } else if (modal.name === 'edit-profile') {
     element = <EditProfileModal.Component {...modal} />
-  } else if (modal.name === 'profile-preview') {
-    element = <ProfilePreviewModal.Component {...modal} />
   } else if (modal.name === 'server-input') {
     element = <ServerInputModal.Component {...modal} />
   } else if (modal.name === 'report') {
diff --git a/src/view/com/modals/ProfilePreview.tsx b/src/view/com/modals/ProfilePreview.tsx
deleted file mode 100644
index 1764b6b90..000000000
--- a/src/view/com/modals/ProfilePreview.tsx
+++ /dev/null
@@ -1,134 +0,0 @@
-import React, {useState, useEffect} from 'react'
-import {ActivityIndicator, StyleSheet, View} from 'react-native'
-import {AppBskyActorDefs, ModerationOpts, moderateProfile} from '@atproto/api'
-import {ThemedText} from '../util/text/ThemedText'
-import {usePalette} from 'lib/hooks/usePalette'
-import {useAnalytics} from 'lib/analytics/analytics'
-import {ProfileHeader} from '../profile/ProfileHeader'
-import {InfoCircleIcon} from 'lib/icons'
-import {useNavigationState} from '@react-navigation/native'
-import {s} from 'lib/styles'
-import {useModerationOpts} from '#/state/queries/preferences'
-import {useProfileQuery} from '#/state/queries/profile'
-import {ErrorScreen} from '../util/error/ErrorScreen'
-import {CenteredView} from '../util/Views'
-import {cleanError} from '#/lib/strings/errors'
-import {useProfileShadow} from '#/state/cache/profile-shadow'
-import {Trans, msg} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-
-export const snapPoints = [520, '100%']
-
-export function Component({did}: {did: string}) {
-  const pal = usePalette('default')
-  const {_} = useLingui()
-  const moderationOpts = useModerationOpts()
-  const {
-    data: profile,
-    error: profileError,
-    refetch: refetchProfile,
-    isLoading: isLoadingProfile,
-  } = useProfileQuery({
-    did: did,
-  })
-
-  if (isLoadingProfile || !moderationOpts) {
-    return (
-      <CenteredView style={[pal.view, s.flex1]}>
-        <ProfileHeader
-          profile={null}
-          moderation={null}
-          isProfilePreview={true}
-        />
-      </CenteredView>
-    )
-  }
-  if (profileError) {
-    return (
-      <ErrorScreen
-        title={_(msg`Not Found`)}
-        message={cleanError(profileError)}
-        onPressTryAgain={refetchProfile}
-      />
-    )
-  }
-  if (profile && moderationOpts) {
-    return <ComponentLoaded profile={profile} moderationOpts={moderationOpts} />
-  }
-  // should never happen
-  return (
-    <ErrorScreen
-      title={_(msg`Oops!`)}
-      message={_(msg`Something went wrong and we're not sure what.`)}
-      onPressTryAgain={refetchProfile}
-    />
-  )
-}
-
-function ComponentLoaded({
-  profile: profileUnshadowed,
-  moderationOpts,
-}: {
-  profile: AppBskyActorDefs.ProfileViewDetailed
-  moderationOpts: ModerationOpts
-}) {
-  const pal = usePalette('default')
-  const profile = useProfileShadow(profileUnshadowed)
-  const {screen} = useAnalytics()
-  const moderation = React.useMemo(
-    () => moderateProfile(profile, moderationOpts),
-    [profile, moderationOpts],
-  )
-
-  // track the navigator state to detect if a page-load occurred
-  const navState = useNavigationState(state => state)
-  const [initNavState] = useState(navState)
-  const isLoading = initNavState !== navState
-
-  useEffect(() => {
-    screen('Profile:Preview')
-  }, [screen])
-
-  return (
-    <View testID="profilePreview" style={[pal.view, s.flex1]}>
-      <View style={[styles.headerWrapper]}>
-        <ProfileHeader
-          profile={profile}
-          moderation={moderation}
-          hideBackButton
-          isProfilePreview
-        />
-      </View>
-      <View style={[styles.hintWrapper, pal.view]}>
-        <View style={styles.hint}>
-          {isLoading ? (
-            <ActivityIndicator />
-          ) : (
-            <>
-              <InfoCircleIcon size={21} style={pal.textLight} />
-              <ThemedText type="xl" fg="light">
-                <Trans>Swipe up to see more</Trans>
-              </ThemedText>
-            </>
-          )}
-        </View>
-      </View>
-    </View>
-  )
-}
-
-const styles = StyleSheet.create({
-  headerWrapper: {
-    height: 440,
-  },
-  hintWrapper: {
-    height: 80,
-  },
-  hint: {
-    flexDirection: 'row',
-    justifyContent: 'center',
-    gap: 8,
-    paddingHorizontal: 14,
-    borderRadius: 6,
-  },
-})
diff --git a/src/view/com/util/UserPreviewLink.tsx b/src/view/com/util/UserPreviewLink.tsx
index 2f257bb5e..a2c46afc0 100644
--- a/src/view/com/util/UserPreviewLink.tsx
+++ b/src/view/com/util/UserPreviewLink.tsx
@@ -1,9 +1,8 @@
 import React from 'react'
-import {Pressable, StyleProp, ViewStyle} from 'react-native'
+import {StyleProp, ViewStyle} from 'react-native'
 import {Link} from './Link'
-import {isAndroid, isWeb} from 'platform/detection'
+import {isWeb} from 'platform/detection'
 import {makeProfileLink} from 'lib/routes/links'
-import {useModalControls} from '#/state/modals'
 import {usePrefetchProfileQuery} from '#/state/queries/profile'
 
 interface UserPreviewLinkProps {
@@ -14,38 +13,19 @@ interface UserPreviewLinkProps {
 export function UserPreviewLink(
   props: React.PropsWithChildren<UserPreviewLinkProps>,
 ) {
-  const {openModal} = useModalControls()
   const prefetchProfileQuery = usePrefetchProfileQuery()
-
-  if (isWeb || isAndroid) {
-    return (
-      <Link
-        onPointerEnter={() => {
-          if (isWeb) {
-            prefetchProfileQuery(props.did)
-          }
-        }}
-        href={makeProfileLink(props)}
-        title={props.handle}
-        asAnchor
-        style={props.style}>
-        {props.children}
-      </Link>
-    )
-  }
   return (
-    <Pressable
-      onPress={() =>
-        openModal({
-          name: 'profile-preview',
-          did: props.did,
-        })
-      }
-      accessibilityRole="button"
-      accessibilityLabel={props.handle}
-      accessibilityHint=""
+    <Link
+      onPointerEnter={() => {
+        if (isWeb) {
+          prefetchProfileQuery(props.did)
+        }
+      }}
+      href={makeProfileLink(props)}
+      title={props.handle}
+      asAnchor
       style={props.style}>
       {props.children}
-    </Pressable>
+    </Link>
   )
 }