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 {} } }