[pull] main from MetaMask:main#792
Merged
Merged
Conversation
…ok and update related components (#30735) <!-- 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. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> Homepage Predict empty-state World Cup discovery was loading markets through a separate path (useHomepagePredictTaggedMarkets → category: 'sports' + hardcoded tag_id=102350), while the dedicated World Cup screen uses usePredictWorldCupMarkets with the ALL tab (buildPredictWorldCupAllQuery → events/keyset?tag_slug=...). This PR aligns the homepage feed with the World Cup screen by introducing useHomepagePredictWorldCupMarkets, which wraps usePredictWorldCupMarkets with PREDICT_WORLD_CUP_TAB_KEYS.ALL and selectPredictWorldCupConfig. The NBA champion discovery feed is unchanged and still uses useHomepagePredictTaggedMarkets. Why: Avoid divergent Polymarket query logic between homepage discovery and the World Cup screen. How: Thin homepage hook + swap the World Cup feed in PredictionsSection; remove the obsolete PREDICT_HOME_WORLD_CUP_TAG_QUERY constant; update types and test mocks. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Fix bug that was causing wrong events number in world cup (predict) section ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Homepage Predict empty state World Cup discovery Scenario: World Cup discovery loads when user has no positions Given Predict is enabled And the user is in the Predict positions empty state AB treatment And the user has no open Predict positions When the user opens the Homepage Predict section Then the World Cup discovery rail renders (event count, bracket pills, championship row) And World Cup markets are fetched via the World Cup ALL-tab keyset query (tag_slug from feature flag config) Scenario: World Cup discovery navigation still works Given the World Cup discovery rail is visible on Homepage When the user taps the men's World Cup row or a bracket pill Then navigation opens the World Cup screen (or Predict market list fallback) with the expected initial tab Scenario: NBA champion row is unaffected Given NBA champion homepage discovery is enabled When the user opens the Homepage Predict empty state Then the NBA champion row still loads via the existing tagged-markets hook ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <img width="403" height="234" alt="Screenshot 2026-05-28 at 13 26 58" src="https://github.com/user-attachments/assets/e26cb906-3a85-4ffc-a961-3ee7c1a29652" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] 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 - [ ] 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** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] 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** > Changes Polymarket fetch logic for a user-visible homepage discovery rail (fixes wrong event counts) but is scoped to Predict UI with tests updated; NBA feed unchanged. > > **Overview** > Homepage Predict **empty-state World Cup discovery** no longer loads markets through `useHomepagePredictTaggedMarkets` with a hardcoded sports `tag_id=102350`. It now uses a new **`useHomepagePredictWorldCupMarkets`** hook that wraps **`usePredictWorldCupMarkets`** on the World Cup **ALL** tab with **`selectPredictWorldCupConfig`**, matching the dedicated World Cup screen’s keyset/`tag_slug` query path. > > **`PredictionsSection`** and the World Cup discovery UI types were switched to that hook; the obsolete World Cup tag constant was removed from **`HOMEPAGE_PREDICT_TAG_QUERIES`**. **NBA champion** discovery still uses tagged markets. Tests and Homepage mocks were updated for the new hook and World Cup feature-flag/hook stubs. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c053706. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- CURSOR_AGENT_PR_BODY_BEGIN -->
## **Description**
Updated the Telegram icon SVG in the component-library to use the
official Telegram logo design (without the tail). This was requested by
the design team to align with the proper Telegram branding requirements
for the Telegram social login feature.
The icon was added to:
- `app/component-library/components/Icons/Icon/assets/telegram.svg`
The icon generation script (`yarn generate-icons`) was run to
regenerate:
- `Icon.types.ts` - Added `Telegram` to `IconName` enum
- `Icon.assets.ts` - Added import and mapping for the Telegram SVG
## **Changelog**
CHANGELOG entry: null
## **Related issues**
Related to Telegram social login implementation.
## **Manual testing steps**
```gherkin
Feature: Telegram icon display
Scenario: user views Telegram icon
Given the app is running with design system components
When user views a component using IconName.Telegram
Then the official Telegram paper plane logo is displayed
```
## **Screenshots/Recordings**
### **Before**
N/A - Icon being added
### **After**
Icon can be verified by importing and using:
```tsx
import { Icon, IconName, IconSize } from '@metamask/design-system-react-native';
<Icon name={IconName.Telegram} size={IconSize.Lg} />
```
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [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)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] 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
- [ ] 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**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] 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_AGENT_PR_BODY_END -->
[Slack
Thread](https://consensys.slack.com/archives/C0354T27M5M/p1777358027891429?thread_ts=1777358027.891429&cid=C0354T27M5M)
<div><a
href="https://cursor.com/agents/bc-e1704607-edb3-5b15-adad-715dacefda4d"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-web-light.png"><img
alt="Open in Web" width="114" height="28"
src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a
href="https://cursor.com/background-agent?bcId=bc-e1704607-edb3-5b15-adad-715dacefda4d"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source
media="(prefers-color-scheme: light)"
srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img
alt="Open in Cursor" width="131" height="28"
src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…lidate header hook (#30714) ## **Description** **For reviewer**: please use this link to better see the diff without formatting changes: https://github.com/MetaMask/metamask-mobile/pull/30714/changes?w=1 **Summary** Migrates the main Card stack (MainRoutes in app/components/UI/Card/routes/index.tsx) from navigator-provided headers (headerLeft / headerRight with ButtonIcon) to in-screen HeaderStandard chrome, matching the pattern already used by Card onboarding via OnboardingStep. Also consolidates the two header hooks (onboarding-only + main) into a single shared useCardHeaderHandlers so every Card screen builds its header from the same primitives. **What changed** New shared hook: useCardHeaderHandlers - app/components/UI/Card/hooks/useCardHeaderHandlers.ts (+ tests) - CardHeaderMode: > back → navigation.goBack() > close-with-confirmation → exit alert → WALLET.HOME > close-direct → WALLET.HOME > close-reset-home → navigation.reset to CARD.HOME > none → no header handlers - Returns props that spread directly into <HeaderStandard ...handlers />. - Close button testID standardized as card-header-close-button. **Removed** - useCardOnboardingNavigationHandlers.ts + its test — replaced by useCardHeaderHandlers. - cardDefaultNavigationOptions, cardChooseYourCardNavigationOptions, cardSpendingLimitNavigationOptions, headerStyle from routes/index.tsx. **Navigator (routes/index.tsx)** - MainRoutes now sets screenOptions={{ headerShown: false }}. - SpendingLimit keeps per-screen options only to disable swipe-back when flow === 'onboarding'. | Screen | Header behavior | | --- | --- | | `CardHome` | `back` (main + error state) | | `ReviewOrder` | `back` | | `OrderCompleted` | `back` | | `Cashback` | `back` | | `CardAuthentication` | `back` (via `OnboardingStep` `headerMode`) | | `ChooseYourCard` | `none` (`flow: onboarding`) / `back` (`upgrade`, `home`); safe-area `edges` adjusted | | `SpendingLimit` | `close-reset-home` (`flow: onboarding`) / `back` (other flows); header in loading, error, and main branches | | `CardWelcome` | Unchanged (no header) | | `OnboardingStep` | Switched to `useCardHeaderHandlers` (types aligned to `CardHeaderMode`) | Android test build: https://github.com/MetaMask/metamask-mobile/actions/runs/26588329872 <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry:null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Card screens render in-screen HeaderStandard chrome Background: Given the user is signed in to the wallet And the user has completed Card onboarding (where required) # ----- CardHome ------------------------------------------------------------- Scenario: CardHome shows a back header in the main state Given the user is on the Wallet home screen When the user opens the Card tab Then the CardHome screen is shown And a back arrow is visible at the top-left of the screen And no duplicate header / no gap is rendered above the content Scenario: Tapping back from CardHome returns the user to the previous screen Given the user is on CardHome When the user taps the back arrow in the header Then the user is returned to the previous screen (Wallet home) Scenario: CardHome error state still shows a back header Given CardHome fails to load and renders the error state Then the back arrow is still visible in the header When the user taps the back arrow Then the user is returned to the previous screen # ----- ReviewOrder / OrderCompleted / Cashback / CardAuthentication --------- Scenario Outline: <screen> shows a back header Given the user navigates to <screen> Then a back arrow is visible at the top-left When the user taps the back arrow Then the user is returned to the previous screen Examples: | screen | | ReviewOrder | | OrderCompleted | | Cashback | | CardAuthentication | # ----- ChooseYourCard ------------------------------------------------------- Scenario: ChooseYourCard in the onboarding flow has no header chrome Given the user is in the Card onboarding flow When the user reaches the ChooseYourCard step Then no back or close button is visible at the top of the screen And the top safe-area inset is respected (no content under the status bar) Scenario Outline: ChooseYourCard outside onboarding shows a back header Given the user opens ChooseYourCard with flow "<flow>" Then a back arrow is visible at the top-left When the user taps the back arrow Then the user is returned to the previous screen Examples: | flow | | upgrade | | home | # ----- SpendingLimit -------------------------------------------------------- Scenario Outline: SpendingLimit outside onboarding shows a back header Given the user opens SpendingLimit with flow "<flow>" Then a back arrow is visible at the top-left And the screen can be dismissed by swiping back (iOS) When the user taps the back arrow Then the user is returned to the previous screen Examples: | flow | | manage | | enable | Scenario: SpendingLimit in the onboarding flow shows a close button that resets to CardHome Given the user is in the Card onboarding flow And the user is on SpendingLimit with flow "onboarding" Then a close (X) button is visible at the top-left And the screen cannot be dismissed by swiping back When the user taps the close button Then the navigator is reset and the user lands on CardHome And the back stack does not contain the SpendingLimit onboarding screen Scenario: SpendingLimit loading and error states render the header Given SpendingLimit is loading Then the header is visible above the loading indicator Given SpendingLimit fails to load Then the header is visible above the error state # ----- Onboarding regression (header behavior unchanged) -------------------- Scenario Outline: Onboarding step header behavior is unchanged Given the user is on the "<step>" onboarding screen Then the header mode "<mode>" is rendered When the user taps the header action Then the expected behavior occurs Examples: | step | mode | | SignUp | back | | ConfirmEmail | back | | PersonalDetails | close-with-confirmation | | PhysicalAddress | close-with-confirmation | | VerifyingVeriffKYC | close-direct | Scenario: Close-with-confirmation prompts before exiting onboarding Given the user is on an onboarding step that uses "close-with-confirmation" When the user taps the close (X) button Then a "leave onboarding?" alert is shown with Cancel and Exit options When the user taps "Cancel" Then the user remains on the current onboarding step When the user taps the close (X) button again and confirms "Exit" Then the user is navigated to Wallet home # ----- Visual / device sanity ---------------------------------------------- Scenario: Headers respect safe area on notched devices Given the device has a top notch / Dynamic Island When the user navigates to any migrated Card screen Then the header sits below the status bar with no overlap and no double inset ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/user-attachments/assets/eabfe621-b661-48e6-bcda-10ed152dee70 ### **After** https://github.com/user-attachments/assets/74a922b3-cfb4-4baa-8c81-834c7aa8aa00 Android test: https://github.com/user-attachments/assets/01826eca-a29b-4766-9d9f-75c50c0a000a <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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 - [ ] 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 - [ ] 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** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [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** > Navigation and exit behavior changed across many Card screens (including onboarding SpendingLimit reset and gesture rules); regressions would mostly affect UX/back-stack, not security or payments. > > **Overview** > Main Card stack screens now render navigation chrome in-screen with **`HeaderStandard`** and a shared **`useCardHeaderHandlers`** hook, instead of stack **`headerLeft` / `headerRight`** options. **`routes/index.tsx`** defaults to **`headerShown: false`** and drops the old per-screen header option helpers; **SpendingLimit** still disables swipe-back when **`flow === 'onboarding'`**. > > **`useCardOnboardingNavigationHandlers`** is removed and replaced by **`useCardHeaderHandlers`**, which adds **`close-reset-home`** (navigator reset to **`CARD.HOME`**) and standardizes the close button testID. **CardHome**, **Cashback**, **ReviewOrder**, **OrderCompleted**, and related flows use **`back`**; **ChooseYourCard** uses **`none`** for onboarding and **`back`** for upgrade/home with safe-area tweaks; **SpendingLimit** uses **`close-reset-home`** vs **`back`** by flow; **OnboardingStep** / **CardAuthentication** wire the same modes. Tests drop navigator-header assertions and mock **`HeaderStandard`** where needed. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3bc157d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- 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. --> ## **Description** * This PR removes the onboarding success animation for Android social-login users to prevent a crash observed shortly after wallet creation <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Fixed a crash affecting some Android social-login users by removing the onboarding success animation in that flow. ## **Related issues** Fixes: #30737 ## **Manual testing steps** ```gherkin Feature: Android social onboarding success stability Scenario: Android social user reaches onboarding success Given user is on Android and signs up via social login When user completes wallet creation and lands on onboarding success Then the onboarding success animation should not render And the app should not crash ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** https://github.com/user-attachments/assets/e13a6a99-88c7-4a02-a5c4-cc8856141d21 <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/7885dfb0-28e9-4193-8fc4-59ab25034c02 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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 - [ ] 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 - [ ] 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** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] 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] > **Low Risk** > Targeted UI guard on an existing onboarding screen; no auth, key material, or navigation reset logic changes beyond skipping one animation. > > **Overview** > Skips the onboarding success end animation on **Android** when navigation passes `showPasswordHint: true` (the social-login path from `ChoosePassword`). The screen still shows the success title and actions; only `OnboardingSuccessEndAnimation` is omitted for that platform/flag combination. > > A new optional route param and component prop wire `showPasswordHint` from the navigator into `OnboardingSuccessComponent`, with `Platform.OS` used to gate the animation. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e352fa2. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description**
This is PR 3 of the GE-217 push pre-prompt rollout.
This PR mounts the push notification onboarding pre-prompt from
`Nav/Main` and wires the production flow for the two currently supported
startup variants:
- `push_permission`: shown to eligible users who have not granted OS
push permission or do not yet have notification preferences.
- `marketing_consent`: shown to eligible existing users with push
notifications enabled but marketing notification preferences disabled.
The prompt resolver now gates display on notification runtime
eligibility, completed onboarding, the default-on feature flag, one-time
“shown” storage, OS push permission status, Authenticated User Storage
notification preferences, and pending social-login marketing-consent
backfill. AUS preference reads stay behind the runtime gate, and
resetting the developer “push pre prompt shown” flag does not
immediately reopen the prompt until the app is restarted.
This PR also adds shared notification preference helpers used by
Settings and startup onboarding, background enablement for the push
pre-prompt path, marketing notification preference updates, toast copy,
and MetaMetrics/identify instrumentation for pre-prompt actions, OS
prompt responses, marketing consent, and push notification enablement.
## **Changelog**
CHANGELOG entry: Added a startup prompt for eligible users to enable
push notifications.
## **Related issues**
Fixes: GE-217
## **Manual testing steps**
```gherkin
Feature: Push notification startup pre-prompt
Scenario: eligible user sees the push permission pre-prompt
Given notifications are enabled for the build
And the user is eligible for the push permission pre-prompt
And the push pre-prompt has not already been shown
When the user launches the app
Then the push notification onboarding sheet is shown
When the user taps "Yes"
Then the native push permission prompt is requested
And the startup surface is completed
And notifications are enabled in the background
Scenario: eligible user dismisses the push permission pre-prompt
Given notifications are enabled for the build
And the user is eligible for the push permission pre-prompt
And the push pre-prompt has not already been shown
When the user launches the app
And the user taps "Not now"
Then the push notification onboarding sheet closes
And the startup surface is completed
Scenario: existing user sees the marketing consent pre-prompt
Given notifications are enabled for the build
And the user already has notification preferences
And the user has not enabled marketing consent
And the push pre-prompt has not already been shown
When the user launches the app
Then the marketing consent onboarding sheet is shown
When the user confirms marketing consent
Then marketing consent is enabled
And the startup surface is completed
```
## Manual Testing Steps
### Preconditions
- Use a build with the notifications feature flag enabled.
- Use a device/simulator where OS notification permissions can be reset.
- After seeing either pre-prompt once, go to **Settings > Developer
options** and tap **Reset push pre prompt shown**, then fully kill and
reopen the app before testing another prompt.
- To force a clean first-run state, delete the app from the device and
install it again.
- To test update behavior, do not delete the app. Install/update the PR
build over an existing installed build so app data is preserved.
---
## Flow 1: New User / Push Permission Pre-Prompt
### Setup
1. Delete the app from the device.
2. Install the PR build.
3. If needed, reset OS notification permission for MetaMask from device
settings.
4. Open the app and complete onboarding with a new wallet or imported
wallet.
5. Keep marketing consent disabled during onboarding if the option is
shown.
6. Finish onboarding and land in the wallet.
### Steps
1. Confirm the push notification pre-prompt appears after onboarding.
2. Confirm the sheet explains push notifications and personalized
updates.
3. Tap **Not now**.
4. Confirm the sheet closes.
5. Confirm a toast appears saying notifications can be enabled later in
**Settings > Notifications**.
6. Go to **Settings > Developer options** and tap **Reset push pre
prompt shown**.
7. Fully kill and reopen the app.
8. Confirm the push notification pre-prompt appears again.
9. Tap **Yes**.
10. Confirm the native OS push notification prompt appears.
11. Tap **Allow**.
12. Confirm the sheet closes.
13. Confirm a success toast appears.
14. Go to **Settings > Notifications**.
15. Confirm notifications are enabled.
16. Confirm the relevant notification categories, including
marketing/updates, are enabled where available.
### Also Verify
- Repeat the **Yes** path and tap **Don’t Allow** on the OS prompt.
- Confirm the app does not crash.
- Confirm the sheet closes and the user sees guidance to enable
notifications later in settings.
---
## Flow 2: Existing User / App Update With Push Enabled But Marketing
Consent Disabled
### Setup
1. Start from an existing installed app with a completed wallet.
2. Do not delete the app.
3. Enable push notifications from **Settings > Notifications**.
4. Disable marketing consent from **Settings > Security & Privacy > Data
collection for marketing**.
5. Install/update to the PR build over the existing app.
6. Open the app and unlock the wallet.
7. If the prompt was already seen, use **Settings > Developer options >
Reset push pre prompt shown**, then fully kill and reopen the app.
### Steps
1. Confirm the existing-user marketing consent pre-prompt appears.
2. Confirm the prompt asks for personalized/marketing updates.
3. Tap **Not now**.
4. Confirm the sheet closes.
5. Confirm marketing consent remains disabled.
6. Confirm push notifications remain enabled.
7. Reset **push pre prompt shown** in Developer options.
8. Fully kill and reopen the app.
9. Confirm the existing-user marketing consent prompt appears again.
10. Tap **Confirm**.
11. Confirm the sheet closes.
12. Confirm a success toast appears.
13. Go to **Settings > Security & Privacy**.
14. Confirm **Data collection for marketing** is enabled.
15. Go to **Settings > Notifications**.
16. Confirm **Updates and Rewards** / marketing notification preferences
are enabled.
---
## Flow 3: Existing User / App Update With Marketing Consent Enabled But
Push Disabled
### Setup
1. Start from an existing installed app with a completed wallet but push
not enabled (also not denied)
2. Do not delete the app.
3. Enable marketing consent from **Settings > Security & Privacy > Data
collection for marketing**.
4. Disable push notifications from device OS settings or **Settings >
Notifications**.
5. Install/update to the PR build over the existing app.
6. Open the app and unlock the wallet.
7. Reset **push pre prompt shown** in Developer options if needed, then
fully kill and reopen.
### Steps
1. Confirm the push permission pre-prompt appears.
2. Tap **Yes**.
3. Confirm the native OS notification prompt appears.
4. Tap **Allow**.
5. Confirm notifications are enabled.
6. Confirm marketing consent remains enabled.
---
## Regression Checks
- The pre-prompt should only show once per install/session unless reset
from Developer options.
- Resetting **push pre prompt shown** should not immediately reopen the
prompt until the app is restarted.
- Deleting and reinstalling the app should allow the new-user flow to be
tested again.
- Updating the app without deleting it should preserve user state and
trigger the correct existing-user flow.
- Users with both push notifications and marketing consent already
enabled should not see either pre-prompt.
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See docs/readme/ready-for-review.md for the full
checklist
semantics.
-->
- [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)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] 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
- [ ] 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**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See docs/readme/ready-for-review.md.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] 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.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Wires Batch Sell quote fetching and quote display into the Batch Sell review flow. This PR replaces the Batch Sell review placeholder state with real batch quote request and quote data handling. It builds per-token quote requests from selected source tokens, allocation amounts, destination stablecoin, slippage, gas-included settings, and wallet address, then sends the batch to `BridgeController`. It also updates the review UI so rows, totals, quote details, and final review consume real quote data. Rows now show batch-level loading states, quote-unavailable states, high-price-impact indicators, per-token slippage settings, and refreshed receive amounts. Allocation sliders update source amounts in Redux and quote requests are debounced to avoid excessive refetching. The destination stablecoin selector now updates the selected stablecoin immediately on row tap, and quote display is guarded so old-destination quotes are treated as stale instead of briefly showing mismatched token or fiat values after switching stablecoins. ## **Changelog** CHANGELOG entry: Added quote fetching and quote review details to Batch Sell. ## **Related issues** Related to: [SWAPS-4439](https://consensyssoftware.atlassian.net/browse/SWAPS-4439) ## **Manual testing steps** ```gherkin Feature: Batch Sell quotes Scenario: user reviews and updates a batch sell quote Given the user has multiple eligible tokens on the same network And the user opens Batch Sell and selects multiple source tokens When the user taps Continue Then the quote screen opens with each allocation defaulted to 100% And token rows and Total received show loading skeletons while quotes load And token rows and Total received show quote amounts after quotes load When the user changes one token allocation with the slider Then all token rows and Total received return to loading while quotes refetch And updated row and total amounts are shown after the refetch completes When the user opens settings for a token row and changes slippage Then quotes are refetched for the batch And updated row and total amounts are shown after the refetch completes When the user changes the destination stablecoin Then stale quotes for the previous stablecoin are hidden And the Review button remains disabled until matching destination quotes load When at least one token has a valid quote and the user taps Review Then the final review sheet opens with only valid quoted tokens reflected in totals ``` ## **Screenshots/Recordings** ### **Before** n/a ### **After** https://github.com/user-attachments/assets/c9193d86-5f53-40c8-a044-57c1e08640bc ## **Automated testing** ```bash yarn jest app/components/UI/Bridge/hooks/useBatchSellQuoteData/useBatchSellQuoteData.test.ts --runInBand --watchman=false --forceExit yarn jest app/components/UI/Bridge/Views/BatchSellReview/BatchSellReview.test.tsx --runInBand --watchman=false --forceExit yarn eslint app/components/UI/Bridge/hooks/useBatchSellQuoteData/index.ts app/components/UI/Bridge/hooks/useBatchSellQuoteData/useBatchSellQuoteData.test.ts ``` ## **Pre-merge author checklist** - [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) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] 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 - [ ] 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** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] 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. [SWAPS-4439]: https://consensyssoftware.atlassian.net/browse/SWAPS-4439?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches swap/bridge quote flows, Redux amounts, and controller state; incorrect stale-quote or amount sync could show wrong receive totals before submit (Sell all still TODO). > > **Overview** > Replaces Batch Sell review placeholders with **live batch quote fetching and display** via new `useBatchSellQuoteData` and `useBatchSellQuoteRequest`, driving row amounts, totals, loading/unavailable states, high price impact, quote expiry (“Get new quote”), and gas checks on final review. > > **Allocation and Redux:** Sliders move from 25% snaps to **1% rounded** values with smoother panning; source token amounts, default slippages, and destination token are seeded on Continue and kept in sync when allocations change. **Stale quotes** after switching destination stablecoin are hidden until matching quotes load. > > **UI/navigation:** Quote details and final review read from Redux/controller state instead of route params; unmount clears **BridgeController** quote state but not full bridge Redux. Adds a price-impact info modal and improves stablecoin balance display (fiat vs token fallback). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 229dd4a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Continues the `TouchableOpacity` → `Pressable` migration started in #30543 by migrating six shared design-system row primitives. These sit beneath dozens of selector flows (account picker, network selector, Buy/Deposit modals, Card onboarding, Rewards, multi-select token search), so fixing them once cascades. Migrated components: - `ListItemSelect` - `ListItemMultiSelect` - `ListItemMultiSelectButton` - `ListItemMultiSelectWithMenuButton` - `CellSelectWithMenu` (the inner secondary-text press target) - `PickerBase` (+ `PickerAccount` consumer) Secondary changes: - **`Pressable` and `PressableGH` now `forwardRef`.** `TouchableOpacity` forwarded refs; without this the migration would have been a quiet capability regression for any future caller that wants to `measure()` / focus / animate the underlying view. Added real ref-forwarding tests (assert `ref.current.measure` exists) to both primitives. - **Removed `PickerAccount`'s manual pressed-state machinery.** It maintained `useState(pressed)` + `onPressIn`/`onPressOut` handlers + a `basePressed` style swap to `background.pressed` — exactly what `Pressable` now does for free. - **Dropped resting `background.default` from `ListItemSelect`/`ListItemMultiSelect`.** Matches the SettingsDrawer precedent from #30543: parent surface (sheet / screen) owns the resting background so the pressed overlay composites correctly, including in pure-black mode. - **Test updates:** Multi-select rows now have a correctly role-tagged row AND an inner `ButtonIcon`, so `getByRole('button')` is ambiguous. Switched affected tests to `getAllByRole('button')[0]` to target the row. ## **Changelog** CHANGELOG entry:null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-790 ## **Manual testing steps** ```gherkin Feature: Row press feedback across DS primitives Scenario: user presses a single-select row in pure-black mode Given MM_PURE_BLACK_PREVIEW=true is set in .js.env and the app is rebuilt When user opens Buy → Token selector and taps any token row Then the row background briefly shifts to background.pressed and remains clearly visible And the row does not "disappear" against the pure-black backdrop And there is no full-subtree opacity dim Scenario: user presses a multi-select row with a side menu button Given the app is open When user opens the wallet header account picker and taps an account row Then the row flashes the pressed token And the MoreVertical (⋮) menu button at the right is independently pressable Scenario: user presses the wallet header account picker Given the app is open on the Wallet screen When user taps the account name pill in the header Then the pill briefly shifts to background.pressed (no manual state, no opacity dim) And the account selector sheet opens Scenario: disabled rows still appear dimmed Given a list with a disabled ListItemSelect row Then the disabled row renders at opacity 0.5 (behavior unchanged) ``` ## **Screenshots/Recordings** ### Notice there is no dim anymore when pressed https://github.com/user-attachments/assets/469def01-dfb1-40f7-a75f-5862430f5f33 ### **Before** https://github.com/user-attachments/assets/3965483c-28aa-4c57-b0c9-c39ad97d2dae ### **After** https://github.com/user-attachments/assets/469def01-dfb1-40f7-a75f-5862430f5f33 ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] 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 - [ ] 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** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [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 widely reused UI primitives and press/visual behavior (including pure-black mode), but changes are localized to the component library with added tests and no auth or data-path impact. > > **Overview** > Continues the **`TouchableOpacity` → design-system `Pressable`** migration on shared row and picker primitives used across account/network selectors, buy flows, and multi-select lists. > > **`ListItemSelect`**, **`ListItemMultiSelect`**, **`ListItemMultiSelectButton`**, **`ListItemMultiSelectWithMenuButton`**, **`CellSelectWithMenu`** (clickable secondary text), **`PickerBase`**, and **`PickerAccount`** now use **`Pressable`** for press handling and **`background.pressed`** overlay instead of subtree opacity dimming. **`Pressable`** and **`PressableGH`** gain **`forwardRef`** (with ref tests) so callers can still **`measure`** the native view. > > Style/layout tweaks: resting **`background.default`** removed from select rows so parent surfaces own the backdrop; multi-select button rows move disabled opacity and selection background onto the outer pressable **`container`**; **`PickerAccount`** drops manual pressed-state styling and **`onPressIn`/`onPressOut`** wiring. Tests add **`ROW_TEST_ID`** targeting and assert row **`accessibilityRole="button"`** where row + side **`ButtonIcon`** both expose buttons. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ec0a797. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )