Use Reanimated layout animations for Android composer (#8546)

This commit is contained in:
Samuel Newman
2026-06-05 00:37:42 +03:00
committed by GitHub
parent 144ba30ea6
commit f84c85aac6
5 changed files with 38 additions and 50 deletions
+12 -11
View File
@@ -1,29 +1,30 @@
import {useEffect, useRef} from 'react'
import {useEffect} from 'react'
import {Modal, View} from 'react-native'
import {SystemBars} from 'react-native-edge-to-edge'
import {useDialogStateControlContext} from '#/state/dialogs'
import {useComposerState} from '#/state/shell/composer'
import {ComposePost, useComposerCancelRef} from '#/view/com/composer/Composer'
import {atoms as a, useTheme} from '#/alf'
import {SheetCompatProvider as TooltipSheetCompatProvider} from '#/components/Tooltip'
import {IS_LIQUID_GLASS} from '#/env'
export function Composer({}: {winHeight: number}) {
const {setFullyExpandedCount} = useDialogStateControlContext()
export function Composer() {
const t = useTheme()
const state = useComposerState()
const ref = useComposerCancelRef()
const open = !!state
const prevOpen = useRef(open)
useEffect(() => {
if (open && !prevOpen.current) {
setFullyExpandedCount(c => c + 1)
} else if (!open && prevOpen.current) {
setFullyExpandedCount(c => c - 1)
if (open && !IS_LIQUID_GLASS) {
const entry = SystemBars.pushStackEntry({
style: {
statusBar: 'light',
},
})
return () => SystemBars.popStackEntry(entry)
}
prevOpen.current = open
}, [open, setFullyExpandedCount])
}, [open])
return (
<Modal
+22 -30
View File
@@ -1,49 +1,41 @@
import {useEffect} from 'react'
import {Animated, Easing} from 'react-native'
import {SystemBars} from 'react-native-edge-to-edge'
import Animated, {
Easing,
SlideInDown,
SlideOutDown,
} from 'react-native-reanimated'
import {useAnimatedValue} from '#/lib/hooks/useAnimatedValue'
import {useComposerState} from '#/state/shell/composer'
import {ComposePost} from '#/view/com/composer/Composer'
import {atoms as a, useTheme} from '#/alf'
import {ComposePost} from '../com/composer/Composer'
export function Composer({winHeight}: {winHeight: number}) {
export function Composer() {
const state = useComposerState()
const t = useTheme()
const initInterp = useAnimatedValue(0)
const open = !!state
useEffect(() => {
if (state) {
Animated.timing(initInterp, {
toValue: 1,
duration: 300,
easing: Easing.out(Easing.exp),
useNativeDriver: true,
}).start()
} else {
initInterp.setValue(0)
if (open) {
const entry = SystemBars.pushStackEntry({
style: {
statusBar: t.name !== 'light' ? 'light' : 'dark',
},
})
return () => SystemBars.popStackEntry(entry)
}
}, [initInterp, state])
const wrapperAnimStyle = {
transform: [
{
translateY: initInterp.interpolate({
inputRange: [0, 1],
outputRange: [winHeight, 0],
}),
},
],
}
}, [open, t.name])
// rendering
// =
if (!state) {
if (!open) {
return null
}
return (
<Animated.View
style={[a.absolute, a.inset_0, t.atoms.bg, wrapperAnimStyle]}
style={[a.absolute, a.inset_0, t.atoms.bg]}
entering={SlideInDown.duration(300).easing(Easing.out(Easing.exp))}
exiting={SlideOutDown.duration(200).easing(Easing.in(Easing.quad))}
aria-modal
accessibilityViewIsModal>
<ComposePost
+2 -5
View File
@@ -5,18 +5,15 @@ import {RemoveScrollBar} from 'react-remove-scroll-bar'
import {useA11y} from '#/state/a11y'
import {useModals} from '#/state/modals'
import {type ComposerOpts, useComposerState} from '#/state/shell/composer'
import {ComposePost, useComposerCancelRef} from '#/view/com/composer/Composer'
import {atoms as a, flatten, useBreakpoints, useTheme} from '#/alf'
import {ComposePost, useComposerCancelRef} from '../com/composer/Composer'
const BOTTOM_BAR_HEIGHT = 61
export function Composer({}: {winHeight: number}) {
export function Composer() {
const state = useComposerState()
const isActive = !!state
// rendering
// =
if (!isActive) {
return null
}
+1 -3
View File
@@ -51,7 +51,6 @@ import {Composer} from './Composer'
import {DrawerContent} from './Drawer'
function ShellInner() {
const winDim = useWindowDimensions()
const insets = useSafeAreaInsets()
const {state: policyUpdateState} = usePolicyUpdateContext()
@@ -108,8 +107,7 @@ function ShellInner() {
<TabsNavigator layout={drawerLayout} />
</ErrorBoundary>
</View>
<Composer winHeight={winDim.height} />
<Composer />
<ModalsContainer />
<MutedWordsDialog />
<SigninDialog />
+1 -1
View File
@@ -64,7 +64,7 @@ function ShellInner() {
<ErrorBoundary>
<FlatNavigator layout={drawerLayout} />
</ErrorBoundary>
<Composer winHeight={0} />
<Composer />
<ModalsContainer />
<MutedWordsDialog />
<SigninDialog />