diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-06-11 04:10:57 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-11 05:10:57 +0200 |
commit | d85c8a09760aa91c080465840144b61155dc7ddf (patch) | |
tree | 2ccd90963836c98acc276c3399bb7e8bc9859ee2 /src/view/shell/Composer.tsx | |
parent | 14cddb7ec0a6088b5f2f89f61fc2a32656756f7a (diff) | |
download | voidsky-d85c8a09760aa91c080465840144b61155dc7ddf.tar.zst |
Revert to old modal on android (#4458)
* revert to old modal on android * close alf dialogs before closing composer * Try to fix white area * Use hook * Fix Back button * oops --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Diffstat (limited to 'src/view/shell/Composer.tsx')
-rw-r--r-- | src/view/shell/Composer.tsx | 159 |
1 files changed, 58 insertions, 101 deletions
diff --git a/src/view/shell/Composer.tsx b/src/view/shell/Composer.tsx index 1d656ca8f..b978d6b85 100644 --- a/src/view/shell/Composer.tsx +++ b/src/view/shell/Composer.tsx @@ -1,116 +1,73 @@ -import React, {useLayoutEffect, useState} from 'react' -import {Modal, View} from 'react-native' -import {GestureHandlerRootView} from 'react-native-gesture-handler' -import {RootSiblingParent} from 'react-native-root-siblings' -import {StatusBar} from 'expo-status-bar' -import * as SystemUI from 'expo-system-ui' +import React, {useEffect} from 'react' +import {Animated, Easing, StyleSheet, View} from 'react-native' import {observer} from 'mobx-react-lite' -import {isIOS} from '#/platform/detection' -import {Provider as LegacyModalProvider} from '#/state/modals' -import {useComposerState} from '#/state/shell/composer' -import {ModalsContainer as LegacyModalsContainer} from '#/view/com/modals/Modal' -import {atoms as a, useTheme} from '#/alf' -import {getBackgroundColor, useThemeName} from '#/alf/util/useColorModeTheme' -import { - Outlet as PortalOutlet, - Provider as PortalProvider, -} from '#/components/Portal' -import {ComposePost, useComposerCancelRef} from '../com/composer/Composer' +import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' +import {usePalette} from 'lib/hooks/usePalette' +import {useComposerState} from 'state/shell/composer' +import {ComposePost} from '../com/composer/Composer' -export const Composer = observer(function ComposerImpl({}: { +export const Composer = observer(function ComposerImpl({ + winHeight, +}: { winHeight: number }) { - const t = useTheme() const state = useComposerState() - const ref = useComposerCancelRef() - const [isModalReady, setIsModalReady] = useState(false) + const pal = usePalette('default') + const initInterp = useAnimatedValue(0) - const open = !!state - const [prevOpen, setPrevOpen] = useState(open) - if (open !== prevOpen) { - setPrevOpen(open) - if (!open) { - setIsModalReady(false) + useEffect(() => { + if (state) { + Animated.timing(initInterp, { + toValue: 1, + duration: 300, + easing: Easing.out(Easing.exp), + useNativeDriver: true, + }).start() + } else { + initInterp.setValue(0) } + }, [initInterp, state]) + const wrapperAnimStyle = { + transform: [ + { + translateY: initInterp.interpolate({ + inputRange: [0, 1], + outputRange: [winHeight, 0], + }), + }, + ], + } + + // rendering + // = + + if (!state) { + return <View /> } return ( - <Modal + <Animated.View + style={[styles.wrapper, pal.view, wrapperAnimStyle]} aria-modal - accessibilityViewIsModal - visible={open} - presentationStyle="formSheet" - animationType="slide" - onShow={() => setIsModalReady(true)} - onRequestClose={() => ref.current?.onPressCancel()}> - <View style={[t.atoms.bg, a.flex_1]}> - <Providers open={open}> - <ComposePost - isModalReady={isModalReady} - cancelRef={ref} - replyTo={state?.replyTo} - onPost={state?.onPost} - quote={state?.quote} - mention={state?.mention} - text={state?.text} - imageUris={state?.imageUris} - /> - </Providers> - </View> - </Modal> + accessibilityViewIsModal> + <ComposePost + replyTo={state.replyTo} + onPost={state.onPost} + quote={state.quote} + mention={state.mention} + text={state.text} + imageUris={state.imageUris} + /> + </Animated.View> ) }) -function Providers({ - children, - open, -}: { - children: React.ReactNode - open: boolean -}) { - // on iOS, it's a native formSheet. We use FullWindowOverlay to make - // the dialogs appear over it - if (isIOS) { - return ( - <> - {children} - <IOSModalBackground active={open} /> - </> - ) - } else { - // on Android we just nest the dialogs within it - return ( - <GestureHandlerRootView style={a.flex_1}> - <RootSiblingParent> - <LegacyModalProvider> - <PortalProvider> - {children} - <LegacyModalsContainer /> - <PortalOutlet /> - </PortalProvider> - </LegacyModalProvider> - </RootSiblingParent> - </GestureHandlerRootView> - ) - } -} - -// Generally, the backdrop of the app is the theme color, but when this is open -// we want it to be black due to the modal being a form sheet. -function IOSModalBackground({active}: {active: boolean}) { - const theme = useThemeName() - - useLayoutEffect(() => { - SystemUI.setBackgroundColorAsync('black') - - return () => { - SystemUI.setBackgroundColorAsync(getBackgroundColor(theme)) - } - }, [theme]) - - // Set the status bar to light - however, only if the modal is active - // If we rely on this component being mounted to set this, - // there'll be a delay before it switches back to default. - return active ? <StatusBar style="light" animated /> : null -} +const styles = StyleSheet.create({ + wrapper: { + position: 'absolute', + top: 0, + bottom: 0, + width: '100%', + }, +}) |