Skip to content

feat: add new-feature badge + 50/50 A/B test on play queue button#14254

Merged
dylanjeffers merged 2 commits intomainfrom
claude/heuristic-turing-a1159a
May 7, 2026
Merged

feat: add new-feature badge + 50/50 A/B test on play queue button#14254
dylanjeffers merged 2 commits intomainfrom
claude/heuristic-turing-a1159a

Conversation

@dylanjeffers
Copy link
Copy Markdown
Contributor

Summary

  • Adds a pulsing accent dot to the queue button in the web play bar and the mobile now-playing actions bar to highlight the new play-queue feature.
  • Gates the badge behind a new QUEUE_NEW_FEATURE_BADGE feature flag (default off), so the 50/50 cohort split is configured in Optimizely — existing PLAY_QUEUE_OPEN analytics can be split by treatment in the experiment dashboard without new events.
  • Dismisses the badge permanently on the user's first queue open via shared local storage (@queue-new-feature-badge-dismissed), so users only see the highlight once.

Implementation

  • New flag: FeatureFlags.QUEUE_NEW_FEATURE_BADGE in packages/common/src/services/remote-config/feature-flags.ts.
  • New cross-platform hook: useQueueNewFeatureBadge in packages/common/src/hooks/useQueueNewFeatureBadge.ts — composes useFeatureFlag with the dismissed-flag in useAppContext().localStorage (uses the same wrapper that backs both web localStorage and mobile AsyncStorage). Returns { showBadge, dismiss }.
  • Web: QueueButton.tsx renders an absolutely positioned pulsing dot (Emotion keyframes) at the icon's top-right when showBadge is true; calls dismiss() in the click handler before toggling open. Tooltip flips to "New" when badge is showing.
  • Mobile: ActionsBar.tsx wraps the queue IconButton in a View with a sibling Animated.View dot driven by react-native-reanimated's useSharedValue + withRepeat/withTiming (matching Skeleton.tsx's shimmer pattern); handleOpenQueue dismisses before delegating to openQueue.

Notes on the A/B split

The 50/50 traffic allocation is configured in the Optimizely dashboard for the queue_new_feature_badge flag — this is the existing pattern in the repo (defaults stay false in code; rollout is a remote-config concern). Treatment-arm users see the badge until first interaction; control-arm users see the queue button as before.

Test plan

  • Default state (flag off): queue button looks identical to before on web and mobile — no badge, no extra renders.
  • Override flag enabled: pulsing dot is visible on the queue button until the user opens the queue once.
  • After first queue open, reload and confirm badge no longer appears (persisted in local storage / AsyncStorage).
  • Verify Optimizely 50/50 rollout: half of users in treatment cohort see badge, half do not, regardless of dismissed state.
  • Confirm PLAY_QUEUE_OPEN analytics still fire normally after dismissal.

🤖 Generated with Claude Code

dylanjeffers and others added 2 commits May 6, 2026 13:13
Match the union of filters (genre, mood, key, bpm, isPremium,
hasDownloads, isVerified) on both web and mobile so the All tab
isn't forced to clear filters when switching off a sub-category.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces QUEUE_NEW_FEATURE_BADGE feature flag (default off) gating a
pulsing accent dot on the queue button in the web play bar and the mobile
now-playing actions bar. The badge is dismissed permanently on first
queue open via local storage, ensuring users only see the highlight once.
The 50/50 split is configured via Optimizely on the flag, so cohort
assignment lives outside code and existing PLAY_QUEUE_OPEN analytics can
be split by treatment in the experiment dashboard.

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

changeset-bot Bot commented May 6, 2026

⚠️ No Changeset found

Latest commit: 9c9efea

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

github-actions Bot commented May 6, 2026

🌐 Web preview ready

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

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

@dylanjeffers dylanjeffers enabled auto-merge (squash) May 7, 2026 04:04
@dylanjeffers dylanjeffers merged commit 65cd8b6 into main May 7, 2026
14 checks passed
@dylanjeffers dylanjeffers deleted the claude/heuristic-turing-a1159a branch May 7, 2026 04:04
dylanjeffers added a commit that referenced this pull request May 7, 2026
#14269)

## Summary

Sets an Amplitude user property `queue_new_feature_badge` = `'on' |
'off'` so the A/B test for the play-queue "New" badge
([#14254](#14254)) can be
sliced in Amplitude. Currently nothing surfaces the variation to
Amplitude, so charts can't filter by treatment vs. control.

- Adds `queue_new_feature_badge?: 'on' | 'off'` to `IdentifyTraits`.
- In `useQueueNewFeatureBadge`, dispatches `ANALYTICS/IDENTIFY` once
when the feature flag has loaded, with the variation as a trait. The
existing analytics saga forwards it to both web and mobile Amplitude
SDKs as a user property via `Identify.set(...)`.
- Per-mount `useRef` guard so it dispatches at most once per mount;
Amplitude `Identify.set` is idempotent so re-fires across mounts are
harmless.

## Optimizely setup (separate, not in this PR)

Create a flag named `queue_new_feature_badge` (lowercase, exact) with a
Targeted Delivery rule at 50% included → variation `on`. The flag
default is `false`
([feature-flags.ts](packages/common/src/services/remote-config/feature-flags.ts)),
so until the rule is on, all users get tagged `'off'`.

## Test plan

- [ ] In dev with the flag forced on, confirm an `Identify` call fires
once with `queue_new_feature_badge: 'on'` (Amplitude network panel /
Redux DevTools `ANALYTICS/IDENTIFY` action).
- [ ] In dev with the flag forced off, same check with `'off'`.
- [ ] Verify on web (`QueueButton`) and mobile (`ActionsBar`) — both
consume the hook.
- [ ] Verify in Amplitude that the user property shows up on the next
event after the dispatch.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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