Skip to content

Cherry-picking commits from main to release/7.82.0 for PR #31505#31652

Open
runway-github[bot] wants to merge 1 commit into
release/7.82.0from
runway-cherry-pick-7.82.0-1781283432
Open

Cherry-picking commits from main to release/7.82.0 for PR #31505#31652
runway-github[bot] wants to merge 1 commit into
release/7.82.0from
runway-cherry-pick-7.82.0-1781283432

Conversation

@runway-github

@runway-github runway-github Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Description

The Predict game-market chart draws an endpoint label for each outcome
(the team/player name above, the percentage below) to the right of each
line. Depending on the data, these labels were being cut off on three
different edges:

  1. Top — when the leading outcome was high and the trailing outcomes
    were clustered low (e.g. 70% / 21% / 11%), the de-clutter logic
    shifted the whole label stack up to keep the bottom label on screen,
    pushing the top label's name off the top edge.
  2. Bottom — when two outcomes were clustered near the chart floor
    (e.g. 91% / 6% / 3%), the lowest label was pushed below the chart and
    its percentage was cut off.
  3. Right (horizontal) — wide content overflowed the reserved right
    gutter: the 3-digit value 100% and long team/player names like
    UDVARDY were clipped at the right edge.

What changed

  • Vertical (top & bottom): Replaced the one-directional "push down +
    shift up" label spacing with a two-sided resolution in
    getSeparatedLabelYPositions. Labels are pushed down to honor the
    minimum gap; if the bottom value would overflow the floor, the bottom is
    anchored at MAX_LABEL_Y and the rest are pushed back up; the top is
    then guarded at MIN_LABEL_Y. Two named bounds (MIN_LABEL_Y,
    MAX_LABEL_Y) make the visible region explicit, so neither the top name
    nor the bottom value can clip.
  • Horizontal (right): Replaced the fixed right content inset with a
    content-aware one. getChartRightInset(labels, maxValue) sizes the
    right gutter to the widest element that will actually render (team name
    or value) across the series, clamped to a sensible range so a very
    long name can't squeeze the chart away. The gutter stays tight for short
    content (no wasted space) and widens only when a long name or 100%
    needs it. Both the static endpoint view and the scrub tooltip use the
    same inset.
  • All chart inset constants are co-located in
    PredictGameChart.constants.ts.

Note: SVG text cannot be measured synchronously in React Native, so
horizontal width is approximated from conservative glyph-advance ratios
(leaning slightly wide to avoid clipping) and clamped.

Changelog

CHANGELOG entry: Fixed Predict game-market chart labels (team/player
names and percentages) being cut off at the top, bottom, and right
edges.

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-955

Manual testing steps

Feature: Predict game chart labels are fully visible

  Scenario: Leading outcome is high with clustered low outcomes
    Given I open a 3-outcome game market (e.g. ~70% / ~21% / ~11%)
    When the game chart renders
    Then the top outcome's name and percentage are fully visible (not clipped at the top)

  Scenario: Two outcomes are clustered near the chart floor
    Given I open a game market like ~91% / ~6% / ~3%
    When the game chart renders
    Then the lowest outcome's name and percentage are fully visible (not clipped at the bottom)

  Scenario: An outcome reaches 100%
    Given I open a settled/lopsided market showing 100% / 0%
    When the game chart renders
    Then "100%" is fully visible (not clipped on the right)

  Scenario: Long team/player names
    Given I open a market with long names (e.g. SNIGUR / UDVARDY)
    When the game chart renders
    Then both names are fully visible (not clipped on the right)

  Scenario: Short names and 2-digit values
    Given I open a market with short names and 2-digit values (e.g. GER / KOR · 94%)
    When the game chart renders
    Then the labels hug the right edge with no excessive empty gap

  Scenario: Scrubbing the chart
    Given any of the markets above
    When I drag across the chart to show the tooltip
    Then the tooltip labels and percentages are fully visible at every position

Screenshots/Recordings

Before

Screenshot 2026-06-10 at 16 43 52

Screenshot 2026-06-10 at 16 44 41

Screenshot 2026-06-10 at 14 57 54

After

Screenshot 2026-06-10 at 16 48 51

