Skip to content

fix(perps): Button flash when open a market with an open position #27671

Merged
abretonc7s merged 5 commits into
mainfrom
fix/perps/tat-2236-0319-1615
Mar 20, 2026
Merged

fix(perps): Button flash when open a market with an open position #27671
abretonc7s merged 5 commits into
mainfrom
fix/perps/tat-2236-0319-1615

Conversation

@abretonc7s

@abretonc7s abretonc7s commented Mar 19, 2026

Copy link
Copy Markdown
Contributor

Description

When navigating to a market with an existing position, Long/Short buttons briefly flashed before switching to Modify/Close. Root cause: positions in usePerpsLivePositions was derived from rawPositions via a useEffect, creating a one-frame lag where isInitialLoading was false but positions still held stale data. Fix: replace the state+effect pattern with useMemo for synchronous derivation.

Changelog

CHANGELOG entry: Fixed button flash (Long/Short briefly visible) when opening a market with an existing position

Related issues

Fixes: TAT-2236

Manual testing steps

Feature: Market detail action buttons
  Scenario: Open market with existing position
    Given I have an open BTC position
    When I navigate to the BTC market detail screen
    Then I see Modify/Close buttons immediately
    And I do not see Long/Short buttons flash

  Scenario: Open market without position
    Given I have no position on SOL
    When I navigate to the SOL market detail screen
    Then I see Long/Short buttons immediately

Screenshots/Recordings

Before

See automation/27671/before.mp4

After

See automation/27671/after.mp4

Pre-merge author checklist

  • I've followed MetaMask Contributor Docs and Coding Standards
  • 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 format if applicable
  • I've applied the right labels on the PR

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
Low risk: small hook refactor to compute positions synchronously plus a targeted regression test; main risk is subtle rendering behavior changes around initial WebSocket updates.

Overview
Fixes a one-render mismatch in usePerpsLivePositions where isInitialLoading could flip to false before derived positions updated, causing a brief Long/Short button flash when opening a market with an existing position.

positions is now derived from rawPositions and priceData via useMemo (instead of state set in an effect), and a new regression test asserts that the first WebSocket update makes isInitialLoading=false and positions available in the same render.

Written by Cursor Bugbot for commit 997d441. This will update automatically on new commits. Configure here.

@abretonc7s abretonc7s added the team-perps Perps team label Mar 19, 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 github-actions Bot added the risk-low Low testing needed · Low bug introduction risk label Mar 19, 2026
@github-actions github-actions Bot added size-M risk-low Low testing needed · Low bug introduction risk and removed risk-low Low testing needed · Low bug introduction risk labels Mar 19, 2026
@abretonc7s

Copy link
Copy Markdown
Contributor Author

TAT-2236: Button color flash when open a market with an open position

Summary

When navigating to a market with an existing position, Long/Short buttons flashed briefly before switching to Modify/Close buttons. The fix converts an async state derivation (useEffect) to a synchronous one (useMemo) in usePerpsLivePositions, eliminating the one-frame lag between loading state resolution and position data availability.

Root Cause

File: app/components/UI/Perps/hooks/stream/usePerpsLivePositions.ts:117-128

The positions state was derived from rawPositions via a useEffect (state + effect pattern). When the first WebSocket update arrived, setIsInitialLoading(false) and setRawPositions(newPositions) were batched into one render. However, the useEffect that derived positions from rawPositions ran after that render, creating one render frame where:

  • isInitialLoading = false (buttons footer visible)
  • positions still held old empty value → existingPosition = null
  • Long/Short buttons showed briefly before the next render corrected to Modify/Close

Reproduction Commit

SHA: 4d17a150e7

Metro log excerpt proving the bug:

(NOBRIDGE) DEBUG  [PR-27671] BUG_MARKER: Long/Short buttons visible while position data not yet resolved {"existingPosition": false, "hasLongShortButtons": true, "isLoadingPosition": false, "symbol": "BTC"}

Changes

File Change
app/components/UI/Perps/hooks/stream/usePerpsLivePositions.ts Replace state+effect positions derivation with useMemo for synchronous computation
app/components/UI/Perps/hooks/stream/useLivePositions.test.ts Add test verifying positions are available synchronously when isInitialLoading becomes false

Test Plan

