From 4cd663cbdb730947b80cda0e0463f2eb3a37fe78 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Thu, 18 Jun 2026 22:22:47 -0300 Subject: [PATCH 1/6] refactor: migrate ShareExtensionStack to React Navigation static config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Converts ShareExtensionStack from the dynamic JSX API to the static config API (createNativeStackNavigator with screens object). Introduces a shared withNavigation HOC in app/lib/navigation/ that injects navigation={useNavigation()} at the screen registration site, allowing class components (ShareListView, ShareView) to keep consuming this.props.navigation without internal edits. - ShareListView and ShareView are wrapped via withNavigation() at registration; cast through `any` to break the type cycle that would arise from their NativeStackNavigationProp props referencing StaticParamList ← themselves. - ShareViewParams is declared inline so StaticParamList correctly derives ShareView route params from the explicit ComponentType annotation. - ShareInsideStackParamList is now derived via StaticParamList and re-exported from navigationTypes.ts; the hand-written definition and its IAttachment/TServerModel/TSubscriptionModel imports are removed. - Theme spread moves into the .with() callback (themedHeader applied via Navigator screenOptions); defaultHeader stays in the static config. - Default export is ShareExtension.getComponent() so AppContainer is untouched during this slice. Claude-Session: https://claude.ai/code/session_01Qh9P8Bbp6V7PFpCY2X5on3 --- app/definitions/navigationTypes.ts | 20 ++---------- app/lib/navigation/withNavigation.tsx | 13 ++++++++ app/stacks/ShareExtensionStack.tsx | 45 +++++++++++++++++++-------- 3 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 app/lib/navigation/withNavigation.tsx diff --git a/app/definitions/navigationTypes.ts b/app/definitions/navigationTypes.ts index 7d6fe2eed98..246c2353a4d 100644 --- a/app/definitions/navigationTypes.ts +++ b/app/definitions/navigationTypes.ts @@ -1,11 +1,11 @@ import { type NavigatorScreenParams } from '@react-navigation/core'; import { type NativeStackNavigationOptions } from '@react-navigation/native-stack'; -import { type TSubscriptionModel } from './ISubscription'; -import { type TServerModel } from './IServer'; -import { type IAttachment } from './IAttachment'; import { type MasterDetailInsideStackParamList } from '../stacks/MasterDetailStack/types'; import { type OutsideParamList, type InsideStackParamList } from '../stacks/types'; +import { type ShareInsideStackParamList } from '../stacks/ShareExtensionStack'; + +export type { ShareInsideStackParamList }; interface INavigationProps { route?: any; @@ -31,17 +31,3 @@ export type StackParamList = { SetUsernameStack: NavigatorScreenParams; ShareExtensionStack: NavigatorScreenParams; }; - -export type ShareInsideStackParamList = { - ShareListView: undefined; - ShareView: { - attachments: IAttachment[]; - isShareView?: boolean; - isShareExtension: boolean; - serverInfo: TServerModel; - text: string; - room: TSubscriptionModel; - thread?: any; // TODO: Change - }; - SelectServerView: undefined; -}; diff --git a/app/lib/navigation/withNavigation.tsx b/app/lib/navigation/withNavigation.tsx new file mode 100644 index 00000000000..12367faca4e --- /dev/null +++ b/app/lib/navigation/withNavigation.tsx @@ -0,0 +1,13 @@ +import { useNavigation } from '@react-navigation/native'; +import { type ComponentType } from 'react'; + +function withNavigation