Screenshot 2026-06-10 at 14 34 17

Screenshot 2026-06-10 at 16 46 05

Pre-merge author checklist

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

    to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production
    performance metrics
  • See trace() for usage and
    addToken
    for an example

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.

Note

Low Risk
Predict chart layout and label positioning only; no auth, payments, or
data-path changes, with expanded unit tests.

Overview
Fixes Predict game-market chart endpoint labels (names and
percentages) clipping at the top, bottom, and right on
devices like iPhone 17 Pro (PRED-955).

Vertical: getSeparatedLabelYPositions now uses explicit
MIN_LABEL_Y / MAX_LABEL_Y bounds and two-sided layout: enforce
minimum gap, anchor the bottom at the floor when needed, then
guard the top so name/value text stay inside the chart. Two-label
stacks go through fitLabelStackWithinChart.

Horizontal: Replaces the fixed 80px right inset with
getChartRightInset(labels, maxValue), which estimates width from
team names and values (including 100%) and clamps between min/max so
short labels stay tight and long names are not clipped.
PredictGameChartContent applies this inset everywhere (lines +
tooltip) and keeps pan/scrub math in sync via a ref.

Tests cover the new spacing behavior and dynamic right inset.

Reviewed by Cursor Bugbot for commit
b4ed809. Bugbot is set up for automated
code reviews on this repo. Configure
here.

