Skip to content

fix: TSA-970 header layout shift on Follow Trading screens cp-8.6.0 - #34278

Merged
joaosantos15 merged 1 commit into
mainfrom
TSA-970-fix-social-leaderboard-header-safe-area-jump
Aug 4, 2026
Merged

fix: TSA-970 header layout shift on Follow Trading screens cp-8.6.0#34278
joaosantos15 merged 1 commit into
mainfrom
TSA-970-fix-social-leaderboard-header-safe-area-jump

Conversation

@joaosantos15

@joaosantos15 joaosantos15 commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

The Follow Trading screens showed a vertical layout shift on open: the header title and back button painted at the very top of the screen and then dropped to their natural position under the Dynamic Island once the push transition ended. It reproduced on both iOS and Android, intermittently.

Cause. Each screen applied its top inset as native SafeAreaView padding. RNCSafeAreaView measures its own safeAreaInsets as the view is attached, and that measurement lands after the screen's slide_from_right push completes — so the header renders at y=0 for a few frames and then jumps down. Because it's a native measurement race rather than a stale JS value, it is intermittent and platform-independent.

Fix. Turn the top edge off and apply the inset in JS off the already-resolved SafeAreaProvider, so the value is correct on the first committed frame and there is nothing left to recalculate mid-transition. This matches PerpsMarketDetailsView, which is pushed with the same navigation options (headerShown: false + slide_from_right) and is the one screen of its kind that does not exhibit the jump.

Same root cause and fix as #34260 (What's Happening detail view, TSA-969), which is verified working on device.

Screen Before After
TopTradersView edges={['top']} includesTopInset on HeaderStandardAnimated
SocialTradersTabsView edges={['top']} includesTopInset on HeaderStandardAnimated
TraderProfileView edges={['top']} includesTopInset on HeaderStandardAnimated
TraderPositionView no edges (all four) inset on a single wrapper above the header branch

includesTopInset reaches the right place on the animated header: HeaderStandardAnimated spreads into HeaderStandard, which spreads ...headerBaseProps into HeaderBase, where it becomes marginTop: insets.top.

Why TraderPositionView is different

It can't use includesTopInset. It swaps between three headers depending on state, and neither accepts the prop: TraderPositionHeader (loading and failed states) is a hand-rolled Box, and TraderPositionAnimatedHeader renders HeaderStandard with explicit props and no {...rest} spread. Rather than plumb a new prop through two more components, the inset goes on a single wrapper above the branch. That also guarantees the three headers share one value, so switching from the loading header to the loaded one can't introduce a second jump.

Both leaderboard entry points are covered

SocialTradersView picks between SocialTradersTabsView and standalone TopTradersView depending on aiSocialFeedEnabled, so both needed the fix. TopTradersView in embeddedInTabs mode renders a bare list body with no SafeAreaView of its own, so that path is covered by the tabs container.

Related, not addressed here

app/shims/react-native-safe-area-context.tsx exists specifically to route SafeAreaView's top inset through JS instead of native padding — added by #28622 ("fix: Fix UI issue related to SafeAreaView top inset recalculation"). The Metro resolveRequest alias that wired it was removed by the RN 0.81.5 upgrade (#29195), so the shim and its test are now dead code while every SafeAreaView in the app is back on native top padding. Restoring that alias would address this class of bug app-wide, rather than screen by screen.

Changelog

CHANGELOG entry: Fixed the header shifting down after the Top Traders, Trader Profile and Trader Position screens finished opening.

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/TSA-970
Refs: #34260

Manual testing steps

Feature: Follow Trading header placement

  Scenario Outline: user opens a Follow Trading screen
    Given the user is in the app

    When user opens <screen>
    Then the screen slides in from the right
    And the header title and back button are positioned below the notch / Dynamic Island for the whole transition
    And they do not shift vertically once the transition ends

    Examples:
      | screen                                             |
      | the Top Traders leaderboard                        |
      | a trader profile, from a leaderboard row           |
      | a trader position, from a profile row              |

  Scenario: leaderboard renders correctly with the feed tabs flag on and off
    Given the user toggles aiSocialFeedEnabled
    When user opens the Top Traders leaderboard
    Then the header sits below the notch in both the tabbed and standalone layouts

  Scenario: trader position header does not move as data loads
    Given the user opens a trader position on a cold cache
    When the loading header is replaced by the loaded header
    Then the back button stays in exactly the same position

  Scenario: trader position header does not move when loading fails
    Given the position request fails
    When the fallback state renders
    Then the back button stays in exactly the same position

The jump was intermittent before the fix, so repeat each open several times to be confident.

Screenshots/Recordings

Before

After

no-shift.mp4

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

For performance guidelines and tooling, see the Performance Guide.

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
Layout-only safe-area handling on four social leaderboard screens; no auth, data, or navigation logic changes.

