about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Navigation.tsx16
-rw-r--r--src/view/com/modals/Modal.tsx20
-rw-r--r--src/view/com/modals/ProfilePreview.tsx11
-rw-r--r--src/view/com/profile/ProfileHeader.tsx4
4 files changed, 33 insertions, 18 deletions
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
index 97612c9ec..e1d5e76aa 100644
--- a/src/Navigation.tsx
+++ b/src/Navigation.tsx
@@ -483,9 +483,21 @@ function navigate<K extends keyof AllNavigatorParams>(
   params?: AllNavigatorParams[K],
 ) {
   if (navigationRef.isReady()) {
-    // @ts-ignore I dont know what would make typescript happy but I have a life -prf
-    navigationRef.navigate(name, params)
+    return Promise.race([
+      new Promise<void>(resolve => {
+        const handler = () => {
+          resolve()
+          navigationRef.removeListener('state', handler)
+        }
+        navigationRef.addListener('state', handler)
+
+        // @ts-ignore I dont know what would make typescript happy but I have a life -prf
+        navigationRef.navigate(name, params)
+      }),
+      timeout(1e3),
+    ])
   }
+  return Promise.resolve()
 }
 
 function resetToTab(tabName: 'HomeTab' | 'SearchTab' | 'NotificationsTab') {
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx
index 4f3f424a3..1fe1299d7 100644
--- a/src/view/com/modals/Modal.tsx
+++ b/src/view/com/modals/Modal.tsx
@@ -1,11 +1,12 @@
 import React, {useRef, useEffect} from 'react'
 import {StyleSheet} from 'react-native'
-import {SafeAreaView} from 'react-native-safe-area-context'
+import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context'
 import {observer} from 'mobx-react-lite'
 import BottomSheet from '@gorhom/bottom-sheet'
 import {useStores} from 'state/index'
 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'
 
@@ -36,11 +37,13 @@ import * as SwitchAccountModal from './SwitchAccount'
 import * as LinkWarningModal from './LinkWarning'
 
 const DEFAULT_SNAPPOINTS = ['90%']
+const HANDLE_HEIGHT = 24
 
 export const ModalsContainer = observer(function ModalsContainer() {
   const store = useStores()
   const bottomSheetRef = useRef<BottomSheet>(null)
   const pal = usePalette('default')
+  const safeAreaInsets = useSafeAreaInsets()
 
   const activeModal =
     store.shell.activeModals[store.shell.activeModals.length - 1]
@@ -53,12 +56,16 @@ export const ModalsContainer = observer(function ModalsContainer() {
       navigateOnce('Profile', {name: activeModal.did})
     }
   }
-  const onBottomSheetChange = (snapPoint: number) => {
+  const onBottomSheetChange = async (snapPoint: number) => {
     if (snapPoint === -1) {
       store.shell.closeModal()
     } else if (activeModal?.name === 'profile-preview' && snapPoint === 1) {
-      // ensure we navigate to Profile and close the modal
-      navigateOnce('Profile', {name: activeModal.did})
+      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)
       store.shell.closeModal()
     }
   }
@@ -75,6 +82,7 @@ export const ModalsContainer = observer(function ModalsContainer() {
     }
   }, [store.shell.isModalActive, bottomSheetRef, activeModal?.name])
 
+  let needsSafeTopInset = false
   let snapPoints: (string | number)[] = DEFAULT_SNAPPOINTS
   let element
   if (activeModal?.name === 'confirm') {
@@ -86,6 +94,7 @@ export const ModalsContainer = observer(function ModalsContainer() {
   } 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} />
@@ -164,10 +173,13 @@ export const ModalsContainer = observer(function ModalsContainer() {
     )
   }
 
+  const topInset = needsSafeTopInset ? safeAreaInsets.top - HANDLE_HEIGHT : 0
   return (
     <BottomSheet
       ref={bottomSheetRef}
       snapPoints={snapPoints}
+      topInset={topInset}
+      handleHeight={HANDLE_HEIGHT}
       index={store.shell.isModalActive ? 0 : -1}
       enablePanDownToClose
       android_keyboardInputMode="adjustResize"
diff --git a/src/view/com/modals/ProfilePreview.tsx b/src/view/com/modals/ProfilePreview.tsx
index 225a3972b..dad02aa5e 100644
--- a/src/view/com/modals/ProfilePreview.tsx
+++ b/src/view/com/modals/ProfilePreview.tsx
@@ -9,7 +9,6 @@ import {useAnalytics} from 'lib/analytics/analytics'
 import {ProfileHeader} from '../profile/ProfileHeader'
 import {InfoCircleIcon} from 'lib/icons'
 import {useNavigationState} from '@react-navigation/native'
-import {isIOS} from 'platform/detection'
 import {s} from 'lib/styles'
 
 export const snapPoints = [520, '100%']
@@ -36,11 +35,7 @@ export const Component = observer(function ProfilePreviewImpl({
 
   return (
     <View testID="profilePreview" style={[pal.view, s.flex1]}>
-      <View
-        style={[
-          styles.headerWrapper,
-          isLoading && isIOS && styles.headerPositionAdjust,
-        ]}>
+      <View style={[styles.headerWrapper]}>
         <ProfileHeader
           view={model}
           hideBackButton
@@ -70,10 +65,6 @@ const styles = StyleSheet.create({
   headerWrapper: {
     height: 440,
   },
-  headerPositionAdjust: {
-    // HACK align the header for the profilescreen transition -prf
-    paddingTop: 23,
-  },
   hintWrapper: {
     height: 80,
   },
diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx
index baf95af6c..df19ecad5 100644
--- a/src/view/com/profile/ProfileHeader.tsx
+++ b/src/view/com/profile/ProfileHeader.tsx
@@ -60,14 +60,14 @@ export const ProfileHeader = observer(function ProfileHeaderImpl({
   if (!view || !view.hasLoaded) {
     return (
       <View style={pal.view}>
-        <LoadingPlaceholder width="100%" height={120} />
+        <LoadingPlaceholder width="100%" height={153} />
         <View
           style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}>
           <LoadingPlaceholder width={80} height={80} style={styles.br40} />
         </View>
         <View style={styles.content}>
           <View style={[styles.buttonsLine]}>
-            <LoadingPlaceholder width={100} height={31} style={styles.br50} />
+            <LoadingPlaceholder width={167} height={31} style={styles.br50} />
           </View>
           <View>
             <Text type="title-2xl" style={[pal.text, styles.title]}>