[512d2ab](https://github.com/MetaMask/metamask-mobile/commit/512d2ab5b0a1d2614a89f84f2ca4a855dfbeab47)

## **Description**

The Predict game-market chart draws an endpoint label for each outcome
(the team/player name above, the percentage below) to the right of each
line. Depending on the data, these labels were being cut off on three
different edges:

1. **Top** — when the leading outcome was high and the trailing outcomes
were clustered low (e.g. `70% / 21% / 11%`), the de-clutter logic
shifted the whole label stack up to keep the bottom label on screen,
pushing the top label's name off the top edge.
2. **Bottom** — when two outcomes were clustered near the chart floor
(e.g. `91% / 6% / 3%`), the lowest label was pushed below the chart and
its percentage was cut off.
3. **Right (horizontal)** — wide content overflowed the reserved right
gutter: the 3-digit value `100%` and long team/player names like
`UDVARDY` were clipped at the right edge.

**What changed**

- **Vertical (top & bottom):** Replaced the one-directional "push down +
shift up" label spacing with a **two-sided resolution** in
`getSeparatedLabelYPositions`. Labels are pushed down to honor the
minimum gap; if the bottom value would overflow the floor, the bottom is
anchored at `MAX_LABEL_Y` and the rest are pushed back up; the top is
then guarded at `MIN_LABEL_Y`. Two named bounds (`MIN_LABEL_Y`,
`MAX_LABEL_Y`) make the visible region explicit, so neither the top name
nor the bottom value can clip.
- **Horizontal (right):** Replaced the fixed right content inset with a
**content-aware** one. `getChartRightInset(labels, maxValue)` sizes the
right gutter to the widest element that will actually render (team name
*or* value) across the series, clamped to a sensible range so a very
long name can't squeeze the chart away. The gutter stays tight for short
content (no wasted space) and widens only when a long name or `100%`
needs it. Both the static endpoint view and the scrub tooltip use the
same inset.
- All chart inset constants are co-located in
`PredictGameChart.constants.ts`.

Note: SVG text cannot be measured synchronously in React Native, so
horizontal width is approximated from conservative glyph-advance ratios
(leaning slightly wide to avoid clipping) and clamped.

## **Changelog**

CHANGELOG entry: Fixed Predict game-market chart labels (team/player
names and percentages) being cut off at the top, bottom, and right
edges.

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-955

## **Manual testing steps**

```gherkin
Feature: Predict game chart labels are fully visible

  Scenario: Leading outcome is high with clustered low outcomes
    Given I open a 3-outcome game market (e.g. ~70% / ~21% / ~11%)
    When the game chart renders
    Then the top outcome's name and percentage are fully visible (not clipped at the top)

  Scenario: Two outcomes are clustered near the chart floor
    Given I open a game market like ~91% / ~6% / ~3%
    When the game chart renders
    Then the lowest outcome's name and percentage are fully visible (not clipped at the bottom)

  Scenario: An outcome reaches 100%
    Given I open a settled/lopsided market showing 100% / 0%
    When the game chart renders
    Then "100%" is fully visible (not clipped on the right)

  Scenario: Long team/player names
    Given I open a market with long names (e.g. SNIGUR / UDVARDY)
    When the game chart renders
    Then both names are fully visible (not clipped on the right)

  Scenario: Short names and 2-digit values
    Given I open a market with short names and 2-digit values (e.g. GER / KOR · 94%)
    When the game chart renders
    Then the labels hug the right edge with no excessive empty gap

  Scenario: Scrubbing the chart
    Given any of the markets above
    When I drag across the chart to show the tooltip
    Then the tooltip labels and percentages are fully visible at every position
```

## **Screenshots/Recordings**

### **Before**

<img width="415" height="861" alt="Screenshot 2026-06-10 at 16 43 52"
src="https://github.com/user-attachments/assets/b24f6f37-ea32-4cfc-bc1f-639550aadf29"
/>

<img width="421" height="881" alt="Screenshot 2026-06-10 at 16 44 41"
src="https://github.com/user-attachments/assets/eaf3de16-497b-418f-9b14-33f967951541"
/>

<img width="426" height="885" alt="Screenshot 2026-06-10 at 14 57 54"
src="https://github.com/user-attachments/assets/cd9f2012-f9c0-4272-98a5-e388cfc2b3ad"
/>

<!-- Attach the reported "before" screenshots here. -->

### **After**
<img width="427" height="889" alt="Screenshot 2026-06-10 at 16 48 51"
src="https://github.com/user-attachments/assets/d2f45481-d6d0-4521-aee7-54f1c1b37ec6"
/>

<img width="425" height="897" alt="Screenshot 2026-06-10 at 14 34 17"
src="https://github.com/user-attachments/assets/5fad254c-0d87-4b9f-8316-83f4539384f3"
/>

<img width="414" height="890" alt="Screenshot 2026-06-10 at 16 46 05"
src="https://github.com/user-attachments/assets/ee257f2b-8e7e-4448-9c8c-9663fd02b28c"
/>

<!-- Attach simulator screenshots of the same markets showing all labels
fully rendered:
70/21/11, 91/6/3, 100/0, SNIGUR/UDVARDY, and GER/KOR 94% (tight gutter).
-->

## **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)

<!-- N/A — this is a label positioning/layout-only change with no
performance impact. -->

- [x] I've tested on Android
  - Ideally on a mid-range device; emulator is acceptable
- [x] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [x] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example

## **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]
> **Low Risk**
> Predict chart layout and label positioning only; no auth, payments, or
data-path changes, with expanded unit tests.
> 
> **Overview**
> Fixes **Predict game-market chart** endpoint labels (names and
percentages) clipping at the **top**, **bottom**, and **right** on
devices like iPhone 17 Pro (PRED-955).
> 
> **Vertical:** `getSeparatedLabelYPositions` now uses explicit
**`MIN_LABEL_Y` / `MAX_LABEL_Y`** bounds and two-sided layout: enforce
minimum gap, **anchor the bottom** at the floor when needed, then
**guard the top** so name/value text stay inside the chart. Two-label
stacks go through **`fitLabelStackWithinChart`**.
> 
> **Horizontal:** Replaces the fixed **80px** right inset with
**`getChartRightInset(labels, maxValue)`**, which estimates width from
team names and values (including **100%**) and clamps between min/max so
short labels stay tight and long names are not clipped.
**`PredictGameChartContent`** applies this inset everywhere (lines +
tooltip) and keeps pan/scrub math in sync via a ref.
> 
> Tests cover the new spacing behavior and dynamic right inset.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
b4ed809. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@runway-github runway-github Bot requested a review from a team as a code owner June 12, 2026 16:57
@mm-token-exchange-service mm-token-exchange-service Bot added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label Jun 12, 2026
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - PR targets a release or stable branch (release/* or stable)

All E2E tests pre-selected.

View GitHub Actions results

@github-actions github-actions Bot added size-M risk:low AI analysis: low risk labels Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:low AI analysis: low risk size-M team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant