[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:
Hailey
2024-10-04 13:24:12 -07:00
committed by GitHub
parent 9802ebe20d
commit 00486e9499
86 changed files with 2509 additions and 1577 deletions
+24 -53
View File
@@ -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
View File
@@ -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>