Files
bsky-social-app/src/screens/Messages/components/splitView/MessagesSplitViewLayout.tsx
T
2026-05-15 11:14:46 +03:00

117 lines
3.5 KiB
TypeScript

import {View} from 'react-native'
import {type ScreenLayoutArgs, useIsFocused} from '@react-navigation/native'
import {type NativeStackNavigationProp} from '@react-navigation/native-stack'
import {type FlatNavigatorParams} from '#/lib/routes/types'
import {type NativeStackNavigationOptionsWithAuth} from '#/view/shell/createNativeStackNavigatorWithAuth'
import {atoms as a, useLayoutBreakpoints, useTheme, web} from '#/alf'
import {useDialogControl} from '#/components/Dialog'
import {NewChat} from '#/components/dms/dialogs/NewChatDialog'
import {SCROLLBAR_OFFSET} from '#/components/Layout'
import {LockScroll} from '#/components/LockScroll'
import {useAgeAssurance} from '#/ageAssurance'
import {IS_WEB} from '#/env'
import {ChatList, Header as ChatListHeader} from '../../ChatList'
import {SplitViewProvider} from './context'
const CENTER_COLUMN_WIDTH = 600
const LEFT_NAV_FULL_WIDTH = 245
const LEFT_NAV_MINIMAL_WIDTH = 86
const RIGHT_NAV_FULL_WIDTH = 330
const RIGHT_NAV_MINIMAL_WIDTH = 280
type MessageScreens =
| 'Messages'
| 'MessagesConversation'
| 'MessagesInbox'
| 'MessagesSettings'
type LayoutProps = ScreenLayoutArgs<
FlatNavigatorParams,
MessageScreens,
NativeStackNavigationOptionsWithAuth,
NativeStackNavigationProp<
FlatNavigatorParams,
MessageScreens,
string | undefined
>
>
export function renderMessagesSplitViewLayout(props: LayoutProps) {
return <MessagesSplitViewLayout {...props} />
}
function MessagesSplitViewLayout({children, navigation, route}: LayoutProps) {
const {rightNavVisible, centerColumnOffset} = useLayoutBreakpoints()
const newChatControl = useDialogControl()
const t = useTheme()
const aa = useAgeAssurance()
const isFocused = useIsFocused()
if (!IS_WEB || !rightNavVisible || aa.state.access !== aa.Access.Full) {
return children
}
const onNewChat = (conversation: string) =>
navigation.navigate('MessagesConversation', {conversation})
const selectedChat =
route.name === 'MessagesConversation' &&
route.params &&
'conversation' in route?.params
? route?.params?.conversation
: undefined
const leftNavWidth = centerColumnOffset
? LEFT_NAV_MINIMAL_WIDTH
: LEFT_NAV_FULL_WIDTH
const rightNavWidth = centerColumnOffset
? RIGHT_NAV_MINIMAL_WIDTH
: RIGHT_NAV_FULL_WIDTH
const containerWidth =
leftNavWidth - LEFT_NAV_MINIMAL_WIDTH + CENTER_COLUMN_WIDTH + rightNavWidth
return (
<View
style={[
a.flex_1,
a.flex_row,
a.mx_auto,
{maxWidth: containerWidth},
{
transform: [
{translateX: LEFT_NAV_MINIMAL_WIDTH},
{translateX: web(SCROLLBAR_OFFSET) ?? 0},
],
},
]}>
{isFocused && <LockScroll />}
<SplitViewProvider side="left">
<View
style={[
a.border_l,
t.atoms.border_contrast_low,
{width: containerWidth - CENTER_COLUMN_WIDTH},
]}>
<ChatListHeader newChatControl={newChatControl} />
<ChatList
newChatControl={newChatControl}
selectedChat={selectedChat}
/>
<NewChat onNewChat={onNewChat} control={newChatControl} />
</View>
</SplitViewProvider>
<SplitViewProvider side="right">
<View
style={[
a.border_x,
t.atoms.border_contrast_low,
{width: CENTER_COLUMN_WIDTH},
]}>
{children}
</View>
</SplitViewProvider>
</View>
)
}