refactor: migrate InsideStack to React Navigation static config#7415
refactor: migrate InsideStack to React Navigation static config#7415diegolmello wants to merge 2 commits into
Conversation
Converts all 8 nested navigators in InsideStack (ChatsStack, ProfileStack, SettingsStack, AdminPanelStack, AccessibilityStack, DrawerStack, NewMessageStack, E2ESaveYourPasswordStack, E2EEnterYourPasswordStack, InsideStack) from the dynamic JSX API to the static config API. - Class components and function components taking navigation as a prop are wrapped with withNavigation() so useNavigation() provides the prop at the registration site. - Dynamic navigator props (themedHeader, drawerContent, overlayColor) go in .with() callbacks; static screenOptions stay in the config object. - TNavigation screens (PickerView, ForwardLivechatView, AttachmentView) keep precise param-type annotations so StaticParamList preserves the original types. - Record<string,any> annotations (not `any`) are used for param-bearing screens so StaticParamList infers a concrete type rather than unknown/undefined. - types.ts keeps hand-written param list types for ChatsStackParamList and SettingsStackParamList to preserve cross-stack navigation entries and specific route param types relied on by view callback parameter inference. - Default export via InsideStack.getComponent() — AppContainer.tsx is untouched. Claude-Session: https://claude.ai/code/session_012YMKHjug3ZGEibZ1BAGcTx
diegolmello
left a comment
There was a problem hiding this comment.
High-effort code review (NATIVE-1303). Screen-set integrity verified across all 10 navigators: 78 registrations old vs 78 new, exact match — nothing dropped, renamed, duplicated, or moved between navigators. Per-navigator screenOptions split (static defaultHeader + .with() themedHeader(theme)), navigationOptions→options conversions, @ts-ignore removals, withNavigation wrapping, and useAppNavigation/useAppRoute all check out. tsc clean, no snapshot churn.
Two items worth fixing before this stacks the root slice (both inline):
- Three header titles are frozen at app-launch language (static
I18n.t()literals) — a real but low-severity regression vs the old function-formnavigationOptions. - Ten dead derived param-list exports collide by name with the canonical hand-written types and could leak weaker typing into the root slice.
Nits not blocking: double-as any on the SearchMessagesView (line 202) / ModalBlockView (line 402) options callbacks where the .navigationOptions! non-null form (used in MasterDetailStack) is cleaner.
On-device authenticated-flow smoke test remains the verification gate.
| RoomView: RoomViewScreen, | ||
| RoomActionsView: createNativeStackScreen({ | ||
| screen: RoomActionsViewScreen, | ||
| options: { title: I18n.t('Actions') } |
There was a problem hiding this comment.
bug (low): this title is a static object literal, so I18n.t('Actions') is evaluated once at module load and frozen. The pre-migration code passed RoomActionsView.navigationOptions as a function, which React Navigation re-evaluates per render. A non-RTL language change dispatches appStart({ root: ROOT_INSIDE }) without restarting the bundle, so this header (and Read_Receipt at line 224, Screen_lock at line 273) keeps the previous language until a full restart while every other screen updates. MasterDetailStack keeps these as functions for this reason. Suggest options: props => RoomActionsView.navigationOptions!(props) (and the .navigationOptions form for the other two).
| AddExistingChannelView: AddExistingChannelViewScreen, | ||
| ReadReceiptsView: createNativeStackScreen({ | ||
| screen: ReadReceiptsViewScreen, | ||
| options: { title: I18n.t('Read_Receipt') } |
There was a problem hiding this comment.
Same title-staleness as line 191 — I18n.t('Read_Receipt') frozen at module load. Use the function form: options: ReadReceiptsView.navigationOptions.
| LegalView: LegalViewScreen, | ||
| ScreenLockConfigView: createNativeStackScreen({ | ||
| screen: ScreenLockConfigViewScreen, | ||
| options: { title: I18n.t('Screen_lock') } |
There was a problem hiding this comment.
Same title-staleness as line 191 — I18n.t('Screen_lock') frozen at module load. Use the function form: options: ScreenLockConfigView.navigationOptions.
| </InsideStack.Navigator> | ||
| ); | ||
| }; | ||
| export type ChatsStackParamList = StaticParamList<typeof ChatsStack>; |
There was a problem hiding this comment.
slop (moderate): these derived param-list exports are unused — every consumer imports ChatsStackParamList/SettingsStackParamList/etc. from app/stacks/types.ts, and only this file's default export is imported elsewhere. They also duplicate the canonical names with structurally weaker (Record<string,any>-based) types, so a future import from this module (e.g. the root slice) would silently lose the rich param typing. Suggest deleting this block; the per-screen StaticScreenProps<Record<string,any>> annotations above exist only to feed it and can be simplified to plain casts.
FIX 1 (localization regression): convert three static I18n.t() object literals to function-form options so React Navigation re-evaluates per render on language change — RoomActionsView, ReadReceiptsView, and ScreenLockConfigView now delegate to their static navigationOptions. FIX 2 (dead type exports): remove 10 derived StaticParamList exports that collided with the hand-written types in types.ts; simplify the Record<string,any> screen annotations to plain `as any` casts now that derived exports are gone. Remove unused StaticParamList and I18n imports. Claude-Session: https://claude.ai/code/session_01Qh9P8Bbp6V7PFpCY2X5on3
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🧰 Additional context used📓 Path-based instructions (5)**/*.{js,ts,jsx,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{js,jsx,ts,tsx,json}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{js,jsx,ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
app/stacks/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (1)📚 Learning: 2026-04-30T17:07:51.020ZApplied to files:
🔇 Additional comments (2)
Walkthrough
ChangesInsideStack Composition Refactor
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
InsideStack(Drawer, Chats, Profile, Settings, AdminPanel, Accessibility, NewMessage, E2ESaveYourPassword, E2EEnterYourPassword) from the dynamic JSX API to React Navigation 7's static config API.navigationas a prop are wrapped withwithNavigation()souseNavigation()injects it at the registration site.themedHeader,drawerContent,overlayColor) go in.with()callbacks; staticscreenOptionsstay in the config object.TNavigationscreens (PickerView,ForwardLivechatView,AttachmentView) keep precise param-type annotations soStaticParamListpreserves the original types.Record<string, any>(not bareany) annotations on param-bearing screens soStaticParamListinfers a concrete type rather thanunknown/undefined.types.tskeeps hand-written param lists forChatsStackParamListandSettingsStackParamListto preserve cross-stack navigation entries (e.g.ModalStackNavigatorfor the tablet/MasterDetail modal stack) and specific route param types that view callback parameters rely on for type inference.InsideStack.getComponent()—AppContainer.tsxis untouched.Stacks on #7414 (MasterDetailStack static config). Base should retarget to
developonce #7414 merges.Issues
https://rocketchat.atlassian.net/browse/NATIVE-1303
How to test
https://claude.ai/code/session_012YMKHjug3ZGEibZ1BAGcTx
Summary by CodeRabbit