feat: upgrade React Native to 0.84.1 with native tabs and scan overlay#420
feat: upgrade React Native to 0.84.1 with native tabs and scan overlay#420ignaciosantise wants to merge 13 commits intomainfrom
Conversation
- Upgrade React Native from 0.82.0 to 0.84.1 - Upgrade React from 19.1.1 to 19.2.3 - Integrate react-native-bottom-tabs (1.1.0) + @bottom-tabs/react-navigation (1.1.0) for native platform tab bars - Use native UITabBarController on iOS (Liquid Glass on iOS 26+) and Material BottomNavigationView on Android - Use SF Symbols for iOS tab icons (wallet.bifold.fill, square.stack.3d.up.fill, gearshape.fill) - Keep SVG icons for Android fallback (tab-wallet.svg, tab-connections.svg, tab-settings.svg) - Add 1px border-primary divider above Android tab bar via sceneStyle borderBottomWidth - Update Android theme to Material3.DayNight.NoActionBar for native tab bar compatibility - Fix React 19.2 dev-mode crash with valtio Proxy objects via postinstall patch script (patch-react-dev.sh) - Move Modal inside NavigationContainer and Toast outside for correct native view hierarchy - Add hapticFeedbackEnabled for tab press haptic feedback - Bump react-native-reanimated to ^4.2.2 and react-native-worklets to 0.7.4 for RN 0.84.1 compatibility Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Disable sendDefaultPii in Sentry to prevent auto-attaching IP/headers - Sanitize symKey from WalletConnect deep link URLs before logging - Make patch-react-dev.sh cross-platform (BSD/GNU sed) with patch validation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Set scrollEdgeAppearance to opaque to prevent the translucent tab bar from briefly showing a lighter blur during tab transitions in dark mode. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Disable translucent tab bar (liquid glass) due to dark mode flash issue - Convert postinstall sed script to proper yarn patch for react-native - Restore __DEV__ logging in LogStore (root cause fixed by patch) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sync native iOS color scheme with app theme via Appearance.setColorScheme() so native UIKit/SwiftUI components (tab bar) respect dark mode during transitions. Also bump react-navigation and react-native-screens. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use createNativeStackNavigator for native iOS headers with back chevron on Logs and SecretPhrase screens. Remove @react-navigation/stack which is no longer imported anywhere. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make the selected tab pill/circle transparent by overriding colorSecondaryContainer in the app theme. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rners Redesign the scan camera view with a dark overlay, rounded square cutout, white corner brackets, and close button matching the Figma design. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @ignaciosantise's task in 54s —— View job PR Review: feat/rn-update
🚨 PR Too Large Files: 26 Lines: 3,901 Severity: HIGH Category: maintainability This PR bundles several independent concerns. Suggested splits:
Found 6 issue(s)Issue 1: Potential crash when no codes scannedID: scan-codes-null-crash-a3f1 Context:
Recommendation: const onCodeScanned = (codes: Code[]) => {
const uri = codes[0]?.value;
if (!uri) return;
haptics.scanSuccess();
navigation.navigate('Home', { screen: 'Connections', params: { uri } });
};Issue 2: Static Dimensions break scan overlay on orientation change / foldablesID: scan-dimensions-static-module-b7c2 Context:
Recommendation: Use import { useWindowDimensions } from 'react-native';
export default function Scan({ navigation }: Props) {
const { width: screenWidth, height: screenHeight } = useWindowDimensions();
const scanAreaLeft = (screenWidth - SCAN_AREA_SIZE) / 2;
const scanAreaTop = (screenHeight - SCAN_AREA_SIZE) / 3;
// ...
}Issue 3:
|
There was a problem hiding this comment.
Pull request overview
Upgrades the wallets/rn_cli_wallet React Native app to RN 0.84.1 / React 19.2.3, introduces native bottom tabs via react-native-bottom-tabs, and updates the Scan UI with a new overlay/frame while adjusting Modal/Toast placement for correct z-ordering.
Changes:
- Bump RN/React and related ecosystem deps (Reanimated/Worklets/Valtio/React Navigation), plus a Yarn patch for a dev-mode RN renderer issue.
- Replace JS bottom tabs with native tabs (
@bottom-tabs/react-navigation) and update navigation stack types/structure. - Redesign the Scan screen overlay + add a reusable
ScannerFramecomponent; move Modal/Toast positioning.
Reviewed changes
Copilot reviewed 19 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Adds a top-level Yarn v1 lockfile header (currently empty). |
| wallets/rn_cli_wallet/yarn.lock | Updates dependency lock entries for RN 0.84.1 + new native tabs deps. |
| wallets/rn_cli_wallet/package.json | Bumps RN/React + related deps; adds native bottom tabs packages; updates resolutions/patches. |
| wallets/rn_cli_wallet/src/utils/TypesUtil.ts | Switches stack screen prop typing to native-stack. |
| wallets/rn_cli_wallet/src/store/SettingsStore.ts | Persists theme mode and applies appearance changes on load/set. |
| wallets/rn_cli_wallet/src/store/PaymentStore.ts | Logging formatting change for “cancelled” path. |
| wallets/rn_cli_wallet/src/services/ERC20BalanceService.ts | Formatting/refactor for ABI/Contract creation and call mapping. |
| wallets/rn_cli_wallet/src/screens/Settings/index.tsx | Minor formatting changes; keeps Logs navigation entry. |
| wallets/rn_cli_wallet/src/screens/Scan/styles.ts | Adds dimension-based scan area constants and new layout styles. |
| wallets/rn_cli_wallet/src/screens/Scan/index.tsx | Implements scan overlay/cutout, close button, instruction text, and uses ScannerFrame. |
| wallets/rn_cli_wallet/src/screens/LogList/components/LogFilterSheet.tsx | Minor formatting + eslint suppression for inline styles. |
| wallets/rn_cli_wallet/src/screens/App.tsx | Moves Modal/Toast placement; redacts symKey in deeplink logs; disables Sentry default PII. |
| wallets/rn_cli_wallet/src/navigators/RootStackNavigator.tsx | Migrates to native-stack; introduces custom header for Home; updates back button display mode. |
| wallets/rn_cli_wallet/src/navigators/HomeTabNavigator.tsx | Migrates to native bottom tabs and switches tab icon strategy per platform. |
| wallets/rn_cli_wallet/src/modals/PaymentOptionsModal/ResultView.tsx | Formatting-only change. |
| wallets/rn_cli_wallet/src/modals/PaymentOptionsModal/ExpiryWarningView.tsx | Formatting-only change. |
| wallets/rn_cli_wallet/src/lib/TonLib.ts | Adds eslint suppression for bitwise operation. |
| wallets/rn_cli_wallet/src/components/ScannerFrame.tsx | New SVG-based scanner corner frame component. |
| wallets/rn_cli_wallet/src/components/FadeGradient.tsx | Formatting-only change. |
| wallets/rn_cli_wallet/src/assets/icons/tab-wallet.svg | New Android tab icon asset. |
| wallets/rn_cli_wallet/src/assets/icons/tab-settings.svg | New Android tab icon asset. |
| wallets/rn_cli_wallet/src/assets/icons/tab-connections.svg | New Android tab icon asset. |
| wallets/rn_cli_wallet/ios/RNWeb3Wallet.xcodeproj/project.pbxproj | Adds compile flags (incl. RCT_REMOVE_LEGACY_ARCH) and Swift explicit modules setting. |
| wallets/rn_cli_wallet/android/app/src/main/res/values/styles.xml | Switches app theme to Material3 and adjusts theme colors. |
| wallets/rn_cli_wallet/.yarn/patches/react-native-npm-0.84.1-dev-proxy-fix.patch | Adds a Yarn patch targeting RN dev renderer behavior. |
Comments suppressed due to low confidence (1)
wallets/rn_cli_wallet/src/screens/Scan/index.tsx:46
onCodeScannedassumescodes[0]exists and thatcodes[0].valueis non-null (uri!). If the scanner reports an empty array or a code without avalue, this will throw or navigate with an invalid URI. Add a guard (e.g., return early whencodes.length === 0or when!codes[0].value).
const onCodeScanned = (codes: Code[]) => {
haptics.scanSuccess();
const uri = codes[0].value;
navigation.navigate('Home', {
screen: 'Connections',
params: { uri: uri! },
});
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| const tabWalletIcon = Platform.select({ | ||
| ios: { sfSymbol: 'wallet.bifold.fill' }, | ||
| default: require('@/assets/icons/tab-wallet.svg'), | ||
| }); | ||
|
|
||
| const SettingsIcon = ({ color }: { color: string }) => ( | ||
| <SvgSettingsTab height={24} width={24} fill={color} /> | ||
| ); | ||
| const tabConnectionsIcon = Platform.select({ | ||
| ios: { sfSymbol: 'square.stack.3d.up.fill' }, | ||
| default: require('@/assets/icons/tab-connections.svg'), | ||
| }); | ||
|
|
||
| const NavHeader = () => <Header />; | ||
| const tabSettingsIcon = Platform.select({ | ||
| ios: { sfSymbol: 'gearshape.fill' }, | ||
| default: require('@/assets/icons/tab-settings.svg'), | ||
| }); |
| headerBackButtonDisplayMode: 'minimal', | ||
| headerTintColor: Theme['text-primary'], | ||
| headerTitleStyle: { | ||
| fontWeight: '400', | ||
| }, | ||
| headerTitleStyle, | ||
| cardStyle: { | ||
| backgroundColor: Theme['bg-primary'], | ||
| }} |
| <Defs> | ||
| <ClipPath id="overlay"> | ||
| <Rect x={0} y={0} width={screenWidth} height={screenHeight} /> | ||
| </ClipPath> | ||
| </Defs> |
| import { Button } from '@/components/Button'; | ||
| import { ScannerFrame } from '@/components/ScannerFrame'; | ||
|
|
||
| const { width: screenWidth, height: screenHeight } = Dimensions.get('window'); |
There was a problem hiding this comment.
🤖 Auto Review Issue: Static Dimensions break scan overlay on orientation change / foldables
Severity: MEDIUM
Category: code_quality
Tool: Claude Auto Review
Context:
- Pattern:
screenWidth/screenHeightinindex.tsx:24andscanAreaLeft/scanAreaTopinstyles.ts:4are computed once at module-load time viaDimensions.get('window') - Risk: On orientation change, foldable device fold/unfold, or multi-window mode, the SVG overlay cutout and
scanFrameposition will be misaligned - Impact: The dark overlay cutout won't match the scanner frame
- Trigger: Device rotation or multi-window resize while Scan screen is active
Recommendation: Use useWindowDimensions() inside the component:
import { useWindowDimensions } from 'react-native';
export default function Scan({ navigation }: Props) {
const { width: screenWidth, height: screenHeight } = useWindowDimensions();
const scanAreaLeft = (screenWidth - SCAN_AREA_SIZE) / 2;
const scanAreaTop = (screenHeight - SCAN_AREA_SIZE) / 3;
// ...
}| // Define screen props types | ||
| export type RootStackScreenProps<T extends keyof RootStackParamList> = | ||
| StackScreenProps<RootStackParamList, T>; | ||
| NativeStackScreenProps<RootStackParamList, T>; |
There was a problem hiding this comment.
🤖 Auto Review Issue: RootStackScreenProps type contract change may break screen components
Severity: MEDIUM
Category: breaking_change
Tool: Claude Auto Review
Context:
- Pattern:
RootStackScreenPropschanged fromStackScreenProps(@react-navigation/stack) toNativeStackScreenProps(@react-navigation/native-stack) — these have different navigation prop shapes - Risk: Screen components using Stack-specific navigator APIs (e.g.
navigation.pushoverloads,navigation.reset) could hit TypeScript errors - Impact: All screens importing
RootStackScreenProps—Scan,LogList,SecretPhrase - Trigger: TypeScript compilation; runtime is consistent since the navigator itself was also migrated
Recommendation: Audit all screen components using RootStackScreenProps to confirm they compile cleanly. If any used StackNavigationProp-specific APIs, update to NativeStackNavigationProp equivalents.
| height={screenHeight} | ||
| > | ||
| <Defs> | ||
| <ClipPath id="overlay"> |
There was a problem hiding this comment.
🤖 Auto Review Issue: Unused ClipPath in scan SVG overlay
Severity: LOW
Category: code_quality
Tool: Claude Auto Review
Context:
- Pattern:
<ClipPath id="overlay">defined in<Defs>but never referenced viaclipPath="url(#overlay)"on any element;ClipPathimported but unused - Impact: Dead code; unnecessary import
Recommendation: Remove the <ClipPath> block from <Defs> and remove ClipPath from the react-native-svg import. The fillRule="evenodd" on <Path> already correctly produces the cutout.
Fix this →
…vices Set root view background to match theme so transparent nav bar shows correct color in dark mode. Use screen dimensions with buffer for scan overlay SVG to cover full display including navigation bar area. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ariants Debug builds handled this differently, causing internal/release builds on Firebase to still show a white navigation bar and extra tab padding. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
React Native 0.84's enableEdgeToEdge() sets isNavigationBarContrastEnforced to true, causing a white scrim on the nav bar (visible on Xiaomi/HyperOS). Override it after super.onCreate() to ensure transparent nav bar on all build variants. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
react-native-bottom-tabsfor Liquid Glass support on iOS 26+Architecture
graph TD A[App.tsx] --> B[NavigationContainer] B --> C[RootStackNavigator] B --> D[Modal] A --> E[Toast] C --> F[HomeTabNavigator] C --> G[Scan / Logs / SecretPhrase] F --> H[Native TabView] H -->|iOS| I[UITabBarController + SF Symbols] H -->|Android| J[Material BottomNavigationView + SVG Icons] I -->|iOS 26+| K[Liquid Glass Effect]Key Changes
createNativeBottomTabNavigatorreplaces JS-based bottom tabswallet.bifold.fill,square.stack.3d.up.fill,gearshape.fill), SVG on Androidbg-primarytab bar, 1pxborder-primarydividerpatch-react-dev.shwrapsaddObjectDiffToPropertiesin try/catch for valtio Proxy compatTest plan
🤖 Generated with Claude Code