Overview
Fixes TSA-970: headers on Follow Trading screens no longer jump down after a slide_from_right push.

Cause: Native SafeAreaView top padding was re-measured after attach, so title/back briefly rendered at y=0 then dropped under the notch.

Change: Drop the top SafeAreaView edge on SocialTradersTabsView, TopTradersView (standalone), and TraderProfileView, and pass includesTopInset on HeaderStandardAnimated so top spacing comes from JS marginTop via the provider. TraderPositionView uses useSafeAreaInsets() and a single paddingTop wrapper around loading/failed/animated headers so the back button stays fixed when state changes.

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

These screens applied their top safe-area inset as native SafeAreaView
padding. RNCSafeAreaView measures its own safeAreaInsets as the view is
attached, and that measurement lands after the `slide_from_right` push
completes — so the header painted at y=0 and then visibly dropped into
place. Being a native measurement race, it reproduced intermittently and
on both platforms.

Turn the top edge off everywhere and apply the inset in JS off the
already resolved provider, matching PerpsMarketDetailsView (pushed with
the same navigation options, and the one screen of its kind that does not
exhibit the jump).

TopTradersView, SocialTradersTabsView and TraderProfileView take
`includesTopInset` on HeaderStandardAnimated, which resolves to
`marginTop: insets.top` in HeaderBase.

TraderPositionView cannot use that prop: it swaps between three headers,
and TraderPositionHeader is a plain Box while TraderPositionAnimatedHeader
renders HeaderStandard without a prop spread. The inset goes on a single
wrapper above the branch instead, so switching headers on load cannot
introduce a second jump.
@joaosantos15 joaosantos15 self-assigned this Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

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.

@metamask-ci metamask-ci Bot added the team-social-ai Social & AI team label Aug 4, 2026
@github-actions github-actions Bot added the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label Aug 4, 2026
@metamask-ci

metamask-ci Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

PR template — items to address before "Ready for review"

Warnings — informational, address before merging:

  • Pre-merge author checklist has unchecked items (e.g. "I've applied the right labels on the PR (see labeling guidelines). Not required for external contributors."). Every box must be consciously checked — see docs/readme/ready-for-review.md.

See docs/readme/ready-for-review.md for the full Definition of Ready for Review.

@github-actions github-actions Bot added the size-M label Aug 4, 2026
@joaosantos15 joaosantos15 removed the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label Aug 4, 2026
@joaosantos15
joaosantos15 marked this pull request as ready for review August 4, 2026 15:23
@joaosantos15
joaosantos15 requested a review from a team as a code owner August 4, 2026 15:23
@github-actions github-actions Bot added the risk:medium AI analysis: medium risk label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: None (no tests recommended)
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
All 4 changed files are in the SocialLeaderboard feature area (SocialTradersTabsView, TopTradersView, TraderPositionView, TraderProfileView). The changes are purely UI layout fixes: they change SafeAreaView edges from ['top'] to ['bottom', 'left', 'right'] and add includesTopInset to HeaderStandardAnimated (or manually apply useSafeAreaInsets().top via a wrapper Box in TraderPositionView). This fixes a visual glitch where the native SafeAreaView top padding was recalculated after the slide_from_right navigation push, causing the header to visibly drop into place.

No existing E2E smoke tests cover the SocialLeaderboard feature (confirmed by searching for SocialLeaderboard, SocialTraders, TopTraders, TraderProfile, TraderPosition in spec files - no matches found). The changes don't affect any shared components (TabBar, navigation, modals, confirmations), controllers, Engine, or core infrastructure. The impact is entirely contained within the SocialLeaderboard views. No performance-sensitive code paths are affected.

Performance Test Selection:
The changes are UI layout fixes (SafeAreaView edge configuration and top inset handling) in the SocialLeaderboard feature. These do not affect any performance-measured flows (onboarding, login, app launch, asset loading, swaps, account list, perps, or predictions). No performance test tags are warranted.

View GitHub Actions results

@sonarqubecloud

sonarqubecloud Bot commented Aug 4, 2026

Copy link
Copy Markdown

@joaosantos15 joaosantos15 changed the title fix: TSA-970 header layout shift on Follow Trading screens fix: TSA-970 header layout shift on Follow Trading screens cp-8.6.0 Aug 4, 2026
@joaosantos15
joaosantos15 enabled auto-merge August 4, 2026 16:06
@joaosantos15
joaosantos15 added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit d157a0d Aug 4, 2026
140 of 156 checks passed
@joaosantos15
joaosantos15 deleted the TSA-970-fix-social-leaderboard-header-safe-area-jump branch August 4, 2026 16:27
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 4, 2026
@metamask-ci metamask-ci Bot added the release-8.7.0 Issue or pull request that will be included in release 8.7.0 label Aug 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-8.7.0 Issue or pull request that will be included in release 8.7.0 risk:medium AI analysis: medium risk size-M team-social-ai Social & AI team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants