Skip to content

fix(events): prevent follow button flash on contest page#14508

Open
dylanjeffers wants to merge 1 commit into
mainfrom
fix/contest-follow-button-flash
Open

fix(events): prevent follow button flash on contest page#14508
dylanjeffers wants to merge 1 commit into
mainfrom
fix/contest-follow-button-flash

Conversation

@dylanjeffers

Copy link
Copy Markdown
Contributor

Summary

Small UX nit reported by Ray in Slack: when loading a contest page, the Follow button briefly flashes "Follow" (unfollowed state) before snapping to "Following" for users who already follow the contest.

Cause

The button derived its state from useEventFollowState with const isFollowed = !!followState?.isFollowed. While the query is in-flight followState is undefined, so isFollowed evaluates to false and the button renders the unfollowed "Follow" state — then re-renders to "Following" once the query resolves.

Note: a placeholderData/staleTime tweak on the query does not fix this — React Query already returns cached data immediately, so the flash only happens on a genuine first load with no cache. The real fix is to not commit to a label until the data resolves.

Fix

Gate the visible follow button on the query's isPending state. While loading, render a spinner-only button (the fixed width keeps layout stable) instead of the misleading "Follow" label:

  • packages/web/.../desktop/ContestPage.tsxisLoading={isFollowStatePending}, empty label while pending.
  • packages/mobile/.../contest-screen/ContestScreen.tsx — same treatment on the RN button.
  • Mobile web (components/mobile/ContestPage.tsx) hides follow inside an overflow kebab menu, so there's no visible flash on load — left unchanged.

Test

Added a regression test to ContestPage.test.tsx asserting that neither "Follow" nor "Following" renders while the follow state is still loading. Full contest-page suite passes (7/7).

🤖 Generated with Claude Code

The contest follow button briefly rendered "Follow" (unfollowed) before
snapping to "Following" for users who already follow the contest. The
flash happened because the button defaulted to the unfollowed state while
useEventFollowState was still in-flight (data: undefined -> isFollowed
false -> true once resolved).

Gate the visible follow button on the query's isPending state: while
loading, render a spinner-only button (fixed width keeps layout stable)
instead of the misleading "Follow" label, on both the desktop web page
and the React Native contest screen. Mobile web hides follow inside an
overflow menu, so it has no visible flash and is left unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 29, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: a693d98

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

🌐 Web preview ready

Preview URL: https://audius-web-preview-pr-14508.audius.workers.dev

Unique preview for this PR (deployed from this branch).
Workflow run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant