Skip to content

[Mobile] Fix queue drawer: full scroll, header, and full-screen toggle#14278

Merged
dylanjeffers merged 2 commits intomainfrom
claude/elastic-chandrasekhar-d3c562
May 8, 2026
Merged

[Mobile] Fix queue drawer: full scroll, header, and full-screen toggle#14278
dylanjeffers merged 2 commits intomainfrom
claude/elastic-chandrasekhar-d3c562

Conversation

@dylanjeffers
Copy link
Copy Markdown
Contributor

Summary

The mobile play queue drawer had several broken behaviors visible in the original screenshot:

  • Opened mid-queue with no header/handle visible — drawer was auto-sized to its content, so on long queues the drawer's height exceeded the screen and its top translated off-screen.
  • Couldn't scroll up to see prior tracks because the list only rendered queue.slice(index + 1) (now-playing + upcoming).
  • No way to expand to full-screen.
  • Drag handle and "Queue" header were rendered, but pushed above the visible area by the same off-screen translation.

Changes

  • Constrain drawer height<View> wrapping the drawer content now has a fixed height of ~85% of the screen (or full screen when expanded), so the drag handle and header are always on-screen regardless of queue length.
  • Render full queue — the DraggableFlatList now renders all queue items (past / now-playing / upcoming), with the current track highlighted via accent color. Past tracks render at 0.6 opacity. The list opens scrolled to the now-playing track via initialScrollIndex, so the user can scroll up to see history and down to see upcoming.
  • Fixed row height + getItemLayout — every row is exactly ROW_HEIGHT (64), which is required for initialScrollIndex to land in the right place without breaking scroll bounds (the FlatList bug the user identified).
  • Full-screen toggle — added an IconCaretUp / IconCaretDown IconButton in the header next to "Clear". Tapping it animates the drawer between collapsed (~85%) and full-screen heights via the existing drawer slideIn animation.
  • Reorder restricted to upcoming — drag handles only render on upcoming items; the reorder dispatch rejects drags involving the now-playing or past indices.
  • "Up Next from source" footer — moved into ListFooterComponent so it scrolls together with the queue list.

Test plan

  • Open queue drawer with a long queue (50+ tracks): drag handle and "Queue" header are visible at the top, and the list opens scrolled to the now-playing track.
  • Scroll up: see tracks that played before the current track (dimmed). Tap one to jump back.
  • Scroll down: see upcoming tracks. Tap to jump forward.
  • Tap the up-caret in the header: drawer expands to full screen. Tap the down-caret: drawer collapses back.
  • Long-press the drag icon on an upcoming track and reorder: only upcoming positions are valid drop targets.
  • Empty queue still shows the empty state with header visible.
  • iOS and Android both behave the same.

🤖 Generated with Claude Code

The queue drawer was rendering its content without a height constraint, so
on long queues the drawer's auto-sized height exceeded screen height and
the drawer translated above the top of the screen — hiding the drag handle
and header, and leaving the user stuck mid-list with no way to scroll up.
The list also only included tracks after the currently playing one, so
prior queue history was unreachable.

- Constrain drawer to ~85% of screen height (full screen when expanded)
  so the header is always visible.
- Render the entire queue (past + now-playing + upcoming) in the
  DraggableFlatList; current track is highlighted and visible at top of
  viewport via initialScrollIndex, with past tracks scrollable above and
  upcoming below.
- Add a fullscreen expand/collapse IconButton in the header.
- Move the "Up Next from source" section into ListFooterComponent so it
  scrolls with the queue.
- Add fixed row height + getItemLayout so initialScrollIndex works
  reliably and scroll bounds aren't clipped.
- Restrict drag-to-reorder to upcoming tracks only.

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

changeset-bot Bot commented May 8, 2026

⚠️ No Changeset found

Latest commit: 2cab057

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

The pulsing/swelling dot badge over the queue button was visually noisy.
Drop the animation and the absolute-positioned badge entirely; instead
tint the queue IconButton with the 'active' color when there's a new
feature to surface, matching the cast button's pattern. Dismissal still
runs on first open.

- Remove withRepeat/withTiming pulse animation and Animated.View badge
- Set IconButton color to 'active' when showQueueNewFeatureBadge is true
- Drop unused reanimated imports and queueButtonContainer/newFeatureBadge styles

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dylanjeffers dylanjeffers merged commit 719d399 into main May 8, 2026
3 checks passed
@dylanjeffers dylanjeffers deleted the claude/elastic-chandrasekhar-d3c562 branch May 8, 2026 02:12
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