(WrappedComponent: ComponentType

): ComponentType> { + const WithNavigation = (props: Omit) => { + const navigation = useNavigation(); + return ; + }; + WithNavigation.displayName = `WithNavigation(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`; + return WithNavigation; +} + +export default withNavigation; diff --git a/app/stacks/ShareExtensionStack.tsx b/app/stacks/ShareExtensionStack.tsx index 0236e244b1f..ed711b9639c 100644 --- a/app/stacks/ShareExtensionStack.tsx +++ b/app/stacks/ShareExtensionStack.tsx @@ -1,27 +1,46 @@ -import { useContext } from 'react'; +import { useContext, type ComponentType } from 'react'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { type StaticParamList, type StaticScreenProps } from '@react-navigation/native'; import { ThemeContext } from '../theme'; import { defaultHeader, themedHeader } from '../lib/methods/helpers/navigation'; import SelectServerView from '../views/SelectServerView'; import ShareListView from '../views/ShareListView'; import ShareView from '../views/ShareView'; +import withNavigation from '../lib/navigation/withNavigation'; +import { type IAttachment, type TServerModel, type TSubscriptionModel } from '../definitions'; -const ShareExtension = createNativeStackNavigator(); -const ShareExtensionStack = () => { +type ShareViewParams = { + attachments: IAttachment[]; + isShareView?: boolean; + isShareExtension: boolean; + serverInfo: TServerModel; + text: string; + room: TSubscriptionModel; + thread?: any; +}; + +// Cast through `any` to break the type cycle that would arise from ShareListView/ShareView +// referencing ShareInsideStackParamList ← StaticParamList ← these components. +const ShareListViewScreen: ComponentType> = withNavigation(ShareListView as any) as any; +const ShareViewScreen: ComponentType> = withNavigation(ShareView as any) as any; + +const ShareExtension = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + ShareListView: ShareListViewScreen, + ShareView: ShareViewScreen, + SelectServerView + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + return ; +}); - return ( - - {/* @ts-ignore */} - - {/* @ts-ignore */} - - - - ); -}; +export type ShareInsideStackParamList = StaticParamList; + +const ShareExtensionStack = ShareExtension.getComponent(); export default ShareExtensionStack; From df36d5f0f51b05274db7e9684da89ac3a49480bd Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Thu, 18 Jun 2026 23:03:39 -0300 Subject: [PATCH 2/6] refactor: migrate MasterDetailStack to React Navigation static config Convert Drawer + ChatsStack + ModalStack + InsideStack from JSX dynamic navigators to `createNativeStackNavigator`/`createDrawerNavigator` static config. `ModalStack` wraps its Navigator in `` via `.with()`, using `useNavigation()` to get the InsideStack navigation for `.pop()`. Views that take a `navigation` prop are wrapped with `withNavigation` at the registration site; no view internals changed. `isMasterDetail: true` injection preserved in `RoomActionsView` and `ReadReceiptsView` options callbacks. Exports `MasterDetailInsideStaticParamList = StaticParamList`; hand-written param lists in `types.ts` kept as source of truth to avoid a circular type reference. Claude-Session: https://claude.ai/code/session_01Qh9P8Bbp6V7PFpCY2X5on3 --- app/stacks/MasterDetailStack/index.tsx | 394 +++++++++++++++---------- 1 file changed, 235 insertions(+), 159 deletions(-) diff --git a/app/stacks/MasterDetailStack/index.tsx b/app/stacks/MasterDetailStack/index.tsx index d8c22d8caea..191c135ecf1 100644 --- a/app/stacks/MasterDetailStack/index.tsx +++ b/app/stacks/MasterDetailStack/index.tsx @@ -1,15 +1,26 @@ -import { memo, useContext } from 'react'; -import { createNativeStackNavigator, type NativeStackNavigationProp } from '@react-navigation/native-stack'; +import { useContext, type ComponentType } from 'react'; +import { + createNativeStackNavigator, + createNativeStackScreen, + type NativeStackNavigationProp +} from '@react-navigation/native-stack'; import { createDrawerNavigator } from '@react-navigation/drawer'; +import { type StaticParamList, type StaticScreenProps, useNavigation } from '@react-navigation/native'; import { ThemeContext } from '../../theme'; import { defaultHeader, themedHeader, drawerStyle } from '../../lib/methods/helpers/navigation'; +import withNavigation from '../../lib/navigation/withNavigation'; +import { isIOS } from '../../lib/methods/helpers'; +import { ModalContainer } from './ModalContainer'; +import { type MasterDetailChatsStackParamList, type MasterDetailInsideStackParamList, type ModalStackParamList } from './types'; // Chats Stack import RoomView from '../../views/RoomView'; import RoomsListView from '../../views/RoomsListView'; +// Modal Stack import RoomActionsView from '../../views/RoomActionsView'; import RoomInfoView from '../../views/RoomInfoView'; import ReportUserView from '../../views/ReportUserView'; +import SelectListView from '../../views/SelectListView'; import RoomInfoEditView from '../../views/RoomInfoEditView'; import ChangeAvatarView from '../../views/ChangeAvatarView'; import RoomMembersView from '../../views/RoomMembersView'; @@ -50,194 +61,259 @@ import LegalView from '../../views/LegalView'; import SecurityPrivacyView from '../../views/SecurityPrivacyView'; import MediaAutoDownloadView from '../../views/MediaAutoDownloadView'; import E2EEncryptionSecurityView from '../../views/E2EEncryptionSecurityView'; -// InsideStackNavigator -import AttachmentView from '../../views/AttachmentView'; -import ModalBlockView from '../../views/ModalBlockView'; -import JitsiMeetView from '../../views/JitsiMeetView'; -import CallView from '../../views/CallView'; import StatusView from '../../views/StatusView'; import CreateDiscussionView from '../../views/CreateDiscussionView'; import E2ESaveYourPasswordView from '../../views/E2ESaveYourPasswordView'; import E2EHowItWorksView from '../../views/E2EHowItWorksView'; import E2EEnterYourPasswordView from '../../views/E2EEnterYourPasswordView'; -import ShareView from '../../views/ShareView'; import QueueListView from '../../ee/omnichannel/views/QueueListView'; import AddChannelTeamView from '../../views/AddChannelTeamView'; import AddExistingChannelView from '../../views/AddExistingChannelView'; -import SelectListView from '../../views/SelectListView'; import DiscussionsView from '../../views/DiscussionsView'; import AccessibilityAndAppearanceView from '../../views/AccessibilityAndAppearanceView'; -import { ModalContainer } from './ModalContainer'; -import { - type MasterDetailChatsStackParamList, - type MasterDetailDrawerParamList, - type MasterDetailInsideStackParamList, - type ModalStackParamList -} from './types'; -import { isIOS } from '../../lib/methods/helpers'; -import { type TNavigation } from '../stackType'; import { SupportedVersionsWarning } from '../../containers/SupportedVersions'; +// InsideStack +import AttachmentView from '../../views/AttachmentView'; +import ModalBlockView from '../../views/ModalBlockView'; +import JitsiMeetView from '../../views/JitsiMeetView'; +import ShareView from '../../views/ShareView'; +import CallView from '../../views/CallView'; -// ChatsStackNavigator -const ChatsStack = createNativeStackNavigator(); -const ChatsStackNavigator = memo(() => { - 'use memo'; +// ─── withNavigation wrappers ────────────────────────────────────────────────── +// Cast through `any` to break the type cycle that would arise from each view's +// navigation prop referencing ModalStackParamList ← StaticParamList +// ← these components. HOC static properties (navigationOptions) are forwarded by +// hoistNonReactStatics inside connect() and withTheme(), so `.navigationOptions` +// is still reachable on the wrapped imports for options callbacks. - const { theme } = useContext(ThemeContext); +const RoomViewScreen: ComponentType> = withNavigation( + RoomView as any +) as any; - return ( - - - - ); -}); +// class components +const RoomActionsViewScreen: ComponentType> = withNavigation( + RoomActionsView as any +) as any; +const SelectListViewScreen: ComponentType> = withNavigation( + SelectListView as any +) as any; +const SearchMessagesViewScreen: ComponentType> = withNavigation( + SearchMessagesView as any +) as any; +const MessagesViewScreen: ComponentType> = withNavigation( + MessagesView as any +) as any; +const ThreadMessagesViewScreen: ComponentType> = withNavigation( + ThreadMessagesView as any +) as any; +const TeamChannelsViewScreen: ComponentType> = withNavigation( + TeamChannelsView as any +) as any; -// DrawerNavigator -const Drawer = createDrawerNavigator(); -const DrawerNavigator = memo(() => { +// function components +const RoomInfoEditViewScreen: ComponentType> = withNavigation( + RoomInfoEditView as any +) as any; +const InviteUsersViewScreen: ComponentType> = withNavigation( + InviteUsersView as any +) as any; +const DirectoryViewScreen: ComponentType> = withNavigation( + DirectoryView as any +) as any; +const E2EEToggleRoomViewScreen: ComponentType> = withNavigation( + E2EEToggleRoomView as any +) as any; +const CannedResponsesListViewScreen: ComponentType> = + withNavigation(CannedResponsesListView as any) as any; +const LivechatEditViewScreen: ComponentType> = withNavigation( + LivechatEditView as any +) as any; +const ProfileViewScreen: ComponentType> = withNavigation( + ProfileView as any +) as any; +const ChangePasswordViewScreen: ComponentType> = withNavigation( + ChangePasswordView as any +) as any; +const CreateDiscussionViewScreen: ComponentType> = withNavigation( + CreateDiscussionView as any +) as any; +const E2EEnterYourPasswordViewScreen: ComponentType> = + withNavigation(E2EEnterYourPasswordView as any) as any; +const UserPreferencesViewScreen: ComponentType> = withNavigation( + UserPreferencesView as any +) as any; +const SecurityPrivacyViewScreen: ComponentType> = withNavigation( + SecurityPrivacyView as any +) as any; +const PushTroubleshootViewScreen: ComponentType> = withNavigation( + PushTroubleshootView as any +) as any; +const SupportedVersionsWarningScreen: ComponentType> = + withNavigation(SupportedVersionsWarning as any) as any; + +// InsideStack class components +const ModalBlockViewScreen: ComponentType> = withNavigation( + ModalBlockView as any +) as any; +const ShareViewScreen: ComponentType> = withNavigation( + ShareView as any +) as any; + +// ─── ChatsStackNavigator ────────────────────────────────────────────────────── + +const ChatsStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + RoomView: createNativeStackScreen({ + screen: RoomViewScreen, + options: { title: '' } + }) + } +}).with(({ Navigator }) => { 'use memo'; - return ( - }> - - - ); + const { theme } = useContext(ThemeContext); + return ; }); -export interface INavigation { - navigation: NativeStackNavigationProp; -} +// ─── DrawerNavigator ────────────────────────────────────────────────────────── + +const DrawerNav = createDrawerNavigator({ + screenOptions: { drawerType: 'permanent', headerShown: false, drawerStyle: { ...drawerStyle } }, + drawerContent: () => , + screens: { + ChatsStackNavigator: ChatsStack + } +} as any); -const ModalStack = createNativeStackNavigator(); -const ModalStackNavigator = memo(({ navigation }: INavigation) => { +// ─── ModalStackNavigator ────────────────────────────────────────────────────── + +const ModalStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + RoomActionsView: createNativeStackScreen({ + screen: RoomActionsViewScreen, + options: props => RoomActionsView.navigationOptions!({ ...props, isMasterDetail: true }) + }), + RoomInfoView, + ReportUserView, + SelectListView: SelectListViewScreen, + RoomInfoEditView: RoomInfoEditViewScreen, + ChangeAvatarView, + RoomMembersView, + SearchMessagesView: createNativeStackScreen({ + screen: SearchMessagesViewScreen, + options: SearchMessagesView.navigationOptions + }), + SelectedUsersView, + InviteUsersView: InviteUsersViewScreen, + AddChannelTeamView, + AddExistingChannelView, + InviteUsersEditView, + MessagesView: MessagesViewScreen, + AutoTranslateView, + DirectoryView: DirectoryViewScreen, + QueueListView, + NotificationPrefView, + E2EEToggleRoomView: E2EEToggleRoomViewScreen, + ForwardMessageView, + ForwardLivechatView, + CloseLivechatView, + CannedResponsesListView: CannedResponsesListViewScreen, + CannedResponseDetail, + LivechatEditView: LivechatEditViewScreen, + PickerView, + ThreadMessagesView: ThreadMessagesViewScreen, + DiscussionsView, + TeamChannelsView: TeamChannelsViewScreen, + ReadReceiptsView: createNativeStackScreen({ + screen: ReadReceiptsView as any, + options: props => ReadReceiptsView.navigationOptions!({ ...props, isMasterDetail: true }) + }), + SettingsView, + LegalView, + LanguageView, + ThemeView, + DefaultBrowserView, + ScreenLockConfigView: createNativeStackScreen({ + screen: ScreenLockConfigView as any, + options: ScreenLockConfigView.navigationOptions + }), + StatusView, + ProfileView: ProfileViewScreen, + ChangePasswordView: ChangePasswordViewScreen, + DisplayPrefsView, + AdminPanelView, + NewMessageView, + CreateChannelView, + CreateDiscussionView: CreateDiscussionViewScreen, + E2ESaveYourPasswordView, + E2EHowItWorksView, + E2EEnterYourPasswordView: E2EEnterYourPasswordViewScreen, + UserPreferencesView: UserPreferencesViewScreen, + UserNotificationPrefView, + SecurityPrivacyView: SecurityPrivacyViewScreen, + MediaAutoDownloadView, + E2EEncryptionSecurityView, + PushTroubleshootView: PushTroubleshootViewScreen, + SupportedVersionsWarning: SupportedVersionsWarningScreen, + AccessibilityAndAppearanceView + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + const navigation = useNavigation>(); return ( - - RoomActionsView.navigationOptions!({ ...props, isMasterDetail: true })} - /> - - - {/* @ts-ignore */} - - {/* @ts-ignore */} - - - - - - {/* @ts-ignore */} - - - - - - - - - - - - - - - - {/* @ts-ignore */} - - - {/* @ts-ignore */} - - - - ReadReceiptsView.navigationOptions!({ ...props, isMasterDetail: true })} - /> - - - - - - - - - - - - - - {/* @ts-ignore */} - - - - - - - - - - - - - + ); }); -// InsideStackNavigator -const InsideStack = createNativeStackNavigator(); -const InsideStackNavigator = memo(() => { +// ─── InsideStackNavigator (MasterDetailStack root) ──────────────────────────── + +const InsideStack = createNativeStackNavigator({ + screenOptions: { + ...defaultHeader, + presentation: isIOS ? 'containedTransparentModal' : 'containedModal' + }, + screens: { + DrawerNavigator: createNativeStackScreen({ + screen: DrawerNav as any, + options: { headerShown: false } + }), + ModalStackNavigator: createNativeStackScreen({ + screen: ModalStack as any, + options: { headerShown: false } + }), + AttachmentView, + ModalBlockView: createNativeStackScreen({ + screen: ModalBlockViewScreen, + options: ModalBlockView.navigationOptions as any + }), + JitsiMeetView: createNativeStackScreen({ + screen: JitsiMeetView, + options: { + headerShown: false, + animation: isIOS ? 'default' : 'none' + } + }), + ShareView: ShareViewScreen, + CallView: createNativeStackScreen({ + screen: CallView, + options: { headerShown: false } + }) + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); - return ( - - - - - {/* @ts-ignore */} - - - {/* @ts-ignore */} - - - - ); + return ; }); -export default InsideStackNavigator; +export type MasterDetailInsideStaticParamList = StaticParamList; + +const MasterDetailStack = InsideStack.getComponent(); + +export default MasterDetailStack; From 4378fc72730bf5b1b233e6d71b0b16969166eaad Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Fri, 19 Jun 2026 15:34:31 -0300 Subject: [PATCH 3/6] refactor: address review on MasterDetailStack static-config migration Remove the dead exported MasterDetailInsideStaticParamList type (no consumers; deriving it would create a types cycle). Drop the createDrawerNavigator config cast so screenOptions/screens/drawerContent stay type-checked. Wrap ReadReceiptsView and ScreenLockConfigView class screens with withNavigation to match the other stacks. Clarify that .navigationOptions is reachable via the connect/withTheme-wrapped default exports, not the withNavigation wrappers. Claude-Session: https://claude.ai/code/session_01FambjUT5Y47f8V6Kc9Fpn5 --- app/stacks/MasterDetailStack/index.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/stacks/MasterDetailStack/index.tsx b/app/stacks/MasterDetailStack/index.tsx index 191c135ecf1..3b551455fb6 100644 --- a/app/stacks/MasterDetailStack/index.tsx +++ b/app/stacks/MasterDetailStack/index.tsx @@ -5,7 +5,7 @@ import { type NativeStackNavigationProp } from '@react-navigation/native-stack'; import { createDrawerNavigator } from '@react-navigation/drawer'; -import { type StaticParamList, type StaticScreenProps, useNavigation } from '@react-navigation/native'; +import { type StaticScreenProps, useNavigation } from '@react-navigation/native'; import { ThemeContext } from '../../theme'; import { defaultHeader, themedHeader, drawerStyle } from '../../lib/methods/helpers/navigation'; @@ -84,7 +84,7 @@ import CallView from '../../views/CallView'; // navigation prop referencing ModalStackParamList ← StaticParamList // ← these components. HOC static properties (navigationOptions) are forwarded by // hoistNonReactStatics inside connect() and withTheme(), so `.navigationOptions` -// is still reachable on the wrapped imports for options callbacks. +// is still reachable on the connect/withTheme-wrapped default exports for options callbacks. const RoomViewScreen: ComponentType> = withNavigation( RoomView as any @@ -109,6 +109,12 @@ const ThreadMessagesViewScreen: ComponentType> = withNavigation( TeamChannelsView as any ) as any; +const ReadReceiptsViewScreen: ComponentType> = withNavigation( + ReadReceiptsView as any +) as any; +const ScreenLockConfigViewScreen: ComponentType> = withNavigation( + ScreenLockConfigView as any +) as any; // function components const RoomInfoEditViewScreen: ComponentType> = withNavigation( @@ -184,7 +190,7 @@ const DrawerNav = createDrawerNavigator({ screens: { ChatsStackNavigator: ChatsStack } -} as any); +}); // ─── ModalStackNavigator ────────────────────────────────────────────────────── @@ -227,7 +233,7 @@ const ModalStack = createNativeStackNavigator({ DiscussionsView, TeamChannelsView: TeamChannelsViewScreen, ReadReceiptsView: createNativeStackScreen({ - screen: ReadReceiptsView as any, + screen: ReadReceiptsViewScreen, options: props => ReadReceiptsView.navigationOptions!({ ...props, isMasterDetail: true }) }), SettingsView, @@ -236,7 +242,7 @@ const ModalStack = createNativeStackNavigator({ ThemeView, DefaultBrowserView, ScreenLockConfigView: createNativeStackScreen({ - screen: ScreenLockConfigView as any, + screen: ScreenLockConfigViewScreen, options: ScreenLockConfigView.navigationOptions }), StatusView, @@ -312,8 +318,6 @@ const InsideStack = createNativeStackNavigator({ return ; }); -export type MasterDetailInsideStaticParamList = StaticParamList; - const MasterDetailStack = InsideStack.getComponent(); export default MasterDetailStack; From 691eea735b970d9c58130503060587a616c9b59f Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 23 Jun 2026 15:20:48 -0300 Subject: [PATCH 4/6] refactor: trim MasterDetailStack static-config comments to signal-only Drop the import-section labels and navigator box-drawing dividers; condense the withNavigation block to why the cast is needed and why .navigationOptions stays reachable through connect()/withTheme(). Claude-Session: https://claude.ai/code/session_01YGusFn31iyN58idszGKMgt --- app/stacks/MasterDetailStack/index.tsx | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/app/stacks/MasterDetailStack/index.tsx b/app/stacks/MasterDetailStack/index.tsx index 3b551455fb6..02ec28fd9a6 100644 --- a/app/stacks/MasterDetailStack/index.tsx +++ b/app/stacks/MasterDetailStack/index.tsx @@ -13,10 +13,8 @@ import withNavigation from '../../lib/navigation/withNavigation'; import { isIOS } from '../../lib/methods/helpers'; import { ModalContainer } from './ModalContainer'; import { type MasterDetailChatsStackParamList, type MasterDetailInsideStackParamList, type ModalStackParamList } from './types'; -// Chats Stack import RoomView from '../../views/RoomView'; import RoomsListView from '../../views/RoomsListView'; -// Modal Stack import RoomActionsView from '../../views/RoomActionsView'; import RoomInfoView from '../../views/RoomInfoView'; import ReportUserView from '../../views/ReportUserView'; @@ -72,25 +70,19 @@ import AddExistingChannelView from '../../views/AddExistingChannelView'; import DiscussionsView from '../../views/DiscussionsView'; import AccessibilityAndAppearanceView from '../../views/AccessibilityAndAppearanceView'; import { SupportedVersionsWarning } from '../../containers/SupportedVersions'; -// InsideStack import AttachmentView from '../../views/AttachmentView'; import ModalBlockView from '../../views/ModalBlockView'; import JitsiMeetView from '../../views/JitsiMeetView'; import ShareView from '../../views/ShareView'; import CallView from '../../views/CallView'; -// ─── withNavigation wrappers ────────────────────────────────────────────────── -// Cast through `any` to break the type cycle that would arise from each view's -// navigation prop referencing ModalStackParamList ← StaticParamList -// ← these components. HOC static properties (navigationOptions) are forwarded by -// hoistNonReactStatics inside connect() and withTheme(), so `.navigationOptions` -// is still reachable on the connect/withTheme-wrapped default exports for options callbacks. +// Cast through `any` to break the navigation-prop type cycle; removing it reintroduces a real TS circular ref. +// `.navigationOptions` stays reachable on the wrapped components because connect()/withTheme() hoist statics. const RoomViewScreen: ComponentType> = withNavigation( RoomView as any ) as any; -// class components const RoomActionsViewScreen: ComponentType> = withNavigation( RoomActionsView as any ) as any; @@ -116,7 +108,6 @@ const ScreenLockConfigViewScreen: ComponentType> = withNavigation( RoomInfoEditView as any ) as any; @@ -157,7 +148,6 @@ const PushTroubleshootViewScreen: ComponentType> = withNavigation(SupportedVersionsWarning as any) as any; -// InsideStack class components const ModalBlockViewScreen: ComponentType> = withNavigation( ModalBlockView as any ) as any; @@ -165,8 +155,6 @@ const ShareViewScreen: ComponentType; }); -// ─── DrawerNavigator ────────────────────────────────────────────────────────── - const DrawerNav = createDrawerNavigator({ screenOptions: { drawerType: 'permanent', headerShown: false, drawerStyle: { ...drawerStyle } }, drawerContent: () => , @@ -192,8 +178,6 @@ const DrawerNav = createDrawerNavigator({ } }); -// ─── ModalStackNavigator ────────────────────────────────────────────────────── - const ModalStack = createNativeStackNavigator({ screenOptions: defaultHeader, screens: { @@ -277,8 +261,6 @@ const ModalStack = createNativeStackNavigator({ ); }); -// ─── InsideStackNavigator (MasterDetailStack root) ──────────────────────────── - const InsideStack = createNativeStackNavigator({ screenOptions: { ...defaultHeader, From 15d9a7e7bb8d2a735eeabf7f7eb079399027707d Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 23 Jun 2026 16:39:41 -0300 Subject: [PATCH 5/6] refactor: migrate InsideStack to React Navigation static config (#7415) --- app/stacks/InsideStack.tsx | 536 ++++++++++++++++++++----------------- app/stacks/types.ts | 16 +- 2 files changed, 297 insertions(+), 255 deletions(-) diff --git a/app/stacks/InsideStack.tsx b/app/stacks/InsideStack.tsx index 3cbefe6dd3d..97ad0399dd9 100644 --- a/app/stacks/InsideStack.tsx +++ b/app/stacks/InsideStack.tsx @@ -1,12 +1,19 @@ -import { useContext } from 'react'; +import { useContext, type ComponentType } from 'react'; import { I18nManager } from 'react-native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { + createNativeStackNavigator, + createNativeStackScreen, + type NativeStackNavigationOptions +} from '@react-navigation/native-stack'; import { createDrawerNavigator } from '@react-navigation/drawer'; +import { type StaticScreenProps } from '@react-navigation/native'; import { ThemeContext } from '../theme'; import { defaultHeader, themedHeader } from '../lib/methods/helpers/navigation'; +import withNavigation from '../lib/navigation/withNavigation'; import Sidebar from '../views/SidebarView'; -// Chats Stack +import { isIOS } from '../lib/methods/helpers'; +import { type TNavigation } from './stackType'; import RoomView from '../views/RoomView'; import RoomsListView from '../views/RoomsListView'; import RoomActionsView from '../views/RoomActionsView'; @@ -32,317 +39,348 @@ import TeamChannelsView from '../views/TeamChannelsView'; import ReadReceiptsView from '../views/ReadReceiptView'; import CannedResponsesListView from '../views/CannedResponsesListView'; import CannedResponseDetail from '../views/CannedResponseDetail'; -// Profile Stack +import JitsiMeetView from '../views/JitsiMeetView'; +import DiscussionsView from '../views/DiscussionsView'; +import ChangeAvatarView from '../views/ChangeAvatarView'; +import AddChannelTeamView from '../views/AddChannelTeamView'; +import AddExistingChannelView from '../views/AddExistingChannelView'; +import SelectListView from '../views/SelectListView'; +import QueueListView from '../ee/omnichannel/views/QueueListView'; import ProfileView from '../views/ProfileView'; import UserPreferencesView from '../views/UserPreferencesView'; import UserNotificationPrefView from '../views/UserNotificationPreferencesView'; import ChangePasswordView from '../views/ChangePasswordView'; -// Display Preferences View -import DisplayPrefsView from '../views/DisplayPrefsView'; -// Settings Stack import SettingsView from '../views/SettingsView'; import SecurityPrivacyView from '../views/SecurityPrivacyView'; import GetHelpView from '../views/GetHelpView'; import PushTroubleshootView from '../views/PushTroubleshootView'; import E2EEncryptionSecurityView from '../views/E2EEncryptionSecurityView'; import LanguageView from '../views/LanguageView'; -import ThemeView from '../views/ThemeView'; import DefaultBrowserView from '../views/DefaultBrowserView'; import ScreenLockConfigView from '../views/ScreenLockConfigView'; import MediaAutoDownloadView from '../views/MediaAutoDownloadView'; -// Admin Stack +import LegalView from '../views/LegalView'; +import AccessibilityAndAppearanceView from '../views/AccessibilityAndAppearanceView'; +import DisplayPrefsView from '../views/DisplayPrefsView'; +import ThemeView from '../views/ThemeView'; import AdminPanelView from '../views/AdminPanelView'; -// NewMessage Stack import NewMessageView from '../views/NewMessageView'; import CreateChannelView from '../views/CreateChannelView'; -// E2ESaveYourPassword Stack +import CreateDiscussionView from '../views/CreateDiscussionView'; +import ForwardMessageView from '../views/ForwardMessageView'; import E2ESaveYourPasswordView from '../views/E2ESaveYourPasswordView'; import E2EHowItWorksView from '../views/E2EHowItWorksView'; -// E2EEnterYourPassword Stack import E2EEnterYourPasswordView from '../views/E2EEnterYourPasswordView'; -// InsideStackNavigator import AttachmentView from '../views/AttachmentView'; import ModalBlockView from '../views/ModalBlockView'; -import JitsiMeetView from '../views/JitsiMeetView'; import StatusView from '../views/StatusView'; import ShareView from '../views/ShareView'; import CallView from '../views/CallView'; -import CreateDiscussionView from '../views/CreateDiscussionView'; -import ForwardMessageView from '../views/ForwardMessageView'; -import QueueListView from '../ee/omnichannel/views/QueueListView'; -import AddChannelTeamView from '../views/AddChannelTeamView'; -import AddExistingChannelView from '../views/AddExistingChannelView'; -import SelectListView from '../views/SelectListView'; -import DiscussionsView from '../views/DiscussionsView'; -import ChangeAvatarView from '../views/ChangeAvatarView'; -import LegalView from '../views/LegalView'; -import { - type AdminPanelStackParamList, - type ChatsStackParamList, - type DrawerParamList, - type E2EEnterYourPasswordStackParamList, - type E2ESaveYourPasswordStackParamList, - type InsideStackParamList, - type NewMessageStackParamList, - type ProfileStackParamList, - type SettingsStackParamList, - type AccessibilityStackParamList -} from './types'; -import { isIOS } from '../lib/methods/helpers'; -import { type TNavigation } from './stackType'; -import AccessibilityAndAppearanceView from '../views/AccessibilityAndAppearanceView'; -// ChatsStackNavigator -const ChatsStack = createNativeStackNavigator(); -const ChatsStackNavigator = () => { +// Cast through `any` to break the navigation-prop type cycle; removing it reintroduces a real TS circular ref. +const RoomViewScreen = withNavigation(RoomView as any) as any; +const RoomActionsViewScreen = withNavigation(RoomActionsView as any) as any; +const SelectListViewScreen = withNavigation(SelectListView as any) as any; +const RoomInfoEditViewScreen = withNavigation(RoomInfoEditView as any) as any; +const SearchMessagesViewScreen = withNavigation(SearchMessagesView as any) as any; +const InviteUsersViewScreen = withNavigation(InviteUsersView as any) as any; +const MessagesViewScreen = withNavigation(MessagesView as any) as any; +const DirectoryViewScreen = withNavigation(DirectoryView as any) as any; +const PushTroubleshootViewScreen: ComponentType> = withNavigation( + PushTroubleshootView as any +) as any; +const LivechatEditViewScreen = withNavigation(LivechatEditView as any) as any; +const ThreadMessagesViewScreen = withNavigation(ThreadMessagesView as any) as any; +const TeamChannelsViewScreen = withNavigation(TeamChannelsView as any) as any; +const ReadReceiptsViewScreen = withNavigation(ReadReceiptsView as any) as any; +const CannedResponsesListViewScreen = withNavigation(CannedResponsesListView as any) as any; +const ProfileViewScreen: ComponentType> = withNavigation(ProfileView as any) as any; +const ChangePasswordViewScreen: ComponentType> = withNavigation(ChangePasswordView as any) as any; +const UserPreferencesViewScreen: ComponentType> = withNavigation(UserPreferencesView as any) as any; +const SecurityPrivacyViewScreen: ComponentType> = withNavigation(SecurityPrivacyView as any) as any; +const ScreenLockConfigViewScreen: ComponentType> = withNavigation( + ScreenLockConfigView as any +) as any; +const CreateDiscussionViewScreen = withNavigation(CreateDiscussionView as any) as any; +const E2EEnterYourPasswordViewScreen: ComponentType> = withNavigation( + E2EEnterYourPasswordView as any +) as any; +const ShareViewScreen = withNavigation(ShareView as any) as any; +const ModalBlockViewScreen = withNavigation(ModalBlockView as any) as any; +const RoomInfoViewScreen = RoomInfoView as any; +const ReportUserViewScreen = ReportUserView as any; +const RoomMembersViewScreen = RoomMembersView as any; +const DiscussionsViewScreen = DiscussionsView as any; +const SelectedUsersViewScreen = SelectedUsersView as any; +const InviteUsersEditViewScreen = InviteUsersEditView as any; +const AutoTranslateViewScreen = AutoTranslateView as any; +const NotificationPrefViewScreen = NotificationPrefView as any; +const E2EEToggleRoomViewScreen = E2EEToggleRoomView as any; +const CloseLivechatViewScreen = CloseLivechatView as any; +const CreateChannelViewScreen = CreateChannelView as any; +const AddChannelTeamViewScreen = AddChannelTeamView as any; +const AddExistingChannelViewScreen = AddExistingChannelView as any; +const CannedResponseDetailScreen = CannedResponseDetail as any; +const JitsiMeetViewScreen = JitsiMeetView as any; +const ChangeAvatarViewScreen = ChangeAvatarView as any; +const UserNotificationPrefViewScreen: ComponentType> = UserNotificationPrefView as any; +const SettingsViewScreen: ComponentType> = SettingsView as any; +const E2EEncryptionSecurityViewScreen: ComponentType> = E2EEncryptionSecurityView as any; +const LanguageViewScreen: ComponentType> = LanguageView as any; +const DefaultBrowserViewScreen: ComponentType> = DefaultBrowserView as any; +const MediaAutoDownloadViewScreen: ComponentType> = MediaAutoDownloadView as any; +const GetHelpViewScreen: ComponentType> = GetHelpView as any; +const LegalViewScreen: ComponentType> = LegalView as any; +const AccessibilityAndAppearanceViewScreen: ComponentType> = AccessibilityAndAppearanceView as any; +const DisplayPrefsViewScreen: ComponentType> = DisplayPrefsView as any; +const ThemeViewScreen: ComponentType> = ThemeView as any; +const AdminPanelViewScreen: ComponentType> = AdminPanelView as any; +const NewMessageViewScreen: ComponentType> = NewMessageView as any; +const ForwardMessageViewScreen = ForwardMessageView as any; +const E2ESaveYourPasswordViewScreen: ComponentType> = E2ESaveYourPasswordView as any; +const E2EHowItWorksViewScreen = E2EHowItWorksView as any; +const StatusViewScreen: ComponentType> = StatusView as any; +const CallViewScreen: ComponentType> = CallView as any; +const QueueListViewScreen: ComponentType> = QueueListView as any; + +// Explicit param types so the TNavigation screens keep precise route params instead of inferred `any`. +const PickerViewScreen: ComponentType> = PickerView as any; +const ForwardLivechatViewScreen: ComponentType> = + ForwardLivechatView as any; +const AttachmentViewScreen: ComponentType> = AttachmentView as any; + +const ChatsStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + RoomsListView, + RoomView: RoomViewScreen, + RoomActionsView: createNativeStackScreen({ + screen: RoomActionsViewScreen, + options: (args: any): NativeStackNavigationOptions => (RoomActionsView as any).navigationOptions(args) + }), + SelectListView: SelectListViewScreen, + RoomInfoView: RoomInfoViewScreen, + ReportUserView: ReportUserViewScreen, + RoomInfoEditView: RoomInfoEditViewScreen, + ChangeAvatarView: ChangeAvatarViewScreen, + RoomMembersView: RoomMembersViewScreen, + DiscussionsView: DiscussionsViewScreen, + SearchMessagesView: createNativeStackScreen({ + screen: SearchMessagesViewScreen, + options: (args: any): NativeStackNavigationOptions => (SearchMessagesView as any).navigationOptions(args) + }), + SelectedUsersView: SelectedUsersViewScreen, + InviteUsersView: InviteUsersViewScreen, + InviteUsersEditView: InviteUsersEditViewScreen, + MessagesView: MessagesViewScreen, + AutoTranslateView: AutoTranslateViewScreen, + DirectoryView: DirectoryViewScreen, + NotificationPrefView: NotificationPrefViewScreen, + E2EEToggleRoomView: E2EEToggleRoomViewScreen, + PushTroubleshootView: PushTroubleshootViewScreen, + ForwardLivechatView: ForwardLivechatViewScreen, + CloseLivechatView: CloseLivechatViewScreen, + LivechatEditView: LivechatEditViewScreen, + PickerView: PickerViewScreen, + ThreadMessagesView: ThreadMessagesViewScreen, + TeamChannelsView: TeamChannelsViewScreen, + CreateChannelView: CreateChannelViewScreen, + AddChannelTeamView: AddChannelTeamViewScreen, + AddExistingChannelView: AddExistingChannelViewScreen, + ReadReceiptsView: createNativeStackScreen({ + screen: ReadReceiptsViewScreen, + options: (args: any): NativeStackNavigationOptions => (ReadReceiptsView as any).navigationOptions(args) + }), + QueueListView: QueueListViewScreen, + CannedResponsesListView: CannedResponsesListViewScreen, + CannedResponseDetail: CannedResponseDetailScreen, + JitsiMeetView: createNativeStackScreen({ + screen: JitsiMeetViewScreen, + options: { headerShown: false, animation: isIOS ? 'default' : 'none' } + }) + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); - return ( - - - - - {/* @ts-ignore */} - - - - {/* @ts-ignore */} - - - - {/* @ts-ignore */} - - - - {/* @ts-ignore */} - - - - - {/* @ts-ignore */} - - - - - - {/* @ts-ignore */} - - {/* @ts-ignore */} - - - {/* @ts-ignore */} - - - - - - {/* @ts-ignore */} - - - - - - - ); -}; + return ; +}); -// ProfileStackNavigator -const ProfileStack = createNativeStackNavigator(); -const ProfileStackNavigator = () => { +const ProfileStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + ProfileView: ProfileViewScreen, + ChangePasswordView: ChangePasswordViewScreen, + UserPreferencesView: UserPreferencesViewScreen, + ChangeAvatarView: ChangeAvatarViewScreen, + UserNotificationPrefView: UserNotificationPrefViewScreen, + PushTroubleshootView: PushTroubleshootViewScreen, + PickerView: PickerViewScreen + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); - return ( - - - - - - - - - - ); -}; + return ; +}); -// SettingsStackNavigator -const SettingsStack = createNativeStackNavigator(); -const SettingsStackNavigator = () => { +const SettingsStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + SettingsView: SettingsViewScreen, + SecurityPrivacyView: SecurityPrivacyViewScreen, + PushTroubleshootView: PushTroubleshootViewScreen, + E2EEncryptionSecurityView: E2EEncryptionSecurityViewScreen, + LanguageView: LanguageViewScreen, + DefaultBrowserView: DefaultBrowserViewScreen, + MediaAutoDownloadView: MediaAutoDownloadViewScreen, + GetHelpView: GetHelpViewScreen, + LegalView: LegalViewScreen, + ScreenLockConfigView: createNativeStackScreen({ + screen: ScreenLockConfigViewScreen, + options: (): NativeStackNavigationOptions => (ScreenLockConfigView as any).navigationOptions() + }) + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + return ; +}); - return ( - - - - - - - - - - {/* @ts-ignore */} - - - - ); -}; - -// AdminPanelStackNavigator -const AdminPanelStack = createNativeStackNavigator(); -const AdminPanelStackNavigator = () => { +const AdminPanelStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + AdminPanelView: AdminPanelViewScreen + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + return ; +}); - return ( - - - - ); -}; - -// AccessibilityStackNavigator -const AccessibilityStack = createNativeStackNavigator(); -const AccessibilityStackNavigator = () => { +const AccessibilityStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + AccessibilityAndAppearanceView: AccessibilityAndAppearanceViewScreen, + DisplayPrefsView: DisplayPrefsViewScreen, + ThemeView: ThemeViewScreen + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); - return ( - - - - - - ); -}; + return ; +}); -// DrawerNavigator -const Drawer = createDrawerNavigator(); -const DrawerNavigator = () => { +const DrawerStack = createDrawerNavigator({ + screenOptions: { + swipeEnabled: false, + headerShown: false, + drawerPosition: I18nManager.isRTL ? 'right' : 'left', + drawerType: 'slide', + freezeOnBlur: true + }, + screens: { + ChatsStackNavigator: ChatsStack, + ProfileStackNavigator: ProfileStack, + SettingsStackNavigator: SettingsStack, + AdminPanelStackNavigator: AdminPanelStack, + AccessibilityStackNavigator: AccessibilityStack + } +}).with(({ Navigator }) => { 'use memo'; const { colors } = useContext(ThemeContext); - return ( - } - screenOptions={{ - swipeEnabled: false, - headerShown: false, - drawerPosition: I18nManager.isRTL ? 'right' : 'left', - drawerType: 'slide', - overlayColor: `rgba(0,0,0,${colors.backdropOpacity})`, - freezeOnBlur: true - }}> - - - - - - + } + screenOptions={{ overlayColor: `rgba(0,0,0,${colors.backdropOpacity})` }} + /> ); -}; +}); -// NewMessageStackNavigator -const NewMessageStack = createNativeStackNavigator(); -const NewMessageStackNavigator = () => { +const NewMessageStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + NewMessageView: NewMessageViewScreen, + SelectedUsersView: SelectedUsersViewScreen, + CreateChannelView: CreateChannelViewScreen, + CreateDiscussionView: CreateDiscussionViewScreen, + ForwardMessageView: ForwardMessageViewScreen + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + return ; +}); - return ( - - - - - {/* @ts-ignore */} - - - - ); -}; - -// E2ESaveYourPasswordStackNavigator -const E2ESaveYourPasswordStack = createNativeStackNavigator(); -const E2ESaveYourPasswordStackNavigator = () => { +const E2ESaveYourPasswordStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + E2ESaveYourPasswordView: E2ESaveYourPasswordViewScreen, + E2EHowItWorksView: E2EHowItWorksViewScreen + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + return ; +}); - return ( - - - - - ); -}; - -// E2EEnterYourPasswordStackNavigator -const E2EEnterYourPasswordStack = createNativeStackNavigator(); -const E2EEnterYourPasswordStackNavigator = () => { +const E2EEnterYourPasswordStack = createNativeStackNavigator({ + screenOptions: defaultHeader, + screens: { + E2EEnterYourPasswordView: E2EEnterYourPasswordViewScreen, + E2EEncryptionSecurityView: E2EEncryptionSecurityViewScreen + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + return ; +}); - return ( - - - - - ); -}; - -// InsideStackNavigator -const InsideStack = createNativeStackNavigator(); -const InsideStackNavigator = () => { +const InsideStack = createNativeStackNavigator({ + screenOptions: { ...defaultHeader, presentation: 'containedModal' }, + screens: { + DrawerNavigator: createNativeStackScreen({ + screen: DrawerStack, + options: { headerShown: false } + }), + NewMessageStackNavigator: createNativeStackScreen({ + screen: NewMessageStack, + options: { headerShown: false } + }), + E2ESaveYourPasswordStackNavigator: createNativeStackScreen({ + screen: E2ESaveYourPasswordStack, + options: { headerShown: false } + }), + E2EEnterYourPasswordStackNavigator: createNativeStackScreen({ + screen: E2EEnterYourPasswordStack, + options: { headerShown: false } + }), + AttachmentView: AttachmentViewScreen, + StatusView: StatusViewScreen, + ShareView: ShareViewScreen, + ModalBlockView: createNativeStackScreen({ + screen: ModalBlockViewScreen, + options: (args: any): NativeStackNavigationOptions => (ModalBlockView as any).navigationOptions(args) + }), + CallView: createNativeStackScreen({ + screen: CallViewScreen, + options: { headerShown: false } + }) + } +}).with(({ Navigator }) => { 'use memo'; const { theme } = useContext(ThemeContext); + return ; +}); - return ( - - - - - - - - {/* @ts-ignore */} - - {/* @ts-ignore */} - - - - ); -}; +const InsideStackScreen = InsideStack.getComponent(); -export default InsideStackNavigator; +export default InsideStackScreen; diff --git a/app/stacks/types.ts b/app/stacks/types.ts index 56cf34e8fb0..8c1b6608281 100644 --- a/app/stacks/types.ts +++ b/app/stacks/types.ts @@ -19,6 +19,8 @@ import { import { type ModalStackParamList } from './MasterDetailStack/types'; import { type TNavigation } from './stackType'; +// Hand-written rather than StaticParamList-inferred: views use composite navigation props spanning +// cross-stack destinations (ModalStackNavigator, E2E stacks), and explicit params avoid implicit `any`. export type ChatsStackParamList = { ModalStackNavigator: NavigatorScreenParams; E2ESaveYourPasswordStackNavigator: NavigatorScreenParams; @@ -43,7 +45,7 @@ export type ChatsStackParamList = { usedCannedResponse?: string; status?: string; } - | undefined; // Navigates back to RoomView already on stack + | undefined; RoomActionsView: { room: TSubscriptionModel; member?: any; @@ -135,7 +137,7 @@ export type ChatsStackParamList = { }; LivechatEditView: { room: ISubscription; - roomUser: any; // TODO: Change + roomUser: any; }; ThreadMessagesView: { rid: string; @@ -146,7 +148,7 @@ export type ChatsStackParamList = { joined: boolean; }; CreateChannelView: { - isTeam?: boolean; // TODO: To check + isTeam?: boolean; teamId?: string; }; AddChannelTeamView: { @@ -201,6 +203,8 @@ export type ProfileStackParamList = { ChangePasswordView: undefined; }; +// Cross-stack entries (ProfileView, DisplayPrefsView, AccessibilityAndAppearanceView) are reachable +// from SettingsView via the drawer/accessibility stack. export type SettingsStackParamList = { LegalView: undefined; SettingsView: undefined; @@ -248,9 +252,9 @@ export type NewMessageStackParamList = { buttonText?: string; nextAction?: Function; showSkipText?: boolean; - }; // TODO: Change + }; CreateChannelView?: { - isTeam?: boolean; // TODO: To check + isTeam?: boolean; teamId?: string; }; CreateDiscussionView: { @@ -294,7 +298,7 @@ export type InsideStackParamList = { startShareView: () => { text: string; selectedMessages: string[] }; }; ModalBlockView: { - data: any; // TODO: Change; + data: any; }; CallView: undefined; }; From a011c539e5a35d7b1bcdf5320a772e8edf0d2f0f Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Tue, 23 Jun 2026 16:54:10 -0300 Subject: [PATCH 6/6] fix: wrap E2EEToggleRoomView with withNavigation for static API Claude-Session: https://claude.ai/code/session_018nK6uvMdFctev5Q3cK8NND --- app/stacks/InsideStack.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/stacks/InsideStack.tsx b/app/stacks/InsideStack.tsx index 7b4a5306a1a..2884044d1a4 100644 --- a/app/stacks/InsideStack.tsx +++ b/app/stacks/InsideStack.tsx @@ -115,7 +115,7 @@ const SelectedUsersViewScreen = SelectedUsersView as any; const InviteUsersEditViewScreen = InviteUsersEditView as any; const AutoTranslateViewScreen = AutoTranslateView as any; const NotificationPrefViewScreen = NotificationPrefView as any; -const E2EEToggleRoomViewScreen = E2EEToggleRoomView as any; +const E2EEToggleRoomViewScreen = withNavigation(E2EEToggleRoomView as any) as any; const CloseLivechatViewScreen = CloseLivechatView as any; const CreateChannelViewScreen = CreateChannelView as any; const AddChannelTeamViewScreen = AddChannelTeamView as any;