Skip to content

[GSOC POC bottom tabs navigation]feat: migrate from drawer to bottom tabs navigation with iOS 26 Liqui…#7070

Draft
deepak0x wants to merge 1 commit intoRocketChat:developfrom
deepak0x:feat/bottom-tabs-navigation
Draft

[GSOC POC bottom tabs navigation]feat: migrate from drawer to bottom tabs navigation with iOS 26 Liqui…#7070
deepak0x wants to merge 1 commit intoRocketChat:developfrom
deepak0x:feat/bottom-tabs-navigation

Conversation

@deepak0x
Copy link
Copy Markdown
Contributor

@deepak0x deepak0x commented Mar 28, 2026

Replace DrawerNavigator with native bottom tab navigator using react-native-bottom-tabs for phone layout. Adds 5 tabs: Chats, Discussions, DMs, Search (with iOS 26 expanding search role), and More.

  • Add BottomTabNavigator with SF Symbol icons and sidebarAdaptable
  • Add SearchView with native headerSearchBarOptions
  • Add MoreView for Profile, Settings, Accessibility, Admin
  • Filter RoomsListView by tab via roomFilter route param
  • Patch react-native-bottom-tabs to preserve Liquid Glass on iOS 26
  • Set UIDesignRequiresCompatibility to false for iOS 26 visual features

Proposed changes

Issue(s)

How to test or reproduce

Screenshots

ezyZip.mp4

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

…d Glass

Replace DrawerNavigator with native bottom tab navigator using
react-native-bottom-tabs for phone layout. Adds 5 tabs: Chats,
Discussions, DMs, Search (with iOS 26 expanding search role), and More.

- Add BottomTabNavigator with SF Symbol icons and sidebarAdaptable
- Add SearchView with native headerSearchBarOptions
- Add MoreView for Profile, Settings, Accessibility, Admin
- Filter RoomsListView by tab via roomFilter route param
- Patch react-native-bottom-tabs to preserve Liquid Glass on iOS 26
- Set UIDesignRequiresCompatibility to false for iOS 26 visual features
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 28, 2026

Walkthrough

A new bottom tab navigation system is introduced, replacing drawer-based navigation with five tabs: Home, Discussions, DMs, Search, and More. Each tab manages its own native stack navigator. Chat-related tabs (Home, Discussions, DMs) filter room lists via roomFilter parameter. New SearchView and MoreView screens populate dedicated tabs. Hook signatures are updated to accept optional roomFilter for scoped room data.

Changes

Cohort / File(s) Summary
Navigation Architecture
app/stacks/BottomTabNavigator.tsx, app/stacks/InsideStack.tsx, app/stacks/types.ts
Added new BottomTabNavigator with five tab-organized stacks (HomeStack, DiscussionsStack, DMsStack, SearchStack, MoreStack) each with chat/profile screens. DrawerNavigator now exported. Introduced RoomFilterType and updated navigation type hierarchy with SearchStackParamList, MoreStackParamList, and BottomTabParamList.
Room List Filtering
app/views/RoomsListView/index.tsx, app/views/RoomsListView/hooks/useHeader.tsx, app/views/RoomsListView/hooks/useSubscriptions.ts
RoomsListView now extracts optional roomFilter from route params and passes it to useHeader and useSubscriptions hooks. useHeader derives tab-layout mode and applies tab-specific titles/header actions. useSubscriptions applies tab-level filtering (home/discussions/dms) before subscription data processing.
New Screen Components
app/views/SearchView/index.tsx, app/views/MoreView/index.tsx
Added SearchView with debounced room/DM search and FlatList results display. Added MoreView with navigable items (Profile, Accessibility, Settings) and permission-gated Admin Panel option.
Dependencies & Build Configuration
package.json, patches/react-native-bottom-tabs+1.1.0.patch
Added @bottom-tabs/react-navigation and react-native-bottom-tabs dependencies; updated react-native-screens from ^4.13.1 to 4.16.0. Patched bottom-tabs to conditionally set iOS tab bar unselected item tint color for iOS 26.0+.
iOS Configuration
ios/RocketChatRN.xcodeproj/project.pbxproj, ios/RocketChatRN/Info.plist
Removed quotes from environment variable tokens in Bugsnag shell script phases and Firebase header search paths. Changed UIDesignRequiresCompatibility from true to false.

Sequence Diagram

sequenceDiagram
    participant User
    participant BottomTabNavigator
    participant TabStack as Tab Stack<br/>(HomeStack/DiscussionsStack/DMsStack)
    participant RoomsListView
    participant useSubscriptions
    participant useHeader

    User->>BottomTabNavigator: Tap tab (e.g., Discussions)
    BottomTabNavigator->>TabStack: Render tab with roomFilter param
    TabStack->>RoomsListView: Navigate with roomFilter param
    RoomsListView->>useSubscriptions: Pass roomFilter
    useSubscriptions->>useSubscriptions: Filter subscriptions<br/>(home/discussions/dms)
    useSubscriptions-->>RoomsListView: Return filtered rooms
    RoomsListView->>useHeader: Pass roomFilter
    useHeader->>useHeader: Derive isTabLayout<br/>Set tab-specific title
    useHeader-->>RoomsListView: Return header options
    RoomsListView-->>User: Display filtered room list<br/>with tab-specific header
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested labels