Automated

  • Unit tests: 32/32 pass (useLivePositions.test.ts)
  • Coverage: 100% statements, 100% lines, 89.74% branches
  • Type check: No new errors (all pre-existing)
  • Recipe validation: 8/8 steps pass

Manual (Gherkin)

Feature: Market detail action buttons
  Scenario: Open market with existing position
    Given I have an open BTC position
    When I navigate to the BTC market detail screen
    Then I see Modify/Close buttons immediately
    And I do not see Long/Short buttons flash

  Scenario: Open market without position
    Given I have no position on SOL
    When I navigate to the SOL market detail screen
    Then I see Long/Short buttons immediately
    And I do not see Modify/Close buttons flash

Evidence

  • before.mp4: automation/27671/before.mp4 — shows flash of Long/Short buttons on BTC market with position
  • after.mp4: automation/27671/after.mp4 — clean transition to Modify/Close buttons
  • Screenshot: automation/27671/2026-03-19_163654_btc-market-with-position.png

JIRA

TAT-2236


Run Details

Field Value
Runner claude
Model opus (claude-opus-4-6)
Slot macwork-mm-3
Duration ~23 min
Turns 203
Input tokens 17.1M (mostly cache reads)
Output tokens 35.9k
Cost $32.78

@abretonc7s abretonc7s added the DO-NOT-MERGE Pull requests that should not be merged label Mar 19, 2026
@abretonc7s abretonc7s marked this pull request as ready for review March 19, 2026 08:43
@abretonc7s abretonc7s requested a review from a team as a code owner March 19, 2026 08:43

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread TASK.md Outdated
@github-actions github-actions Bot added size-S and removed size-M labels Mar 19, 2026
@abretonc7s abretonc7s removed the DO-NOT-MERGE Pull requests that should not be merged label Mar 19, 2026
@github-actions github-actions Bot added risk-medium Moderate testing recommended · Possible bug introduction risk and removed risk-low Low testing needed · Low bug introduction risk labels Mar 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePreps
  • Risk Level: medium
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR fixes a UI flash bug (TAT-2236) in usePerpsLivePositions.ts by converting positions from useState + useEffect (async derivation) to useMemo (synchronous derivation). This ensures that when isInitialLoading becomes false, positions are already available in the same render cycle, preventing a brief flash of Long/Short buttons before Modify/Close buttons appear in the market detail view.

The hook is consumed by:

  • PerpsMarketTabs (market detail view — directly affected by the flash fix)
  • PerpsSection in Homepage/Trending (Perps section inside Trending tab)
  • PerpsTabControlBar

Tag selection rationale:

  • SmokePerps: Directly tests the Perps feature where this hook is used. The fix affects position display in market detail views.
  • SmokeWalletPlatform: Required per SmokePerps tag description — Perps is a section inside the Trending tab, so changes to Perps views affect Trending.
  • SmokeConfirmations: Required per SmokePerps tag description — Add Funds deposits are on-chain transactions.

The change is a rendering optimization (useMemo vs useState+useEffect) that should not break any existing functionality but needs validation that the fix works correctly in E2E flows.

Performance Test Selection:
The change converts positions derivation from useState+useEffect (async, causes extra render) to useMemo (synchronous). This is a rendering optimization that directly impacts how quickly positions are available in the Perps UI. The @PerformancePreps tag covers perps market loading, position management, and add funds flow — all of which are affected by this rendering change. Running performance tests will validate that the synchronous derivation via useMemo doesn't introduce any unexpected performance regressions.

View GitHub Actions results

@abretonc7s abretonc7s changed the title TAT-2236: Button color flash when open a market with an open position fix(perps): Button flash when open a market with an open position Mar 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
17 value mismatches detected (expected — fixture represents an existing user).
View details

@sonarqubecloud

Copy link
Copy Markdown

@abretonc7s abretonc7s added this pull request to the merge queue Mar 20, 2026
Merged via the queue into main with commit a82a469 Mar 20, 2026
114 of 121 checks passed
@abretonc7s abretonc7s deleted the fix/perps/tat-2236-0319-1615 branch March 20, 2026 01:04
@github-actions github-actions Bot locked and limited conversation to collaborators Mar 20, 2026
@metamaskbot metamaskbot added the release-7.72.0 Issue or pull request that will be included in release 7.72.0 label Mar 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.72.0 Issue or pull request that will be included in release 7.72.0 risk-medium Moderate testing recommended · Possible bug introduction risk size-S team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants