Use Reanimated layout animations for Android composer (#8546)
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -64,7 +64,7 @@ function ShellInner() {
|
||||
<ErrorBoundary>
|
||||
<FlatNavigator layout={drawerLayout} />
|
||||
</ErrorBoundary>
|
||||
<Composer winHeight={0} />
|
||||
<Composer />
|
||||
<ModalsContainer />
|
||||
<MutedWordsDialog />
|
||||
<SigninDialog />
|
||||
|
||||
Reference in New Issue
Block a user