fix drawer layout on mobile web (#9618)

This commit is contained in:
Samuel Newman
2025-12-30 19:56:05 +02:00
committed by GitHub
parent 9cfa7d0ba8
commit 0aaf11aa7b
2 changed files with 50 additions and 29 deletions
+11 -3
View File
@@ -5,7 +5,6 @@ import {i18n, type MessageDescriptor} from '@lingui/core'
import {msg} from '@lingui/macro'
import {
type BottomTabBarProps,
type BottomTabNavigatorProps,
createBottomTabNavigator,
} from '@react-navigation/bottom-tabs'
import {
@@ -637,7 +636,11 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
* The TabsNavigator is used by native mobile to represent the routes
* in 3 distinct tab-stacks with a different root screen on each.
*/
function TabsNavigator({layout}: {layout: BottomTabNavigatorProps['layout']}) {
function TabsNavigator({
layout,
}: {
layout: React.ComponentProps<typeof Tab.Navigator>['layout']
}) {
const tabBar = useCallback(
(props: JSX.IntrinsicAttributes & BottomTabBarProps) => (
<BottomBar {...props} />
@@ -759,7 +762,11 @@ function MessagesTabNavigator() {
* The FlatNavigator is used by Web to represent the routes
* in a single ("flat") stack.
*/
const FlatNavigator = () => {
const FlatNavigator = ({
layout,
}: {
layout: React.ComponentProps<typeof Flat.Navigator>['layout']
}) => {
const t = useTheme()
const numUnread = useUnreadNotifications()
const screenListeners = useWebScrollRestoration()
@@ -767,6 +774,7 @@ const FlatNavigator = () => {
return (
<Flat.Navigator
layout={layout}
screenListeners={screenListeners}
screenOptions={screenOptions(t)}>
<Flat.Screen
+39 -26
View File
@@ -1,4 +1,4 @@
import {useEffect, useLayoutEffect, useState} from 'react'
import {useCallback, useEffect, useLayoutEffect, useState} from 'react'
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -6,7 +6,6 @@ import {useNavigation} from '@react-navigation/native'
import {RemoveScrollBar} from 'react-remove-scroll-bar'
import {useIntentHandler} from '#/lib/hooks/useIntentHandler'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {type NavigationProp} from '#/lib/routes/types'
import {useSession} from '#/state/session'
import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell'
@@ -17,7 +16,7 @@ import {ModalsContainer} from '#/view/com/modals/Modal'
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
import {Deactivated} from '#/screens/Deactivated'
import {Takendown} from '#/screens/Takendown'
import {atoms as a, select, useTheme} from '#/alf'
import {atoms as a, select, useBreakpoints, useTheme} from '#/alf'
import {AgeAssuranceRedirectDialog} from '#/components/ageAssurance/AgeAssuranceRedirectDialog'
import {EmailDialog} from '#/components/dialogs/EmailDialog'
import {LinkWarningDialog} from '#/components/dialogs/LinkWarning'
@@ -39,31 +38,11 @@ import {Composer} from './Composer.web'
import {DrawerContent} from './Drawer'
function ShellInner() {
const t = useTheme()
const isDrawerOpen = useIsDrawerOpen()
const setDrawerOpen = useSetDrawerOpen()
const {isDesktop} = useWebMediaQueries()
const navigator = useNavigation<NavigationProp>()
const closeAllActiveElements = useCloseAllActiveElements()
const {_} = useLingui()
const showDrawer = !isDesktop && isDrawerOpen
const [showDrawerDelayedExit, setShowDrawerDelayedExit] = useState(showDrawer)
const {state: policyUpdateState} = usePolicyUpdateContext()
const welcomeModalControl = useWelcomeModal()
useLayoutEffect(() => {
if (showDrawer !== showDrawerDelayedExit) {
if (showDrawer) {
setShowDrawerDelayedExit(true)
} else {
const timeout = setTimeout(() => {
setShowDrawerDelayedExit(false)
}, 160)
return () => clearTimeout(timeout)
}
}
}, [showDrawer, showDrawerDelayedExit])
useComposerKeyboardShortcut()
useIntentHandler()
@@ -74,10 +53,16 @@ function ShellInner() {
return unsubscribe
}, [navigator, closeAllActiveElements])
const drawerLayout = useCallback(
({children}: {children: React.ReactNode}) => (
<DrawerLayout>{children}</DrawerLayout>
),
[],
)
return (
<>
<ErrorBoundary>
<FlatNavigator />
<FlatNavigator layout={drawerLayout} />
</ErrorBoundary>
<Composer winHeight={0} />
<ModalsContainer />
@@ -100,6 +85,36 @@ function ShellInner() {
</>
)}
<PolicyUpdateOverlayPortalOutlet />
</>
)
}
function DrawerLayout({children}: {children: React.ReactNode}) {
const t = useTheme()
const isDrawerOpen = useIsDrawerOpen()
const setDrawerOpen = useSetDrawerOpen()
const {gtTablet} = useBreakpoints()
const {_} = useLingui()
const showDrawer = !gtTablet && isDrawerOpen
const [showDrawerDelayedExit, setShowDrawerDelayedExit] = useState(showDrawer)
useLayoutEffect(() => {
if (showDrawer !== showDrawerDelayedExit) {
if (showDrawer) {
setShowDrawerDelayedExit(true)
} else {
const timeout = setTimeout(() => {
setShowDrawerDelayedExit(false)
}, 160)
return () => clearTimeout(timeout)
}
}
}, [showDrawer, showDrawerDelayedExit])
return (
<>
{children}
{showDrawerDelayedExit && (
<>
<RemoveScrollBar />
@@ -137,8 +152,6 @@ function ShellInner() {
</TouchableWithoutFeedback>
</>
)}
<PolicyUpdateOverlayPortalOutlet />
</>
)
}