[pull] main from MetaMask:main#315
Merged
Merged
Conversation
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** * BugFix: #22375 * Jira: https://consensyssoftware.atlassian.net/browse/SL-280 * Shadow overlay issue in import srp via home screen <!-- 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: BugFix: #22375 ## **Related issues** Fixes: * #22375 * Shadow overlay issue in import srp via home screen ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="353" height="798" alt="bug" src="https://github.com/user-attachments/assets/2c4b5b6c-8bbd-4bf7-9e0e-4d898a6c855b" /> <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/b36c5b81-96ca-4bd9-b422-db4cde062bdb <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/be424bbd-3175-4cf6-92d0-a5ec18f11c6d https://github.com/user-attachments/assets/278508ca-f130-4f65-a472-10f49be445f3 ## **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. ## **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] > Wraps WalletRecovery in SafeAreaView and updates layout/styles, updating the snapshot accordingly. > > - **UI (WalletRecovery)** > - Wrap screen with `SafeAreaView` (`edges={{ bottom: 'additive' }}`) and add `safeArea` style. > - Adjust layout: reorganize `root` container spacing, `socialContainer` structure, line break placement, and `srp` section paddings (`srpTitle`, `srpListContainer`). > - **Tests** > - Update snapshot `app/components/Views/WalletRecovery/__snapshots__/index.test.tsx.snap` to reflect the new safe area wrapper and layout changes. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e5af869. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR adds a feature flag for automatically updating preinstalled Snaps and enables it. Following onboarding and as long as the user doesn't opt-out, the Snaps registry will be queried and used to serve updates for preinstalled Snaps. ## **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: Enable automatic updates of preinstalled Snaps <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Enables auto-updating preinstalled Snaps and adds a saga to update the Snaps registry after login/onboarding, with tests and a snaps-controllers bump. > > - **Engine / Snaps Controller**: > - Add `featureFlags.autoUpdatePreinstalledSnaps: true` in `snap-controller-init.ts`; update expectations in `snap-controller-init.test.ts`. > - **Sagas**: > - Introduce `handleSnapsRegistry` to call `SnapController.updateRegistry` on `LOGIN` or when `SET_COMPLETED_ONBOARDING` indicates completion; register in `rootSaga`. > - **Tests**: > - Add tests for `handleSnapsRegistry` covering login, onboarding completion, and negative cases. > - **Dependencies**: > - Bump `@metamask/snaps-controllers` from `^16.1.0` to `^16.1.1`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit afc3c7f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **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? --> There was a `transactions` array reference that was being reused on every run of the selector, so duplicate items were being added and breaking the transactions view. ## **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 issue with activity list showing blank spaces ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/ASSETS-1751 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/437d7622-a32f-49dd-80ba-616eaa2c65ef ### **After** <!-- [screenshots/recordings] --> https://github.com/user-attachments/assets/2a2edf96-7332-4c21-8673-078a1328d4cc ## **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. ## **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.
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
- Refactor some text to try to address the cut-off problem
- Add shares quantity to postion item
- Fix formatCents function to show only 1 decimal when necessary
<!--
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: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **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**
- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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.
## **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.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Switches cents display to compact format and enhances position card
text with share counts; adds formatting utilities and extensive tests
plus minor UI/layout tweaks.
>
> - **UI/Components**:
> - `PredictMarketOutcome`:
> - Button prices now use `formatCents` (e.g., `65¢`), adds winner/loser
badge on closed markets, minor layout tweaks.
> - `PredictPosition`:
> - New subtitle: `"${amount} on {outcome} · {shares} share(s) at
{priceCents}"` using i18n, `formatCents`, `formatPositionSize`,
`formatPrice`.
> - Supports `onPress` via test ID; renders icon; colorized PnL.
> - `PredictPositionsHeader`/`PredictMarketDetails`: small text/layout
cleanups.
> - **Utils**:
> - Add/overhaul `formatCents`, `formatVolume`,
`formatPositionSize(options)`, `getRecurrence`; keep
`formatPercentage/formatPrice`.
> - **Tests**:
> - Update expectations from `65.00¢` to `65¢`; add coverage for
pluralization, press handlers, and new formatters.
> - **Localization**:
> - Add `predict.position_info_plural/singular`, outcome labels, and
recurrence mapping.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
71f8d32. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This PR enables automatic account upgrades when Smart Transactions (STX) are turned off. It removes the UI condition that previously blocked the flow from initiating and refines the EIP-7702 authorization handling, signature normalization, and gasless eligibility logic. <!-- 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: Added automatic account upgrade support ## **Related issues** Fixes: MetaMask/mobile-planning#2332 ## **Manual testing steps** ```gherkin Feature: Automatic account upgrade when Smart Transactions are off Scenario: User sends a transaction using USDC as the gas token Given the user account has not been upgraded on the test network And the account has a sufficient USDC balance When the user sends a transaction And selects USDC as the gas payment token Then the transaction should complete successfully And the account should be automatically upgraded after completion ``` ## **Screenshots/Recordings** [mobile-auto-upgrade.webm](https://github.com/user-attachments/assets/f73d9f2e-ed76-432d-9d76-8542b1f6bf70) <!-- 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** - [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. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds nonce-handling to the 7702 delegation publish path and simplifies gasless eligibility by relying on relay support, plus signature normalization utilities and tests. > > - **Confirmations (Gasless eligibility)**: > - Simplify `useIsGaslessSupported`: remove `isAtomicBatchSupported` checks; now uses relay support and excludes contract deployments. Updated tests accordingly. > - **Transaction Controller Init**: > - Wire `Delegation7702PublishHook` into `hooks.publish` when STX disabled or `sendBundle` unsupported. > - Add `getNextNonce` helper using `getNonceLock`/`releaseLock`; pass to `Delegation7702PublishHook`. Tests verify locking and hex conversion. > - **Delegation 7702 Publish Hook**: > - Accept `getNextNonce`; use it to build authorization list (fallback when tx nonce absent). > - Normalize authorization signature parts (`r`, `s`, `yParity`) using new util and `toHex`; improve calldata normalization. > - Expand tests for gasless/sponsored flows, deployments, relay responses, and errors. > - **Utils**: > - Add `stripSingleLeadingZero` with tests for hex normalization. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 1b24923. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
# Interactive Chart for Predict Markets ## Overview This PR adds interactive drag-to-view functionality to the Predict market details chart, allowing users to explore historical price data by dragging their finger across the chart. CHANGELOG entry: null https://github.com/user-attachments/assets/036a225c-d751-4233-8e8a-453c03de7506 ## Features ### 1. **Touch Interaction** - Users can touch and drag on the chart to view values at different points in time - Crosshair line follows finger position from top to bottom of chart - Values update in real-time as user drags ### 2. **Visual Feedback** - **Crosshair Line**: Solid vertical line (theme-aware) extends from top to bottom - **Time Label**: Displayed at top of chart showing timestamp at dragged position - **Data Point Indicators**: Colored circles on each line at the active position - **Value Labels**: Colored badges showing series name and value at each data point ### 3. **Smart Label Positioning** - **Collision Detection**: Labels automatically adjust to prevent overlap when lines cross - **Side Switching**: Labels flip from right to left side when user drags past chart midpoint - **Character Limit**: Labels truncate to 25 characters to prevent overflow ### 4. **Dynamic Legend Values** - Legend above chart updates to show values at dragged position - Automatically reverts to latest values when user releases touch - Provides context for historical data exploration ### 5. **Gesture Handling** - **Directional Detection**: Distinguishes between horizontal drags (chart interaction) and vertical scrolls (page scrolling) - **No Scroll Conflicts**: Parent ScrollView continues to work for vertical scrolling - Smart gesture capture prevents interference between chart interaction and page navigation ### 6. **Theme Support** - All colors use design tokens for automatic light/dark mode support - Crosshair line: `colors.border.muted` (gray in light mode, white in dark mode) - Text: `colors.text.alternative` (gray in light mode, white in dark mode) - Labels: `colors.background.default` for text on colored backgrounds ## Technical Implementation ### Components Modified 1. **`PredictDetailsChart.tsx`** - Added `PanResponder` for touch gesture handling - Implemented collision detection algorithm for label positioning - Created tooltip overlay with proper z-index stacking - Added directional gesture discrimination 2. **`ChartLegend.tsx`** - Added `activeIndex` prop to display dragged position values - Updates dynamically during drag interaction - Reverts to latest values on release ### Key Technical Decisions - **Tooltip Rendering**: Uses separate transparent `LineChart` overlay rendered last for proper z-index - **Collision Detection**: Sorts labels by Y position and applies minimum 4px spacing - **Gesture Direction**: Uses `gestureState.dx` and `gestureState.dy` to determine horizontal vs vertical movement - **Label Truncation**: 25-character limit with ellipsis for long outcome titles ## Testing ### Manual Testing Steps 1. Navigate to any Predict market with price history 2. Touch and drag horizontally on the chart 3. Verify: - Crosshair line appears and follows touch - Time label shows at top of chart - Value labels appear next to data points - Legend values update to show dragged position - Labels flip to left side when dragging on right half - Labels don't overlap when lines cross 4. Release touch and verify: - Tooltip disappears - Legend reverts to latest values 5. Try vertical scrolling on chart area: - Verify page scrolls normally - Chart interaction only activates on horizontal drag ### Edge Cases Tested - ✅ Multiple series with crossing lines (collision detection) - ✅ Long outcome titles (truncation to 25 chars) - ✅ Single vs multiple series charts - ✅ Empty data states - ✅ Loading states - ✅ Light and dark modes - ✅ Gesture conflicts with ScrollView ## Screenshots/Demo _Add screenshots or screen recording demonstrating the interactive features_ ## Performance Considerations - Uses `useCallback` for gesture handlers to prevent unnecessary re-renders - Tooltip component defined outside render to avoid recreation - Collision detection runs only during active drag (not on every render) - Proper cleanup on gesture release ## Accessibility - Touch targets are appropriate size (chart fills available width) - Visual feedback is clear and theme-aware - Falls back to showing latest values when not interacting ## Breaking Changes None. All changes are additive and backward compatible. ## Dependencies No new dependencies added. Uses existing: - `react-native-svg-charts` (already in use) - `react-native-svg` (already in use) - React Native `PanResponder` (built-in) ## Future Enhancements Potential improvements for future PRs: - Haptic feedback on touch - Animation transitions for label movements - Pinch-to-zoom for chart data - Export chart data feature - Customizable tooltip appearance ## Commits - `ba2a015` - feat: add interactive chart with drag-to-view values in Predict - `3a40cd1` - refactor: improve chart tooltip styling and positioning - `93142d5` - feat: add label collision detection to chart tooltip - `2a6f32b` - feat: update legend values dynamically based on dragged position - `a9d37d6` - feat: add character limit to tooltip labels ## Checklist - [x] Code follows project coding guidelines - [x] No linting errors - [x] Changes are backward compatible - [x] Manual testing completed - [x] Works in both light and dark themes - [x] Gesture handling doesn't conflict with ScrollView - [ ] Unit tests added (if applicable) - [ ] E2E tests updated (if applicable) - [ ] Documentation updated (if applicable) ## Related Issues _Link any related issues or tickets here_ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds touch-driven crosshair/tooltip overlay with dynamic legend updates to Predict details chart, plus extensive tests and minor type/mocks updates. > > - **PredictDetailsChart** (`PredictDetailsChart.tsx`): > - Add interactive drag support via `PanResponder` with horizontal/vertical gesture discrimination. > - Implement `ChartTooltip` overlay (crosshair, timestamp, per-series circles/labels) rendered via transparent `LineChart` layer. > - Dynamic legend: pass `activeIndex` to `ChartLegend` to show values at the dragged position; revert when inactive. > - Data/type updates: `ChartSeries.data` supports optional `label`; generate formatted `label` for timestamps; collision handling and side-switching for tooltip labels; theme-aware colors. > - **ChartLegend** (`components/ChartLegend.tsx`): > - Accept `activeIndex` to display contextual values; fallback to last point; formatting via `formatTickValue`. > - **Tests**: > - Expand `PredictDetailsChart.test.tsx` to cover interactions, overlays, label truncation/collisions, theme, multiple series, and axis labels; adjust `LineChart` mock to hide transparent overlay; add `Circle`/`Rect` to SVG mocks. > - Add `ChartLegend.test.tsx` with value formatting, activeIndex behaviors, edge cases, and multi-series coverage. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 98d1802. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Luis Taniça <matallui@gmail.com>
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** This pull request adds analytics tracking for button presses in the buy and deposit settings modals, ensuring that user interactions are logged with relevant context such as modal location, ramp type, and region. It also updates tests to cover the new analytics behavior and adjusts the analytics event type to support both deposit and buy actions. **Analytics tracking enhancements:** * Added calls to `useAnalytics` in both `SettingsModal` and `ConfigurationModal` to track when users press key buttons, logging the event `RAMPS_BUTTON_CLICKED` with details including location, ramp type, and region. [[1]](diffhunk://#diff-e763577f4d665c8606263239492930e87bf3d4e279cbbac587936cf66d7bd4d8R24-R26) [[2]](diffhunk://#diff-e763577f4d665c8606263239492930e87bf3d4e279cbbac587936cf66d7bd4d8L37-R48) [[3]](diffhunk://#diff-14b45fbd996660ab55073b32a73ea45aa0488624ceb4efbd267c8a967cda1f4cR37-R40) [[4]](diffhunk://#diff-14b45fbd996660ab55073b32a73ea45aa0488624ceb4efbd267c8a967cda1f4cR58-R65) * Updated the analytics event type definition in `analytics.ts` to allow `ramp_type` to be either `'DEPOSIT'` or `'BUY'`. **Testing improvements:** * Added and updated mocks for the analytics hook (`useAnalytics`) and region selection in test files to verify that analytics events are triggered with the correct parameters. [[1]](diffhunk://#diff-c97ef93052f382820dc15a75c6550cfb58cb2e02701b00954bf6627ee973dae5L6-R18) [[2]](diffhunk://#diff-c97ef93052f382820dc15a75c6550cfb58cb2e02701b00954bf6627ee973dae5R33-R43) [[3]](diffhunk://#diff-2b29b56f399f76e64d8c1f0562554c20f367f832fcef7a8bbd87d7a31363dcd4R49-R51) [[4]](diffhunk://#diff-2b29b56f399f76e64d8c1f0562554c20f367f832fcef7a8bbd87d7a31363dcd4R102) * Added new test cases to ensure that pressing the relevant buttons in both modals triggers the analytics event as expected. [[1]](diffhunk://#diff-c97ef93052f382820dc15a75c6550cfb58cb2e02701b00954bf6627ee973dae5R165-R177) [[2]](diffhunk://#diff-2b29b56f399f76e64d8c1f0562554c20f367f832fcef7a8bbd87d7a31363dcd4R135-R145) ## **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: https://consensyssoftware.atlassian.net/browse/TRAM-2840 ## **Manual testing steps** ```gherkin Feature: Deposit and Buy switcher Scenario: user switches between buy and deposit Given user is in Deposit or Buy When user opens the settings modal And navigates to the other experience Then analytic event is tracked ``` ## **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** - [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. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Add analytics tracking for settings modal button presses in buy/deposit flows (with region) and update event types; tests updated to cover tracking. > > - **Analytics tracking**: > - Add `useAnalytics` calls in `Aggregator/Views/Modals/Settings/SettingsModal.tsx` and `Deposit/Views/Modals/ConfigurationModal/ConfigurationModal.tsx` to emit `RAMPS_BUTTON_CLICKED` with `location`, `ramp_type`, and `region` from SDK-selected region. > - **Types**: > - Expand `RampsButtonClicked.ramp_type` in `Deposit/types/analytics.ts` to support `'DEPOSIT' | 'BUY'`. > - **Tests**: > - Mock `useAnalytics` and region in `SettingsModal.test.tsx` and `ConfigurationModal.test.tsx`. > - Add assertions that pressing "Use new buy experience" / "More ways to buy" triggers `RAMPS_BUTTON_CLICKED` with correct params. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bcf0b8b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## Description This PR significantly improves the loading experience across the Predict feature by implementing skeleton loaders in place of generic loading indicators. Skeleton loaders provide visual placeholders that mimic the actual content structure, reducing perceived loading time and creating a smoother user experience. CHANGELOG entry: null https://github.com/user-attachments/assets/992ab739-7dc8-47f3-b7df-9fdddbfe072e ### What Changed **Market List** - Created `PredictMarketSkeleton` component to show placeholder cards during market list loading - Replaced generic loading spinner with realistic market card skeletons - Applied to both initial load and pagination footer **Market Details Page** - Created `PredictDetailsHeaderSkeleton` for header section (back arrow, avatar, title) - Created `PredictDetailsContentSkeleton` for outcome options area - Created `PredictDetailsButtonsSkeleton` for action buttons (Buy Yes/No) - Header renders immediately with skeleton if route params are missing - Content and buttons show skeletons only during initial market data fetch - Chart component handles its own loading state independently **Home Screen - Positions Tab** - Added inline skeleton for "Available Balance" value in `PredictPositionsHeader` - Added inline skeleton for "Unrealized P&L" value in `PredictPositionsHeader` - Removed early return to ensure card always renders during loading - Hidden arrow icon during balance loading state - Created `PredictPositionSkeleton` component for individual position items - Replaced large `ActivityIndicator` with 4 skeleton position cards in `PredictPositions` **Buy/Trade Preview Screen** - Added smart skeleton loader for "To win" value - Skeleton only appears when user changes input amount (not during auto-refresh) - Uses `previousValueRef` to track actual value changes - Automatically clears after calculation completes - Prevents annoying skeleton flashing from background 1s auto-refresh ### Why These Changes - **Improved Perceived Performance**: Skeleton loaders reduce perceived loading time by providing visual feedback that content is coming - **Consistent UX Pattern**: Matches modern mobile app patterns (Facebook, Instagram, etc.) - **Better User Feedback**: Shows the structure of content before it loads, setting expectations - **Reduced Jarring Transitions**: Smooth visual transition from skeleton to content vs. spinner to content - **Context Preservation**: Users can see where content will appear and what type of content to expect ### Technical Approach 1. **Component Structure**: Each skeleton component mirrors the layout and dimensions of its real content counterpart 2. **Modular Design**: Split complex skeletons into reusable sub-components (Header, Content, Buttons) 3. **Conditional Rendering**: Smart logic to show skeletons only during appropriate loading states 4. **Independent Loading States**: Different sections load independently (e.g., chart vs. market data) 5. **Smart Debouncing**: Buy preview skeleton uses value change detection + debouncing to avoid flash ### Design Alignment All skeleton implementations were created based on Figma SVG designs provided by the design team, ensuring pixel-perfect alignment with design specifications. ## Changelog ### Added - Added skeleton loader component for prediction market cards in feed - Added skeleton loaders for market details page (header, content, action buttons) - Added skeleton loaders for Available Balance and Unrealized P&L on home screen - Added skeleton loader component for position items in positions list - Added smart skeleton loader for "To win" value in buy preview screen ### Changed - Replaced generic loading spinner with skeleton cards in market list - Replaced large activity indicator with position card skeletons in positions list - Updated positions header to always render main card with inline value skeletons during loading ## Related Issues Refs: [Add issue number if applicable] ## Manual Testing Steps ### Market List Skeleton ```gherkin GIVEN I am on the Predict tab WHEN the market list is loading for the first time THEN I should see 4 skeleton market cards with avatar, title, content area, and footer AND the skeletons should smoothly transition to real market cards once loaded WHEN I scroll to the bottom of the market list AND more markets are being fetched THEN I should see 2 skeleton cards at the bottom AND they should transition to real market cards once loaded ``` ### Market Details Skeleton ```gherkin GIVEN I tap on a prediction market from the list WHEN the market details page is loading AND the title exists in route params THEN I should see the header with real back arrow, avatar, and title immediately AND I should see skeleton content for outcome options AND I should see skeleton buttons at the bottom WHEN the market data finishes loading THEN the skeleton content should transition to real outcome options AND the skeleton buttons should transition to real "Buy Yes" and "Buy No" buttons GIVEN I tap on a market with no title in route params WHEN the market details page loads THEN I should see a skeleton header with functional back arrow AND the avatar and title should be skeleton placeholders AND the skeleton header should transition to real content once market data loads ``` ### Home Screen Positions Skeleton ```gherkin GIVEN I am on the Predict home screen WHEN my balance and unrealized P&L are loading THEN I should see the main card with skeleton placeholders for both values AND the arrow icon next to Available Balance should be hidden AND the skeletons should smoothly transition to real values once loaded WHEN my positions list is loading THEN I should see 4 skeleton position cards AND each should show avatar, title lines, and value placeholders AND they should transition to real position items once loaded WHEN I have no positions and no balance data AND nothing is loading THEN the positions header card should not render at all ``` ### Buy Preview Skeleton ```gherkin GIVEN I am on the Buy/Trade preview screen WHEN I type in a new amount value THEN I should see the "To win" label remain visible AND the value should show as a skeleton while calculating AND the skeleton should disappear once calculation completes (max 500ms) WHEN the preview auto-refreshes every 1 second THEN the skeleton should NOT flash or appear AND the "To win" value should update silently in the background WHEN I clear the input to 0 THEN the skeleton state should reset AND no skeleton should show for the "To win" value ``` ## Screenshots/Recordings <!-- Add before/after screenshots or screen recordings showing: - Market list with skeleton loaders during initial load - Market list with skeleton loaders during pagination - Market details page with skeleton header/content/buttons - Home screen positions tab with skeleton values and position cards - Buy preview screen with "To win" skeleton appearing on input change --> ## Pre-merge Checklist - [ ] Manually tested all skeleton loader scenarios - [ ] All unit tests pass (`yarn jest app/components/UI/Predict`) - [ ] No new linter errors - [ ] No TypeScript errors - [ ] Screenshots/recordings added (UI changes) - [ ] Follows coding guidelines and design system rules - [ ] PR template completed - [ ] Assigned to myself - [ ] Team label added - [ ] Branch follows naming convention ## Components Created ### New Files 1. `app/components/UI/Predict/components/PredictMarketSkeleton/` - `PredictMarketSkeleton.tsx` - Skeleton for market list cards - `PredictMarketSkeleton.test.tsx` - Unit tests - `index.ts` - Barrel export 2. `app/components/UI/Predict/components/PredictDetailsHeaderSkeleton/` - `PredictDetailsHeaderSkeleton.tsx` - Skeleton for details page header - `PredictDetailsHeaderSkeleton.test.tsx` - Unit tests - `index.ts` - Barrel export 3. `app/components/UI/Predict/components/PredictDetailsContentSkeleton/` - `PredictDetailsContentSkeleton.tsx` - Skeleton for details page content - `PredictDetailsContentSkeleton.test.tsx` - Unit tests - `index.ts` - Barrel export 4. `app/components/UI/Predict/components/PredictDetailsButtonsSkeleton/` - `PredictDetailsButtonsSkeleton.tsx` - Skeleton for action buttons - `PredictDetailsButtonsSkeleton.test.tsx` - Unit tests - `index.ts` - Barrel export 5. `app/components/UI/Predict/components/PredictPositionSkeleton/` - `PredictPositionSkeleton.tsx` - Skeleton for position list items - `PredictPositionSkeleton.test.tsx` - Unit tests - `index.ts` - Barrel export ### Modified Files 1. `app/components/UI/Predict/components/MarketListContent/MarketListContent.tsx` - Integrated `PredictMarketSkeleton` for loading states 2. `app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.tsx` - Integrated header, content, and button skeletons - Modified conditional rendering logic 3. `app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.test.tsx` - Updated tests to expect new skeleton components 4. `app/components/UI/Predict/components/PredictPositionsHeader/PredictPositionsHeader.tsx` - Added inline skeletons for balance and P&L values - Modified loading state logic 5. `app/components/UI/Predict/components/PredictPositionsHeader/PredictPositionsHeader.test.tsx` - Updated tests for new loading behavior 6. `app/components/UI/Predict/components/PredictPositions/PredictPositions.tsx` - Replaced ActivityIndicator with PredictPositionSkeleton components 7. `app/components/UI/Predict/components/PredictPositions/PredictPositions.test.tsx` - Updated tests to expect skeleton components 8. `app/components/UI/Predict/views/PredictBuyPreview/PredictBuyPreview.tsx` - Added smart skeleton for "To win" value with value-change detection 9. `app/components/UI/Predict/hooks/usePredictOrderPreview.ts` - Exposed `isCalculating` state for skeleton logic ## Technical Notes ### Design System Compliance - All skeletons use `Box` component from `@metamask/design-system-react-native` - Styling uses `useTailwind()` hook and `twClassName` prop - No StyleSheet usage (adheres to workspace rules) - Uses design system color tokens (`bg-muted`, `bg-section`, etc.) ### Testing Strategy - Unit tests for all new skeleton components - Integration tests updated for modified components - All tests use React Testing Library best practices ### Performance Considerations - Skeleton components are lightweight (no heavy computations) - Smart debouncing prevents excessive skeleton re-renders - Independent loading states prevent unnecessary full-page re-renders ## Review Focus Areas 1. **Visual Accuracy**: Do skeletons match the Figma designs and real content structure? 2. **Loading Logic**: Are skeletons appearing at the right times and transitioning smoothly? 3. **User Experience**: Does this feel smoother than the previous loading indicators? 4. **Test Coverage**: Do tests properly cover loading states and transitions? 5. **Code Organization**: Are components modular and reusable? <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds dedicated skeleton loaders for market lists, market details, positions, and buy preview, replacing spinners and refining loading logic. > > - **Predict UI**: > - **Market List (`MarketListContent.tsx`)**: Replace generic loading/footer placeholders with `PredictMarketSkeleton` cards for initial load and pagination. > - **Market Details (`PredictMarketDetails.tsx`)**: Add `PredictDetailsHeaderSkeleton`, `PredictDetailsContentSkeleton`, and `PredictDetailsButtonsSkeleton`; render skeletons during initial fetch; keep chart loading independent; refine header rendering when route params missing. > - **Positions**: > - **Header (`PredictPositionsHeader.tsx`)**: Inline skeletons for Available Balance and Unrealized P&L; always render card while loading; disable arrow while loading. > - **List (`PredictPositions.tsx`)**: Replace `ActivityIndicator` with 4 `PredictPositionSkeleton` rows during initial/refresh loads; gate `PredictNewButton` when loading. > - **Buy Preview (`PredictBuyPreview.tsx`)**: Show smart skeleton for "To win" value only while recalculating due to user input; keep balance skeleton. > - **New Components**: `PredictMarketSkeleton`, `PredictDetailsHeaderSkeleton`, `PredictDetailsContentSkeleton`, `PredictDetailsButtonsSkeleton`, `PredictPositionSkeleton` (+ index files). > - **Misc**: Simplify `selectPredictEnabledFlag` property check; update tests and snapshots to assert skeletons. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 118502a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** - show polymarket offline screen for feed errors <!-- 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: [PRED-280 ](https://consensyssoftware.atlassian.net/browse/PRED-280?atlOrigin=eyJpIjoiYzgwMjc5ODhlNDAzNDNiZmJmYWVmOWY4MzYyNjQyMWUiLCJwIjoiaiJ9) ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **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** - [ ] 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). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] 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. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Replaces inline error message with `PredictOffline` in `MarketListContent`, wiring retry to `refetch`, and updates tests to validate offline UI and retry behavior. > > - **Predict Feed** > - **Error UI**: Replace inline error message in `app/components/UI/Predict/components/MarketListContent/MarketListContent.tsx` with `PredictOffline` and hook `onRetry` to `handleRefresh`/`refetch`. > - **Tests** > - Update `MarketListContent.test.tsx` to mock `PredictOffline` and assert offline copy and layout via `testID`s. > - Add retry behavior test invoking `onRetry` (using `act`) to verify `refetch` is called. > - Keep existing loading/footer skeleton and empty state tests intact. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 566f524. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=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 : )