import { StaticParamList } from '@react-navigation/native'
import {
createNativeStackNavigator,
NativeStackHeaderRightProps,
NativeStackNavigationOptions,
} from '@react-navigation/native-stack'
import { CardStyleInterpolators } from '@react-navigation/stack'
import React from 'react'
import {
composeOptions,
withMinimalBack,
withRightClose,
withRightDone,
} from '../components/display/platform_modal_header_buttons'
import { useDirectMessagesEligible, useQualifiedByAge } from '../hooks'
import {
AttachmentActionsScreen,
AttachmentActionsScreenOptions,
} from '../screens/attachment_actions/attachment_actions_screen'
import {
AvatarPickerScreen,
AvatarPickerScreenOptions,
AvatarPickerCreateScreenOptions,
} from '../screens/avatar_picker/avatar_picker_screen'
import { BugReportScreen, BugReportScreenOptions } from '../screens/bug_report_screen'
import {
MessageReadReceiptsScreen,
MessageReadReceiptsScreenOptions,
} from '../screens/conversation/message_read_receipts_screen'
import { ConversationDetailsScreen } from '../screens/conversation_details_screen'
import {
ConversationFilterReceipientsScreenOptions,
ConversationFilterRecipientsScreen,
} from '../screens/conversation_filter_recipients/conversation_filter_recipients_screen'
import { ConversationFiltersParams } from '../screens/conversation_filters/screen_props'
import {
ConversationFiltersScreen,
ConversationFiltersScreenOptions,
} from '../screens/conversation_filters_screen'
import { ConversationNewScreen } from '../screens/conversation_new/conversation_new_screen'
import {
ConversationNotificationLevelSelectScreen,
ConversationNotificationLevelSelectScreenOptions,
} from '../screens/conversation_notification_level_select_screen'
import {
ConversationRouteProps,
ConversationScreen,
ConversationScreenTitle,
} from '../screens/conversation_screen'
import { ConversationNewEntryScreen } from '../screens/conversation_select_recipients/conversation_new_entry_screen'
import { ConversationSelectDirectMessageRecipientsScreen } from '../screens/conversation_select_recipients/conversation_select_direct_message_recipients_screen'
import { ConversationSelectGroupRecipientsScreen } from '../screens/conversation_select_recipients/conversation_select_group_recipients_screen'
import { ConversationSelectTeamsILeadRecipientsScreen } from '../screens/conversation_select_recipients/conversation_select_teams_i_lead_recipients_screen'
import { ConversationSelectRecipientsParams } from '../screens/conversation_select_recipients/types/screen_props'
import {
ConversationSelectTypeScreen,
ConversationSelectTypeScreenOptions,
} from '../screens/conversation_select_type_screen'
import { ConversationsScreen } from '../screens/conversations/conversations_screen'
import { GetHelpScreen } from '../screens/get_help_screen'
import {
GroupNotificationLevelSelectScreen,
GroupNotificationLevelSelectScreenOptions,
} from '../screens/group_notification_level_select_screen'
import { GroupNotificationSettingsScreen } from '../screens/group_notification_settings_screen'
import {
MessageActionsScreen,
MessageActionsScreenOptions,
} from '../screens/message_actions_screen'
import { MessageReportScreen, MessageReportScreenOptions } from '../screens/message_report_screen'
import { NotFound } from '../screens/not_found'
import { NotificationSettingsScreen } from '../screens/notification_settings_screen'
import { PreferredAppSelectionScreen } from '../screens/preferred_app_selection_screen'
import { ReactionsScreen, ReactionsScreenOptions } from '../screens/reactions_screen'
import { SearchScreen, SearchScreenOptions } from '../screens/search/search_screen'
import { SendGiphyScreen, SendGiphyScreenOptions } from '../screens/send_giphy_screen'
import { SettingsScreen } from '../screens/settings_screen'
import {
SystemMessagePeopleScreen,
SystemMessagePeopleScreenOptions,
} from '../screens/system_message_people_screen'
import { TeamConversationScreen } from '../screens/team_conversation_screen'
import { isLiquidGlassEnabled } from '../utils/liquid_glass'
import { ScreenLayoutWithChatAccessGate } from './screenLayout'
const globalScreenOptions: () => NativeStackNavigationOptions = () => ({
headerBackButtonDisplayMode: 'minimal',
...(isLiquidGlassEnabled() ? { headerShadowVisible: false } : {}),
})
export const NewConversationStack = createNativeStackNavigator({
initialRouteName: 'ConversationNewEntry',
screenOptions: globalScreenOptions,
screenLayout: ScreenLayoutWithChatAccessGate,
screens: {
ConversationNewEntry: {
screen: ConversationNewEntryScreen,
options: ({ navigation }) =>
composeOptions(
{
title: 'New conversation',
headerBackVisible: false,
},
withRightClose({ onPress: navigation.goBack })
),
},
ConversationSelectGroupRecipients: {
screen: ConversationSelectGroupRecipientsScreen,
options: ({ navigation, route }) =>
composeOptions(
{
title: 'New conversation',
},
withRightClose({
onPress: () => navigation.popTo('Conversations', route.params),
})
),
},
ConversationSelectTeamsILeadRecipients: {
screen: ConversationSelectTeamsILeadRecipientsScreen,
options: ({ navigation, route }) =>
composeOptions(
{
title: 'New conversation',
},
withRightClose({
onPress: () => navigation.popTo('Conversations', route.params),
})
),
},
ConversationSelectDirectMessageRecipients: {
screen: ConversationSelectDirectMessageRecipientsScreen,
if: useDirectMessagesEligible,
options: ({ navigation }) =>
composeOptions(
{
title: 'New conversation',
headerBackVisible: false,
},
withRightClose({ onPress: navigation.goBack })
),
},
ConversationFilterRecipients: {
screen: ConversationFilterRecipientsScreen,
options: ConversationFilterReceipientsScreenOptions,
},
ConversationNew: {
screen: ConversationNewScreen,
options: ({ navigation, route }) =>
composeOptions(
{
title: 'New conversation',
headerLeft: () => null,
},
withRightClose({
onPress: () => {
const { chat_group_graph_id, group_source_app_name } =
route.params as ConversationSelectRecipientsParams
navigation.popTo('Conversations', { chat_group_graph_id, group_source_app_name })
},
})
),
},
AvatarPicker: {
screen: AvatarPickerScreen,
options: AvatarPickerCreateScreenOptions,
},
},
})
export const ChatStack = createNativeStackNavigator({
screenOptions: globalScreenOptions,
screenLayout: ScreenLayoutWithChatAccessGate,
screens: {
Conversations: {
screen: ConversationsScreen,
options: ({ route, navigation }) =>
composeOptions(
{
headerTitle: (route.params as { title?: string })?.title ?? 'Chat',
headerBackVisible: false,
},
withRightClose({ onPress: navigation.goBack })
),
},
ConversationFilters: {
screen: ConversationFiltersScreen,
options: ConversationFiltersScreenOptions,
},
Search: {
screen: SearchScreen,
options: SearchScreenOptions,
},
Conversation: {
screen: ConversationScreen,
options: ({ route, navigation }) =>
composeOptions(
{
headerTitle: (props: NativeStackHeaderRightProps) => {
const { conversation_id, title, badge, deleted, muted } =
route.params as ConversationRouteProps
return (
{title ?? 'Conversation'}
)
},
},
withMinimalBack({
onPress: () => {
const params = route.params as ConversationRouteProps
if ((params as ConversationFiltersParams)?.chat_group_graph_id) {
// Ensure that conversations with a graph id pass them back to the conversation list
const { chat_group_graph_id } = params
navigation.popTo('Conversations', { chat_group_graph_id })
} else {
navigation.goBack()
}
},
}),
withRightClose({ onPress: () => navigation.getParent()?.goBack() })
),
},
ConversationReply: {
screen: ConversationScreen,
options: ({ route, navigation }) =>
composeOptions(
{ title: (route.params as ConversationRouteProps)?.title ?? 'Reply' },
withMinimalBack({ onPress: navigation.goBack })
),
},
TeamConversation: {
screen: TeamConversationScreen,
if: useQualifiedByAge,
options: {
title: 'Finding conversation...',
animation: 'none',
cardStyleInterpolator: CardStyleInterpolators.forNoAnimation,
},
},
ConversationDetails: {
screen: ConversationDetailsScreen,
options: ({ navigation }) =>
composeOptions(
{
presentation: 'modal',
title: 'Conversation details',
},
withRightDone({ onPress: navigation.goBack })
),
},
AvatarPicker: {
screen: AvatarPickerScreen,
options: AvatarPickerScreenOptions,
},
ChatSettings: {
screen: SettingsScreen,
options: ({ navigation }) =>
composeOptions({ title: 'Chat settings' }, withMinimalBack({ onPress: navigation.goBack })),
},
NotificationSettings: {
screen: NotificationSettingsScreen,
options: ({ navigation }) =>
navigation.getState().index === 0
? composeOptions(
{ title: 'Chat notifications' },
withRightClose({ onPress: navigation.goBack })
)
: composeOptions(
{ title: 'Chat notifications' },
withMinimalBack({ onPress: navigation.goBack })
),
},
PreferredAppSelection: {
screen: PreferredAppSelectionScreen,
options: ({ navigation }) =>
composeOptions({ title: 'Preferred app' }, withMinimalBack({ onPress: navigation.goBack })),
},
GroupNotificationSettings: {
screen: GroupNotificationSettingsScreen,
options: ({ route, navigation }) => {
const title = (route.params as { title?: string })?.title || 'Group Settings'
// The dismiss button only shows when this is the entry screen (e.g.
// deep links); deeper in the stack the back button covers dismissal.
return navigation.getState().index === 0
? composeOptions(
{
title,
},
withRightClose({ onPress: navigation.goBack })
)
: composeOptions({ title }, withMinimalBack({ onPress: navigation.goBack }))
},
},
GroupNotificationLevelSelect: {
screen: GroupNotificationLevelSelectScreen,
options: GroupNotificationLevelSelectScreenOptions,
},
ConversationNotificationLevelSelect: {
screen: ConversationNotificationLevelSelectScreen,
options: ConversationNotificationLevelSelectScreenOptions,
},
New: {
screen: NewConversationStack,
if: useQualifiedByAge,
options: {
headerShown: false,
presentation: 'modal',
},
},
GroupConversationNew: {
screen: ConversationNewScreen,
if: useQualifiedByAge,
options: ({ navigation }) =>
composeOptions(
{
title: 'New conversation',
headerLeft: () => null,
},
withRightClose({ onPress: () => navigation.getParent()?.goBack() })
),
},
SendGiphy: {
screen: SendGiphyScreen,
options: SendGiphyScreenOptions,
},
MessageActions: {
screen: MessageActionsScreen,
// Something about sheetAllowedDetents declared inline breaks TS
options: MessageActionsScreenOptions,
},
MessageReport: {
screen: MessageReportScreen,
options: MessageReportScreenOptions,
},
AttachmentActions: {
screen: AttachmentActionsScreen,
options: AttachmentActionsScreenOptions,
},
ConversationSelectType: {
screen: ConversationSelectTypeScreen,
options: ConversationSelectTypeScreenOptions,
},
Reactions: {
screen: ReactionsScreen,
options: ReactionsScreenOptions,
},
SystemMessagePeople: {
screen: SystemMessagePeopleScreen,
options: SystemMessagePeopleScreenOptions,
},
MessageReadReceipts: {
screen: MessageReadReceiptsScreen,
options: MessageReadReceiptsScreenOptions,
},
BugReport: {
screen: BugReportScreen,
options: BugReportScreenOptions,
},
GetHelp: {
screen: GetHelpScreen,
options: ({ navigation }) =>
composeOptions(
{
headerTitle: 'Get help',
headerBackVisible: false,
presentation: 'modal',
},
withRightClose({ onPress: navigation.goBack })
),
},
NotFound: {
screen: NotFound,
options: {
title: '404',
},
linking: {
path: '*',
},
},
},
})
type ChatStackParamList = StaticParamList
declare global {
namespace ReactNavigation {
interface RootParamList extends ChatStackParamList {}
}
}