Fix profile preview jump (#1693)

* Add top inset for profile preview to match target screen

* Avoid flicker by waiting for profile screen navigation

* Fix glimmer to align with the content

* A more reliable (but non-scientific) fix for the flash

* Lower the timeout
This commit is contained in:
dan 2023-10-13 20:10:15 +01:00 committed by GitHub
parent d5ccbd76d5
commit f447eaa669
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 18 deletions

View file

@ -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"