type: feature

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly describes the main change: migrating from drawer to bottom tabs navigation, with a specific iOS 26 consideration noted.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@deepak0x deepak0x changed the title feat: migrate from drawer to bottom tabs navigation with iOS 26 Liqui… [GSOC POC bottom tabs navigation]feat: migrate from drawer to bottom tabs navigation with iOS 26 Liqui… Mar 28, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (1)
app/stacks/BottomTabNavigator.tsx (1)

68-68: Consider adding proper typing for the Stack parameter.

Using any loses type safety. You could create a generic type or use ReturnType<typeof createNativeStackNavigator> to maintain type checking.

♻️ Suggested improvement
-const renderChatScreens = (Stack: any) => (
+const renderChatScreens = <T extends ReturnType<typeof createNativeStackNavigator<ChatsStackParamList & TNavigation>>>(Stack: T) => (

Alternatively, if the above is too complex, at minimum use a more specific type alias.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/stacks/BottomTabNavigator.tsx` at line 68, The parameter Stack of
renderChatScreens is typed as any which removes type safety; change its type to
a navigator stack type (e.g., use ReturnType<typeof createNativeStackNavigator>
or a generic navigator type) so renderChatScreens(Stack) and its children get
correct props; update the function signature for renderChatScreens and add an
appropriate import/type alias referencing createNativeStackNavigator (or a more
specific alias) so TypeScript enforces navigator screen types.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/stacks/BottomTabNavigator.tsx`:
- Around line 235-236: BottomTabNavigator.tsx currently uses iOS-only sfSymbol
in each tabBarIcon (e.g., tabBarIcon: () => ({ sfSymbol: 'house.fill' })), so
update every tabBarIcon definition (the ones using sfSymbol at the listed sites)
to use Platform.select() and return platform-specific icon props: on iOS return
{ type: 'sfSymbol', sfSymbol: '...' } and on Android return { type: 'image',
image: <android resource name> } or { type: 'materialSymbol', name: '...' } as
appropriate; keep the same tabBarIcon property name and symbol intent but
provide an Android alternative for each sfSymbol occurrence.

In `@app/stacks/InsideStack.tsx`:
- Line 324: goRoom.ts unconditionally calls Navigation.popTo('DrawerNavigator')
which crashes when the DrawerNavigator route was removed from InsideStack;
update the goRoom function so the Navigation.popTo('DrawerNavigator') call is
executed only when isMasterDetail is true (i.e., wrap or guard that popTo call
with if (isMasterDetail)), matching the existing conditional logic used
elsewhere and ensuring all room navigation paths (RoomsListView, SearchView,
etc.) do not attempt to pop to a non-existent route.

In `@app/views/MoreView/index.tsx`:
- Around line 14-20: The admin visibility check misses the
'view-user-administration' permission: update the usePermissions call in
MoreView to request 'view-user-administration' (e.g., const
[viewRoomAdministrationPermission, viewStatisticsPermission,
viewPrivilegedSettingPermission, viewUserAdministrationPermission] =
usePermissions([...])) and include the new viewUserAdministrationPermission in
the showAdmin boolean (showAdmin = viewRoomAdministrationPermission ||
viewStatisticsPermission || viewPrivilegedSettingPermission ||
viewUserAdministrationPermission) so users with only user-admin rights see the
Admin panel; adjust variable names to match your naming convention.

In `@app/views/SearchView/index.tsx`:
- Around line 37-49: The debounced handleSearch callback can leave
searching=true when searchMethod rejects; wrap the await searchMethod({ text })
call in a try/catch/finally inside handleSearch (the function created by
useDebounce) so you catch errors, call setResults([]) or keep prior results in
the catch as appropriate, and always call setSearching(false) in finally; also
ensure setHasSearched(true) behavior remains correct and consider logging the
error or surfacing it to the UI inside the catch.

In `@ios/RocketChatRN.xcodeproj/project.pbxproj`:
- Line 1828: The change removed quoting around build path expansions which can
break when resolved paths contain spaces; restore quotes around the affected
build setting usages such as "$TARGET_BUILD_DIR/$INFOPLIST_PATH" and
"$PODS_CONFIGURATION_BUILD_DIR/Firebase" in the project.pbxproj entries to
ensure paths with spaces are handled correctly, updating each occurrence that
was unquoted (the entries referencing $TARGET_BUILD_DIR/$INFOPLIST_PATH and
$PODS_CONFIGURATION_BUILD_DIR/Firebase) so the build script lines wrap the
entire expanded path in double quotes.

In `@ios/RocketChatRN/Info.plist`:
- Around line 111-112: The Info.plist change sets UIDesignRequiresCompatibility
to false enabling iOS 26 visuals before we've updated the UI; revert this
temporary change by restoring UIDesignRequiresCompatibility to true (or removing
the false override) until the app's UI components and styles referenced by your
React Native screens and native iOS views are updated for the iOS 26 design
system (identify and update any custom UI components, storyboards, or
Swift/Objective-C view code), then run visual and functional testing across
supported OS versions (iOS 15.1 through 25.x and a device/simulator on iOS 26)
to confirm correct rendering and behavior; once all UI fixes and cross-version
tests pass, re-apply UIDesignRequiresCompatibility = false and document the
changes and test results.

In `@package.json`:
- Line 27: Tests fail because the package "@bottom-tabs/react-navigation" used
by app/stacks/BottomTabNavigator.tsx has no Jest mock or transform; add a Jest
manual mock or moduleNameMapper entry for "@bottom-tabs/react-navigation" and/or
include it in jest.transformIgnorePatterns so imports resolve during tests.
Specifically, create a manual mock under __mocks__ for the module name or add
mapping in jest.config.js (moduleNameMapper) to point
"@bottom-tabs/react-navigation" to a simple mock module, or update
transformIgnorePatterns to allow transforming this package so
BottomTabNavigator.tsx can import it in tests.
- Line 93: The dependency "react-native-bottom-tabs" is declared with a caret
("^1.1.0") which allows yarn to install 1.1.x and will break patch-package since
the patch file targets +1.1.0; update the package.json dependency entry for
"react-native-bottom-tabs" to the exact version "1.1.0" (remove the caret) so
installed version matches patches/react-native-bottom-tabs+1.1.0.patch and then
re-run install to regenerate the lockfile.

---

Nitpick comments:
In `@app/stacks/BottomTabNavigator.tsx`:
- Line 68: The parameter Stack of renderChatScreens is typed as any which
removes type safety; change its type to a navigator stack type (e.g., use
ReturnType<typeof createNativeStackNavigator> or a generic navigator type) so
renderChatScreens(Stack) and its children get correct props; update the function
signature for renderChatScreens and add an appropriate import/type alias
referencing createNativeStackNavigator (or a more specific alias) so TypeScript
enforces navigator screen types.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 46e4164e-82e1-49b4-8a17-7db44dfca963

📥 Commits

Reviewing files that changed from the base of the PR and between b71ee89 and fcd13e8.

⛔ Files ignored due to path filters (2)
  • ios/Podfile.lock is excluded by !**/*.lock
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (12)
  • app/stacks/BottomTabNavigator.tsx
  • app/stacks/InsideStack.tsx
  • app/stacks/types.ts
  • app/views/MoreView/index.tsx
  • app/views/RoomsListView/hooks/useHeader.tsx
  • app/views/RoomsListView/hooks/useSubscriptions.ts
  • app/views/RoomsListView/index.tsx
  • app/views/SearchView/index.tsx
  • ios/RocketChatRN.xcodeproj/project.pbxproj
  • ios/RocketChatRN/Info.plist
  • package.json
  • patches/react-native-bottom-tabs+1.1.0.patch
📜 Review details
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-03-10T15:21:45.098Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7046
File: app/containers/InAppNotification/NotifierComponent.stories.tsx:46-75
Timestamp: 2026-03-10T15:21:45.098Z
Learning: In `app/containers/InAppNotification/NotifierComponent.tsx` (React Native, Rocket.Chat), `NotifierComponent` is exported as a Redux-connected component via `connect(mapStateToProps)`. The `isMasterDetail` prop is automatically injected from `state.app.isMasterDetail` and does not need to be passed explicitly at call sites or in Storybook stories that use the default (connected) export.

Applied to files:

  • app/views/RoomsListView/index.tsx
  • app/stacks/InsideStack.tsx
  • app/views/MoreView/index.tsx
  • app/stacks/BottomTabNavigator.tsx
📚 Learning: 2026-02-05T13:55:00.974Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6930
File: package.json:101-101
Timestamp: 2026-02-05T13:55:00.974Z
Learning: In this repository, the dependency on react-native-image-crop-picker should reference the RocketChat fork (RocketChat/react-native-image-crop-picker) with explicit commit pins, not the upstream ivpusic/react-native-image-crop-picker. Update package.json dependencies (and any lockfile) to point to the fork URL and a specific commit, ensuring edge-to-edge Android fixes are included. This pattern should apply to all package.json files in the repo that declare this dependency.

Applied to files:

  • package.json
🔇 Additional comments (11)
app/stacks/BottomTabNavigator.tsx (8)

1-66: LGTM!

Imports are well-organized by category (Chat screens, Search, More tab screens) and align with the components used in the navigator stacks below.


127-164: LGTM on the stack structure and roomFilter implementation.

The three chat stacks (HomeStack, DiscussionsStack, DMsStack) correctly pass distinct roomFilter values via initialParams, which aligns with the updated ChatsStackParamList.RoomsListView signature in types.ts.


166-180: LGTM!

The SearchStack is cleanly implemented with appropriate large title styling for iOS.


182-218: LGTM!

The MoreStack appropriately includes profile, settings, and admin screens. The duplicate registrations of ChangeAvatarView, PushTroubleshootView, and PickerView (also in chat stacks) are reasonable since they allow context-specific navigation from both the More tab and room-related flows.


220-275: LGTM on the overall BottomTabNavigator structure.

The five-tab structure (Chats, Discussions, DMs, Search, More) is well-organized with appropriate i18n titles and SF Symbol icons for iOS.


226-229: Verify Android behavior for iOS-specific tab navigator options.

sidebarAdaptable and ignoresTopSafeArea are iOS-specific props added for the iOS 26 Liquid Glass design. Ensure @bottom-tabs/react-navigation gracefully ignores these on Android, and verify the headerShown option works as expected despite the type definition gap.


68-125: Verify stack-aware navigation for screens registered in multiple tab stacks.

The renderChatScreens function registers 30+ screens (including RoomView, ThreadMessagesView, RoomInfoView, RoomActionsView) identically across HomeStack, DiscussionsStack, and DMsStack. Navigation calls like navigation.navigate('ThreadMessagesView', { rid, t }) from within these screens don't specify a parent stack, which could cause unexpected behavior when called from different tabs.

Note: The codebase shows awareness of this issue in certain contexts—RoomView/RightButtons.tsx uses stack-aware navigation (navigation.navigate('ModalStackNavigator', { screen: 'ThreadMessagesView', ... })) for the MasterDetail layout, but standard navigation calls remain unspecified. Consider standardizing navigation to explicitly target the intended stack or clarifying whether React Navigation's default resolution (nearest navigator) is the intended behavior.


259-259: Remove the suggestion to add version compatibility checks for role: 'search'.

The role: 'search' property is a documented screen option in @bottom-tabs/react-navigation (as shown in their official documentation). The library itself handles platform compatibility internally—developers don't need to add conditional version or Platform checks. This property is supported on iOS 18+ and the native implementation gracefully handles older versions and Android through the library's abstraction layer.

			> Likely an incorrect or invalid review comment.
app/stacks/types.ts (3)

22-23: LGTM!

The RoomFilterType union type and optional roomFilter parameter correctly support the tab-based filtering while maintaining backward compatibility with existing navigation calls.

Also applies to: 31-31


244-261: LGTM!

The new param list types are well-structured:

  • SearchStackParamList is minimal and correct
  • MoreStackParamList appropriately combines multiple stack param lists via intersection
  • BottomTabParamList correctly wraps each stack's params with NavigatorScreenParams

299-301: The coexistence of DrawerNavigator and BottomTabNavigator in InsideStackParamList is intentional and correct.

Both navigators are used in a responsive design pattern: InsideStack.tsx implements the phone layout with BottomTabNavigator, while MasterDetailStack implements the tablet layout with DrawerNavigator. Navigation code throughout the codebase correctly switches between them based on the isMasterDetail flag. The shared type definition supports both device configurations without issues.

Comment on lines +235 to +236
tabBarIcon: () => ({ sfSymbol: 'house.fill' })
}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

@bottom-tabs/react-navigation Android icon support sfSymbol

💡 Result:

No, @react-navigation/bottom-tabs does not support SF Symbols (sfSymbol type) on Android. SF Symbols are iOS-only. Official React Navigation documentation explicitly states: - For Native Bottom Tabs Navigator (which uses native BottomNavigationView on Android): tabBarIcon with type: 'sfSymbol' is "Supported on iOS" only. On Android, use type: 'image' with source (images are always tinted). Example from docs: tabBarIcon: Platform.select({ ios: { type: 'sfSymbol', name: 'heart', }, android: { type: 'image', source: require('./path/to/icon.png'), }, }); - Icons docs: sfSymbol (iOS only), materialSymbol (Android only). - Customizing bottom tab bar (v8.x): "SF Symbols name - iOS", "For Android, you can use Material Symbols by setting type: 'materialSymbol'". A GitHub issue confirms users attempting sfSymbol on Android must use 'resource' or images instead. On Android (native impl), active/inactive icon switching with functions is not supported; inactive icon is used for both.

Citations:


Add Android icon handling for all tab bar icons.

sfSymbol is iOS-only and will not display on Android. Use Platform.select() to provide iOS icons with type: 'sfSymbol' and Android icons with type: 'image' (image resource) or type: 'materialSymbol' (Material Symbols).

This applies to all tab bar icons at lines 235-236, 243-244, 251-252, 260-261, and 268-269.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/stacks/BottomTabNavigator.tsx` around lines 235 - 236,
BottomTabNavigator.tsx currently uses iOS-only sfSymbol in each tabBarIcon
(e.g., tabBarIcon: () => ({ sfSymbol: 'house.fill' })), so update every
tabBarIcon definition (the ones using sfSymbol at the listed sites) to use
Platform.select() and return platform-specific icon props: on iOS return { type:
'sfSymbol', sfSymbol: '...' } and on Android return { type: 'image', image:
<android resource name> } or { type: 'materialSymbol', name: '...' } as
appropriate; keep the same tabBarIcon property name and symbol intent but
provide an Android alternative for each sfSymbol occurrence.

return (
<InsideStack.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme), presentation: 'containedModal' }}>
<InsideStack.Screen name='DrawerNavigator' component={DrawerNavigator} options={{ headerShown: false }} />
<InsideStack.Screen name='BottomTabNavigator' component={BottomTabNavigator} options={{ headerShown: false }} />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "All references to DrawerNavigator route name:"
rg -n "['\"]DrawerNavigator['\"]" -C2

echo
echo "InsideStack registered screen names:"
rg -n "InsideStack\\.Screen name=" app/stacks/InsideStack.tsx -C1

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 3870


🏁 Script executed:

# Check the goRoom.ts function and its callers
cat -n app/lib/methods/helpers/goRoom.ts | head -60

echo "---"
echo "Check if goRoom function has isMasterDetail usage:"
rg -B5 -A10 "popTo\('DrawerNavigator'\)" app/lib/methods/helpers/goRoom.ts

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 2730


🏁 Script executed:

# Check what's exported from goRoom and who calls it
echo "=== Exports from goRoom.ts ==="
grep -n "export" app/lib/methods/helpers/goRoom.ts

echo ""
echo "=== Callers of goRoom ==="
rg "from.*goRoom|import.*goRoom" -A2

echo ""
echo "=== Direct calls to navigate from goRoom ==="
rg "popTo\('DrawerNavigator'\)" -B20 | grep -A5 "goRoom"

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 7911


🏁 Script executed:

# Check the full goRoom function
sed -n '85,132p' app/lib/methods/helpers/goRoom.ts

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 1402


🏁 Script executed:

# Check how goRoom is called in a few key callers
echo "=== RoomsListView calling goRoom ==="
rg -B3 -A3 "goRoom\(" app/views/RoomsListView/index.tsx | head -30

echo ""
echo "=== SearchView calling goRoom ==="
rg -B3 -A3 "goRoom\(" app/views/SearchView/index.tsx | head -30

echo ""
echo "=== Check for isMasterDetail usage in these views ==="
rg "isMasterDetail" app/views/RoomsListView/index.tsx | head -10
</parameter>

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 773


🏁 Script executed:

# Find where InsideStack and MasterDetailStack are used
echo "=== InsideStack usage ==="
rg "InsideStack" --type tsx --type ts | grep -v "import" | head -20

echo ""
echo "=== MasterDetailStack usage ==="
rg "MasterDetailStack" --type tsx --type ts | grep -v "import" | head -20

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 209


🏁 Script executed:

# Find where InsideStack and MasterDetailStack are used
echo "=== InsideStack usage ==="
rg "InsideStack" -t typescript -t javascript | grep -v "^.*import" | head -20

echo ""
echo "=== MasterDetailStack usage ==="
rg "MasterDetailStack" -t typescript -t javascript | grep -v "^.*import" | head -20

echo ""
echo "=== Check RootNavigator to see which stack is used based on isMasterDetail ==="
find app -name "*RootNavigator*" -o -name "*root*" -o -name "*Root*" | grep -i nav

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 303


🏁 Script executed:

# Find where InsideStack and MasterDetailStack are referenced
echo "=== InsideStack usage ==="
rg "InsideStack" | grep -v "^.*:.*import" | head -20

echo ""
echo "=== MasterDetailStack usage ==="
rg "MasterDetailStack" | grep -v "^.*:.*import" | head -20

echo ""
echo "=== List app/stacks directory ==="
ls -la app/stacks/

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 2950


🏁 Script executed:

# Check AppContainer to understand when each stack is used
echo "=== AppContainer navigation setup ==="
cat -n app/AppContainer.tsx | grep -B10 -A10 "MasterDetailStack\|InsideStack"

echo ""
echo "=== Check if there's conditional rendering based on isMasterDetail ==="
rg -B5 -A5 "isMasterDetail.*?" app/AppContainer.tsx | head -40

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 4271


Critical: goRoom.ts unconditionally targets removed DrawerNavigator route, causing runtime crashes in non-master-detail mode.

Line 324 removes DrawerNavigator from InsideStack, but goRoom.ts line 46 unconditionally calls Navigation.popTo('DrawerNavigator') regardless of isMasterDetail state. When isMasterDetail=false, the app uses InsideStack (not MasterDetailStack), and any call to goRoom() will crash attempting to pop to a non-existent route. This affects all room navigation (RoomsListView, SearchView, etc.) in non-master-detail mode.

The popTo call must be guarded by if (isMasterDetail) to match the conditional logic at line 47.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/stacks/InsideStack.tsx` at line 324, goRoom.ts unconditionally calls
Navigation.popTo('DrawerNavigator') which crashes when the DrawerNavigator route
was removed from InsideStack; update the goRoom function so the
Navigation.popTo('DrawerNavigator') call is executed only when isMasterDetail is
true (i.e., wrap or guard that popTo call with if (isMasterDetail)), matching
the existing conditional logic used elsewhere and ensuring all room navigation
paths (RoomsListView, SearchView, etc.) do not attempt to pop to a non-existent
route.

Comment on lines +14 to +20
const [viewRoomAdministrationPermission, viewStatisticsPermission, viewPrivilegedSettingPermission] = usePermissions([
'view-room-administration',
'view-statistics',
'view-privileged-setting'
]);
const showAdmin = viewRoomAdministrationPermission || viewStatisticsPermission || viewPrivilegedSettingPermission;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Admin gate misses view-user-administration permission.

This diverges from app/views/SidebarView/components/Admin.tsx (Lines 14-35), so users with only user-admin permission may not see Admin_Panel in More.

🔧 Proposed fix
-	const [viewRoomAdministrationPermission, viewStatisticsPermission, viewPrivilegedSettingPermission] = usePermissions([
+	const [viewRoomAdministrationPermission, viewStatisticsPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission] =
+		usePermissions([
 		'view-room-administration',
 		'view-statistics',
+		'view-user-administration',
 		'view-privileged-setting'
-	]);
-	const showAdmin = viewRoomAdministrationPermission || viewStatisticsPermission || viewPrivilegedSettingPermission;
+		]);
+	const showAdmin = [
+		viewRoomAdministrationPermission,
+		viewStatisticsPermission,
+		viewUserAdministrationPermission,
+		viewPrivilegedSettingPermission
+	].some(Boolean);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [viewRoomAdministrationPermission, viewStatisticsPermission, viewPrivilegedSettingPermission] = usePermissions([
'view-room-administration',
'view-statistics',
'view-privileged-setting'
]);
const showAdmin = viewRoomAdministrationPermission || viewStatisticsPermission || viewPrivilegedSettingPermission;
const [viewRoomAdministrationPermission, viewStatisticsPermission, viewUserAdministrationPermission, viewPrivilegedSettingPermission] =
usePermissions([
'view-room-administration',
'view-statistics',
'view-user-administration',
'view-privileged-setting'
]);
const showAdmin = [
viewRoomAdministrationPermission,
viewStatisticsPermission,
viewUserAdministrationPermission,
viewPrivilegedSettingPermission
].some(Boolean);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/views/MoreView/index.tsx` around lines 14 - 20, The admin visibility
check misses the 'view-user-administration' permission: update the
usePermissions call in MoreView to request 'view-user-administration' (e.g.,
const [viewRoomAdministrationPermission, viewStatisticsPermission,
viewPrivilegedSettingPermission, viewUserAdministrationPermission] =
usePermissions([...])) and include the new viewUserAdministrationPermission in
the showAdmin boolean (showAdmin = viewRoomAdministrationPermission ||
viewStatisticsPermission || viewPrivilegedSettingPermission ||
viewUserAdministrationPermission) so users with only user-admin rights see the
Admin panel; adjust variable names to match your naming convention.

Comment on lines +37 to +49
const handleSearch = useDebounce(async (text: string) => {
if (!text.trim()) {
setResults([]);
setSearching(false);
setHasSearched(false);
return;
}
setSearching(true);
setHasSearched(true);
const result = await searchMethod({ text });
setResults(result as IRoomItem[]);
setSearching(false);
}, 300);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle search failures to prevent a stuck loading state.

At Line 46, a rejected searchMethod call skips Line 48, leaving searching true and surfacing an unhandled promise rejection.

🔧 Proposed fix
 	const handleSearch = useDebounce(async (text: string) => {
 		if (!text.trim()) {
 			setResults([]);
 			setSearching(false);
 			setHasSearched(false);
 			return;
 		}
 		setSearching(true);
 		setHasSearched(true);
-		const result = await searchMethod({ text });
-		setResults(result as IRoomItem[]);
-		setSearching(false);
+		try {
+			const result = await searchMethod({ text });
+			setResults(result as IRoomItem[]);
+		} catch {
+			setResults([]);
+		} finally {
+			setSearching(false);
+		}
 	}, 300);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleSearch = useDebounce(async (text: string) => {
if (!text.trim()) {
setResults([]);
setSearching(false);
setHasSearched(false);
return;
}
setSearching(true);
setHasSearched(true);
const result = await searchMethod({ text });
setResults(result as IRoomItem[]);
setSearching(false);
}, 300);
const handleSearch = useDebounce(async (text: string) => {
if (!text.trim()) {
setResults([]);
setSearching(false);
setHasSearched(false);
return;
}
setSearching(true);
setHasSearched(true);
try {
const result = await searchMethod({ text });
setResults(result as IRoomItem[]);
} catch {
setResults([]);
} finally {
setSearching(false);
}
}, 300);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/views/SearchView/index.tsx` around lines 37 - 49, The debounced
handleSearch callback can leave searching=true when searchMethod rejects; wrap
the await searchMethod({ text }) call in a try/catch/finally inside handleSearch
(the function created by useDebounce) so you catch errors, call setResults([])
or keep prior results in the catch as appropriate, and always call
setSearching(false) in finally; also ensure setHasSearched(true) behavior
remains correct and consider logging the error or surfacing it to the UI inside
the catch.

);
inputPaths = (
"$TARGET_BUILD_DIR/$INFOPLIST_PATH",
$TARGET_BUILD_DIR/$INFOPLIST_PATH,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Removing quotes from paths may cause issues if paths contain spaces.

The quotes were removed from $TARGET_BUILD_DIR/$INFOPLIST_PATH (Lines 1828, 1848) and $PODS_CONFIGURATION_BUILD_DIR/Firebase (Lines 2596, 2672). While this typically works in standard configurations, unquoted paths can break if the resolved values contain spaces (e.g., custom derived data directories or user paths with spaces).

This is low-risk in most environments but worth verifying on your CI/CD setup.

Also applies to: 1848-1848, 2596-2596, 2672-2672

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ios/RocketChatRN.xcodeproj/project.pbxproj` at line 1828, The change removed
quoting around build path expansions which can break when resolved paths contain
spaces; restore quotes around the affected build setting usages such as
"$TARGET_BUILD_DIR/$INFOPLIST_PATH" and "$PODS_CONFIGURATION_BUILD_DIR/Firebase"
in the project.pbxproj entries to ensure paths with spaces are handled
correctly, updating each occurrence that was unquoted (the entries referencing
$TARGET_BUILD_DIR/$INFOPLIST_PATH and $PODS_CONFIGURATION_BUILD_DIR/Firebase) so
the build script lines wrap the entire expanded path in double quotes.

Comment on lines 111 to +112
<key>UIDesignRequiresCompatibility</key>
<true/>
<false/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

What is UIDesignRequiresCompatibility in iOS Info.plist and what does setting it to false do?

💡 Result:

UIDesignRequiresCompatibility is a Boolean key in an iOS app's Info.plist file. It indicates whether the system should run the app in a compatibility mode for UI elements. When set to YES (true), the system uses compatibility mode, displaying the app's UI as it would appear when built against previous SDK versions, opting out of new UI designs like iOS 26's "Liquid Glass". Setting it to false (NO), or omitting it (default for apps linking against the latest SDKs), means the system uses the UI design of the running OS without compatibility mode, applying the latest design changes to standard UI components. Apple warns this key should be used temporarily while updating the app's UI for the latest SDKs.

Citations:


🌐 Web query:

What is iOS Liquid Glass feature and which iOS version introduced it?

💡 Result:

iOS Liquid Glass is a new dynamic design material introduced by Apple that combines the optical properties of glass with fluidity. It is translucent, reflects and refracts surroundings, dynamically adapts to content and context, and is used in controls, navigation, app icons, and system interfaces to create expressive, harmonious experiences across Apple platforms. It was introduced in iOS 26, announced at WWDC 2025 on June 9, 2025, along with iPadOS 26, macOS Tahoe 26, watchOS 26, and tvOS 26.

Citations:


🌐 Web query:

What is the latest iOS version as of March 2026?

💡 Result:

The latest iOS version as of March 28, 2026, is iOS 26.4.

Citations:


🏁 Script executed:

# Check for minimum iOS version in Info.plist
grep -n "MinimumOSVersion\|NSMinimumOSVersion" ios/RocketChatRN/Info.plist

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 60


🏁 Script executed:

# Check for iOS version in project.pbxproj or other Xcode config
fd -e pbxproj -o -e xcconfig | xargs grep -l "IPHONEOS_DEPLOYMENT_TARGET\|MinimumOSVersion" 2>/dev/null | head -5

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 194


🏁 Script executed:

# Find Xcode project files
fd -e pbxproj -o -e xcconfig

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 194


🏁 Script executed:

# Search for deployment target in all project files
rg "IPHONEOS_DEPLOYMENT_TARGET|MinimumOSVersion|mmacosx-version-min" ios/

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 897


🏁 Script executed:

# Check the full Info.plist content around version-related keys
cat -n ios/RocketChatRN/Info.plist | grep -i "version\|deployment\|minimum\|os"

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 701


Verify backward compatibility and complete UI updates for iOS 26.

The change correctly enables iOS 26 Liquid Glass features. However, the app supports iOS 15.1+ (minimum deployment target), creating a 10+ major version gap. Apple's documentation explicitly states that UIDesignRequiresCompatibility = false should be used "temporarily while updating the app's UI for the latest SDKs."

Ensure:

  1. The app's UI has been fully updated to handle iOS 26 design system changes
  2. Behavior has been tested on older supported iOS versions (15.1-25.x) to confirm they render appropriately with their respective OS design systems
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ios/RocketChatRN/Info.plist` around lines 111 - 112, The Info.plist change
sets UIDesignRequiresCompatibility to false enabling iOS 26 visuals before we've
updated the UI; revert this temporary change by restoring
UIDesignRequiresCompatibility to true (or removing the false override) until the
app's UI components and styles referenced by your React Native screens and
native iOS views are updated for the iOS 26 design system (identify and update
any custom UI components, storyboards, or Swift/Objective-C view code), then run
visual and functional testing across supported OS versions (iOS 15.1 through
25.x and a device/simulator on iOS 26) to confirm correct rendering and
behavior; once all UI fixes and cross-version tests pass, re-apply
UIDesignRequiresCompatibility = false and document the changes and test results.

"bugsnag:upload-android": "bugsnag-cli upload react-native-android"
},
"dependencies": {
"@bottom-tabs/react-navigation": "^1.1.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "New bottom-tabs imports:"
rg -n '@bottom-tabs/react-navigation|react-native-bottom-tabs' app/stacks/BottomTabNavigator.tsx -C2

echo
echo "Jest coverage for these modules:"
rg -n '@bottom-tabs/react-navigation|react-native-bottom-tabs' jest.setup.js jest.config.js -C2

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 372


🏁 Script executed:

# Check BottomTabNavigator.tsx to see the imports and usage
cat -n app/stacks/BottomTabNavigator.tsx

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 14002


🏁 Script executed:

# Check current jest.setup.js
cat -n jest.setup.js

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 7218


🏁 Script executed:

# Check current jest.config.js
cat -n jest.config.js

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 924


🏁 Script executed:

# Search for imports of BottomTabNavigator in tests
rg -l 'BottomTabNavigator' --type ts --type tsx | head -20

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 105


🏁 Script executed:

# Check if react-native-bottom-tabs is actually imported anywhere
rg -r 'react-native-bottom-tabs' .

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 50394


🏁 Script executed:

# Search for test files that import BottomTabNavigator
fd -e test.ts -e test.tsx -e spec.ts -e spec.tsx | head -20 | xargs grep -l "BottomTabNavigator" 2>/dev/null || echo "No test files found importing BottomTabNavigator"

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 126


🏁 Script executed:

# Check package.json to see the actual dependencies
cat package.json | grep -A 50 '"dependencies"' | grep -E "(bottom-tabs|react-native-bottom)"

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 122


🏁 Script executed:

# Also check if react-native-bottom-tabs is listed in devDependencies or peerDependencies
cat package.json | grep -A 20 '"devDependencies"' | grep -E "(bottom-tabs|react-native-bottom)"

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 60


Add Jest mock for @bottom-tabs/react-navigation before merge.

@bottom-tabs/react-navigation is imported in app/stacks/BottomTabNavigator.tsx but lacks Jest mock/transform coverage. Tests importing from this file will fail.

🔧 Suggested updates (outside this file)
--- a/jest.setup.js
+++ b/jest.setup.js
@@
+jest.mock('@bottom-tabs/react-navigation', () => {
+	const React = require('react');
+	const MockNavigator = ({ children }) => React.createElement(React.Fragment, null, children);
+	const MockScreen = ({ children }) => React.createElement(React.Fragment, null, children);
+	return {
+		createNativeBottomTabNavigator: () => ({
+			Navigator: MockNavigator,
+			Screen: MockScreen
+		})
+	};
+});
--- a/jest.config.js
+++ b/jest.config.js
@@
-		'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|@rocket.chat/ui-kit)'
+		'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@bottom-tabs/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|@rocket.chat/ui-kit)'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` at line 27, Tests fail because the package
"@bottom-tabs/react-navigation" used by app/stacks/BottomTabNavigator.tsx has no
Jest mock or transform; add a Jest manual mock or moduleNameMapper entry for
"@bottom-tabs/react-navigation" and/or include it in
jest.transformIgnorePatterns so imports resolve during tests. Specifically,
create a manual mock under __mocks__ for the module name or add mapping in
jest.config.js (moduleNameMapper) to point "@bottom-tabs/react-navigation" to a
simple mock module, or update transformIgnorePatterns to allow transforming this
package so BottomTabNavigator.tsx can import it in tests.

"react-native-animatable": "1.3.3",
"react-native-background-timer": "2.4.1",
"react-native-bootsplash": "^6.3.8",
"react-native-bottom-tabs": "^1.1.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Declared dependency:"
node -e 'const p=require("./package.json"); console.log(p.dependencies["react-native-bottom-tabs"])'

echo
echo "Available patch files:"
fd -a 'react-native-bottom-tabs+*.patch' patches

echo
echo "Resolved versions in lockfile (if present):"
if [ -f yarn.lock ]; then
  rg -n 'react-native-bottom-tabs@' yarn.lock -A2 -B1
fi

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 395


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Patches directory structure ==="
if [ -d patches ]; then
  ls -la patches/ | head -20
  echo
  echo "Total patch files:"
  fd -a '.patch$' patches | wc -l
  echo
  echo "All patch filenames:"
  fd -a '.patch$' patches
else
  echo "No patches directory found"
fi

echo
echo "=== Check for patch-package in package.json ==="
rg -A5 '"postinstall"' package.json

echo
echo "=== Check if `@bottom-tabs/react-navigation` exists ==="
node -e 'const p=require("./package.json"); console.log(p.dependencies["@bottom-tabs/react-navigation"] || "not found")'

echo
echo "=== Jest configuration check ==="
if [ -f jest.config.js ]; then
  head -50 jest.config.js
fi

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 3513


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Checking `@bottom-tabs/react-navigation` in node_modules ==="
if [ -d node_modules/@bottom-tabs/react-navigation ]; then
  cat node_modules/@bottom-tabs/react-navigation/package.json | jq '{name, main, module, types, exports}' 2>/dev/null || echo "Failed to parse package.json"
else
  echo "@bottom-tabs/react-navigation not installed"
fi

echo
echo "=== Checking react-native-bottom-tabs in node_modules ==="
if [ -d node_modules/react-native-bottom-tabs ]; then
  cat node_modules/react-native-bottom-tabs/package.json | jq '{name, main, module, types, exports}' 2>/dev/null || echo "Failed to parse package.json"
else
  echo "react-native-bottom-tabs not installed"
fi

echo
echo "=== Check if these packages are used in code ==="
rg '@bottom-tabs/react-navigation|react-native-bottom-tabs' --type ts --type tsx -l src/ 2>/dev/null | head -5 || echo "No imports found in src/"

echo
echo "=== Verify lockfile has both dependencies ==="
rg -B1 -A1 '@bottom-tabs/react-navigation|react-native-bottom-tabs' yarn.lock | head -20

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 1021


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Git status of package.json changes ==="
git diff HEAD -- package.json | grep -A2 -B2 "react-native-bottom-tabs\|@bottom-tabs/react-navigation" || echo "No recent changes in git diff"

echo
echo "=== Check git log for these dependencies ==="
git log --oneline -20 -- package.json | head -10

echo
echo "=== Search for usage in entire codebase ==="
rg '@bottom-tabs/react-navigation|react-native-bottom-tabs' --type-list | head -5
rg '@bottom-tabs/react-navigation|react-native-bottom-tabs' --all-types 2>/dev/null | head -20 || echo "No matches found"

echo
echo "=== Check git status ==="
git status --short package.json patches/ 2>/dev/null | head -10

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 734


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search for actual imports ==="
rg '@bottom-tabs/react-navigation|react-native-bottom-tabs' --no-type-add 2>/dev/null | head -20 || true

echo
echo "=== Check if patches are applied during install ==="
cat package.json | jq '.scripts.postinstall'

echo
echo "=== Look at the actual patch file content ==="
head -30 patches/react-native-bottom-tabs+1.1.0.patch

echo
echo "=== Check yarn.lock resolution behavior ==="
rg -A3 'react-native-bottom-tabs@' yarn.lock
</parameter>

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 1472


Pin react-native-bottom-tabs to an exact version while using patch-package.

Line 93 uses ^1.1.0, which allows yarn to resolve to 1.1.x versions, but the patch file is tied to the exact version +1.1.0 in patches/react-native-bottom-tabs+1.1.0.patch. If the lockfile is regenerated or a minor version bump occurs, the postinstall patch will fail to apply.

🔧 Proposed fix
-		"react-native-bottom-tabs": "^1.1.0",
+		"react-native-bottom-tabs": "1.1.0",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"react-native-bottom-tabs": "^1.1.0",
"react-native-bottom-tabs": "1.1.0",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` at line 93, The dependency "react-native-bottom-tabs" is
declared with a caret ("^1.1.0") which allows yarn to install 1.1.x and will
break patch-package since the patch file targets +1.1.0; update the package.json
dependency entry for "react-native-bottom-tabs" to the exact version "1.1.0"
(remove the caret) so installed version matches
patches/react-native-bottom-tabs+1.1.0.patch and then re-run install to
regenerate the lockfile.

@deepak0x deepak0x marked this pull request as draft March 28, 2026 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant