Commit c83f25f
authored
fix(rewards): modal navigation stack (#32180)
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
<!--
mms-check directive vocabulary — read by
.github/scripts/shared/pr-template-checks.ts
at module load to build the validation plan. Directives are invisible in
rendered
markdown and must NOT be removed or edited without updating the
validator registry.
type=text Section must contain non-placeholder prose.
type=changelog Section must have a valid CHANGELOG entry: line.
type=issue-link Section must have a Fixes:/Closes:/Refs: line with a
value.
type=manual-testing Section must have real testing steps or an explicit
N/A.
type=screenshot Section must have evidence (image/URL) or an explicit
N/A.
type=checklist Section must have all checkboxes consciously checked.
required=true|false Whether a missing/invalid section runs the validator
at all.
blocking=true|false Whether a failure of this check fails the CI
workflow.
Default: false — failures are shown as warnings in the sticky
comment but do not block the PR.
Sections without a directive are checked for structural presence only.
-->
## **Description**
<!-- mms-check: type=text required=true -->
Fixes rewards bottom sheets that briefly navigate to `RewardsDashboard`
(or animate incorrectly) when opened from campaign sub-pages.
### Regression introduced by
[32573f0](32573f0)
(#31227)
That PR migrated Rewards to native stack and **split the navigation
tree**:
**Before `32573f06`**
```
RewardsHome (Rewards tab)
├── REWARDS_VIEW → RewardsNavigator (dashboard + all sub-pages)
└── modal sheets (siblings of REWARDS_VIEW)
```
Campaign pages and modal routes shared the same parent stack.
`navigation.navigate('RewardsSelectSheet')` bubbled up one level and
opened the sheet on top of the current rewards screen.
**After `32573f06`**
```
RewardsHome (Rewards tab)
├── RewardsDashboard / Onboarding
└── modal sheets
MainNavigator (root)
└── REWARDS_FLOW → RewardsNavigator (sub-pages only)
```
Sub-pages moved to root-level `REWARDS_FLOW`, but the five rewards modal
routes stayed in `RewardsHome`. From a campaign page, `navigate()` could
not resolve the route locally, walked up the tree, found it in the
Rewards tab navigator, switched to that tab (showing
`RewardsDashboard`), then opened the sheet.
The same mismatch affects all five rewards modal routes when opened from
`REWARDS_FLOW` (tier selector, settings account group, season-one claim
sheets, etc.).
### Fix in this PR
Move all five rewards modal screens to **root `MainNavigator`**
(alongside `REWARDS_FLOW`) so they are registered once and reachable
from both the Rewards tab and campaign sub-pages:
- `RewardsBottomSheetModal`
- `RewardsClaimBottomSheetModal`
- `RewardOptInAccountGroupModal`
- `EndOfSeasonClaimBottomSheet`
- `RewardsSelectSheet`
`RewardsHome` now only registers the dashboard/onboarding entry screens.
Modal screen options use `clearNativeStackNavigatorOptions` +
`transparentModalScreenOptions`. When modals lived under `RewardsHome`,
they inherited that navigator's default `animation: 'none'`, so only the
`BottomSheet` component animated. At root without `animation: 'none'`,
the native stack slid the entire transparent screen (backdrop included)
from the bottom; adding `clearNativeStackNavigatorOptions` restores the
expected overlay fade + sheet slide behavior.
## **Changelog**
<!-- mms-check: type=changelog required=true blocking=true -->
CHANGELOG entry: null
## **Related issues**
<!-- mms-check: type=issue-link required=true -->
Refs:
32573f0
## **Manual testing steps**
<!-- mms-check: type=manual-testing required=true -->
```gherkin
Feature: Rewards modal navigation from REWARDS_FLOW
Scenario: Ondo campaign tier selector opens in place
Given an opted-in user on an Ondo campaign detail or leaderboard page (REWARDS_FLOW)
When the user taps the tier selector
Then the tier select bottom sheet opens
And the app does not navigate to RewardsDashboard first
And the semitransparent backdrop fades in while only the sheet content slides up
Scenario: Rewards dashboard modals still work
Given an opted-in user on the Rewards dashboard
When the user opens a rewards bottom sheet (e.g. dashboard modal, claim sheet)
Then the sheet opens with correct backdrop and sheet animation
Scenario: Settings account group modal from REWARDS_FLOW
Given an opted-in user on Rewards Settings (REWARDS_FLOW)
When the user taps to show account group addresses
Then the account group modal opens without switching to the Rewards tab first
```
## **Screenshots/Recordings**
<!-- mms-check: type=screenshot required=true -->
N/A — navigation/animation fix; manual verification on device
recommended.
### **Before**
Tier selector on Ondo campaign detail briefly shows `RewardsDashboard`;
backdrop slides up with the sheet when opened from `REWARDS_FLOW`.
### **After**
Sheet opens in place over the current campaign screen; backdrop fades
in, sheet slides up independently.
https://github.com/user-attachments/assets/1c94add1-6d7b-41fd-bea9-e892526e2499
## **Pre-merge author checklist**
<!-- mms-check: type=checklist required=true -->
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [x] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Touches core Rewards navigation and modal presentation; wrong
registration could break deeplinks or sheets from tab vs flow, but scope
is limited to navigator wiring and covered by updated tests.
>
> **Overview**
> Fixes rewards bottom sheets that briefly jumped to
**RewardsDashboard** or used the wrong animation when opened from
**REWARDS_FLOW** campaign sub-pages.
>
> **Navigation:** All five rewards modal routes are removed from the
**Rewards** tab stack (`RewardsHome`) and registered on root
**MainNavigator** next to `REWARDS_FLOW`, so `navigate()` resolves them
without switching tabs. `RewardsHome` now only exposes dashboard vs
onboarding.
>
> **Presentation:** Shared `rewardsModalScreenOptions` is hoisted to
module scope and merges `clearNativeStackNavigatorOptions` with
`transparentModalScreenOptions` so root-level modals keep `animation:
'none'` and only the **BottomSheet** animates (not the full transparent
overlay).
>
> **Tests:** Assert modals are absent from the tab stack and present on
the root navigator.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
fe2ae68. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->1 parent 6ac63f4 commit c83f25f
2 files changed
Lines changed: 71 additions & 32 deletions
File tree
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
196 | 205 | | |
197 | 206 | | |
198 | 207 | | |
| |||
331 | 340 | | |
332 | 341 | | |
333 | 342 | | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
338 | 343 | | |
339 | 344 | | |
340 | 345 | | |
| |||
359 | 364 | | |
360 | 365 | | |
361 | 366 | | |
362 | | - | |
363 | | - | |
364 | | - | |
365 | | - | |
366 | | - | |
367 | | - | |
368 | | - | |
369 | | - | |
370 | | - | |
371 | | - | |
372 | | - | |
373 | | - | |
374 | | - | |
375 | | - | |
376 | | - | |
377 | | - | |
378 | | - | |
379 | | - | |
380 | | - | |
381 | | - | |
382 | | - | |
383 | | - | |
384 | | - | |
385 | | - | |
386 | | - | |
387 | 367 | | |
388 | 368 | | |
389 | 369 | | |
| |||
1050 | 1030 | | |
1051 | 1031 | | |
1052 | 1032 | | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
| 1043 | + | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
| 1052 | + | |
| 1053 | + | |
| 1054 | + | |
| 1055 | + | |
| 1056 | + | |
| 1057 | + | |
1053 | 1058 | | |
1054 | 1059 | | |
1055 | 1060 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1571 | 1571 | | |
1572 | 1572 | | |
1573 | 1573 | | |
1574 | | - | |
1575 | | - | |
1576 | | - | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
1577 | 1577 | | |
1578 | 1578 | | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
1579 | 1613 | | |
1580 | 1614 | | |
1581 | 1615 | | |
| |||
0 commit comments