[Sheets] [Pt. 1] Root PR (#5557)
Co-authored-by: Samuel Newman <mozzius@protonmail.com> Co-authored-by: Eric Bailey <git@esb.lol> Co-authored-by: dan <dan.abramov@gmail.com> Co-authored-by: Hailey <me@haileyok.com>
This commit is contained in:
@@ -1,19 +1,28 @@
|
||||
import React, {useLayoutEffect} from 'react'
|
||||
import React from 'react'
|
||||
import {Modal, View} from 'react-native'
|
||||
import {StatusBar} from 'expo-status-bar'
|
||||
import * as SystemUI from 'expo-system-ui'
|
||||
|
||||
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||
import {useComposerState} from '#/state/shell/composer'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {getBackgroundColor, useThemeName} from '#/alf/util/useColorModeTheme'
|
||||
import {ComposePost, useComposerCancelRef} from '../com/composer/Composer'
|
||||
|
||||
export function Composer({}: {winHeight: number}) {
|
||||
const {setFullyExpandedCount} = useDialogStateControlContext()
|
||||
const t = useTheme()
|
||||
const state = useComposerState()
|
||||
const ref = useComposerCancelRef()
|
||||
|
||||
const open = !!state
|
||||
const prevOpen = React.useRef(open)
|
||||
|
||||
React.useEffect(() => {
|
||||
if (open && !prevOpen.current) {
|
||||
setFullyExpandedCount(c => c + 1)
|
||||
} else if (!open && prevOpen.current) {
|
||||
setFullyExpandedCount(c => c - 1)
|
||||
}
|
||||
prevOpen.current = open
|
||||
}, [open, setFullyExpandedCount])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -24,56 +33,18 @@ export function Composer({}: {winHeight: number}) {
|
||||
animationType="slide"
|
||||
onRequestClose={() => ref.current?.onPressCancel()}>
|
||||
<View style={[t.atoms.bg, a.flex_1]}>
|
||||
<Providers open={open}>
|
||||
<ComposePost
|
||||
cancelRef={ref}
|
||||
replyTo={state?.replyTo}
|
||||
onPost={state?.onPost}
|
||||
quote={state?.quote}
|
||||
quoteCount={state?.quoteCount}
|
||||
mention={state?.mention}
|
||||
text={state?.text}
|
||||
imageUris={state?.imageUris}
|
||||
videoUri={state?.videoUri}
|
||||
/>
|
||||
</Providers>
|
||||
<ComposePost
|
||||
cancelRef={ref}
|
||||
replyTo={state?.replyTo}
|
||||
onPost={state?.onPost}
|
||||
quote={state?.quote}
|
||||
quoteCount={state?.quoteCount}
|
||||
mention={state?.mention}
|
||||
text={state?.text}
|
||||
imageUris={state?.imageUris}
|
||||
videoUri={state?.videoUri}
|
||||
/>
|
||||
</View>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
<IOSModalBackground active={open} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
+21
-16
@@ -13,6 +13,14 @@ import * as NavigationBar from 'expo-navigation-bar'
|
||||
import {StatusBar} from 'expo-status-bar'
|
||||
import {useNavigation, useNavigationState} from '@react-navigation/native'
|
||||
|
||||
import {useDedupe} from '#/lib/hooks/useDedupe'
|
||||
import {useNotificationsHandler} from '#/lib/hooks/useNotificationHandler'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {useNotificationsRegistration} from '#/lib/notifications/notifications'
|
||||
import {isStateAtTabRoot} from '#/lib/routes/helpers'
|
||||
import {useTheme} from '#/lib/ThemeContext'
|
||||
import {isAndroid, isIOS} from '#/platform/detection'
|
||||
import {useDialogStateControlContext} from '#/state/dialogs'
|
||||
import {useSession} from '#/state/session'
|
||||
import {
|
||||
useIsDrawerOpen,
|
||||
@@ -20,17 +28,9 @@ import {
|
||||
useSetDrawerOpen,
|
||||
} from '#/state/shell'
|
||||
import {useCloseAnyActiveElement} from '#/state/util'
|
||||
import {useDedupe} from 'lib/hooks/useDedupe'
|
||||
import {useNotificationsHandler} from 'lib/hooks/useNotificationHandler'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useNotificationsRegistration} from 'lib/notifications/notifications'
|
||||
import {isStateAtTabRoot} from 'lib/routes/helpers'
|
||||
import {useTheme} from 'lib/ThemeContext'
|
||||
import {isAndroid} from 'platform/detection'
|
||||
import {useDialogStateContext} from 'state/dialogs'
|
||||
import {Lightbox} from 'view/com/lightbox/Lightbox'
|
||||
import {ModalsContainer} from 'view/com/modals/Modal'
|
||||
import {ErrorBoundary} from 'view/com/util/ErrorBoundary'
|
||||
import {Lightbox} from '#/view/com/lightbox/Lightbox'
|
||||
import {ModalsContainer} from '#/view/com/modals/Modal'
|
||||
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
|
||||
import {MutedWordsDialog} from '#/components/dialogs/MutedWords'
|
||||
import {SigninDialog} from '#/components/dialogs/Signin'
|
||||
import {Outlet as PortalOutlet} from '#/components/Portal'
|
||||
@@ -61,7 +61,6 @@ function ShellInner() {
|
||||
const canGoBack = useNavigationState(state => !isStateAtTabRoot(state))
|
||||
const {hasSession} = useSession()
|
||||
const closeAnyActiveElement = useCloseAnyActiveElement()
|
||||
const {importantForAccessibility} = useDialogStateContext()
|
||||
|
||||
useNotificationsRegistration()
|
||||
useNotificationsHandler()
|
||||
@@ -101,9 +100,7 @@ function ShellInner() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Animated.View
|
||||
style={containerPadding}
|
||||
importantForAccessibility={importantForAccessibility}>
|
||||
<Animated.View style={containerPadding}>
|
||||
<ErrorBoundary>
|
||||
<Drawer
|
||||
renderDrawerContent={renderDrawerContent}
|
||||
@@ -127,6 +124,7 @@ function ShellInner() {
|
||||
}
|
||||
|
||||
export const Shell: React.FC = function ShellImpl() {
|
||||
const {fullyExpandedCount} = useDialogStateControlContext()
|
||||
const pal = usePalette('default')
|
||||
const theme = useTheme()
|
||||
React.useEffect(() => {
|
||||
@@ -140,7 +138,14 @@ export const Shell: React.FC = function ShellImpl() {
|
||||
}, [theme])
|
||||
return (
|
||||
<View testID="mobileShellView" style={[styles.outerContainer, pal.view]}>
|
||||
<StatusBar style={theme.colorScheme === 'dark' ? 'light' : 'dark'} />
|
||||
<StatusBar
|
||||
style={
|
||||
theme.colorScheme === 'dark' || (isIOS && fullyExpandedCount > 0)
|
||||
? 'light'
|
||||
: 'dark'
|
||||
}
|
||||
animated
|
||||
/>
|
||||
<RoutesContainer>
|
||||
<ShellInner />
|
||||
</RoutesContainer>
|
||||
|
||||
Reference in New Issue
Block a user