Skip to content

Redesign player UI with new full-screen layout and queue/lyrics modes - #5

Merged
ingoau merged 16 commits into
mainfrom
claude/loving-euler-m3kqyo
Sep 24, 2026
Merged

ingoau merged 16 commits into
mainfrom
claude/loving-euler-m3kqyo

Conversation

@ingoau

@ingoau ingoau commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Summary

This PR implements a comprehensive redesign of the player interface, introducing a new full-screen player layout with tabbed modes (lyrics, queue, about), improved animations, loading skeletons, and enhanced visual polish throughout the player and related screens.

Key Changes

Player UI Redesign

  • New full-screen player layout (NowPlayingPage.kt): Replaces the previous implementation with a modern design featuring the artwork, playback controls, and mode selection pills
  • Mode-based navigation: Introduces three player modes accessible via pills:
    • Lyrics mode (LyricsPage)
    • Queue mode (QueuePanel)
    • About mode (new PlayerAbout.kt)
  • Enhanced transport controls (Transport.kt): Redesigned playback controls with improved animations and visual feedback
  • Improved mini player (MiniPlayerBar.kt): Updated styling with better typography and layout

Sheet and Modal Improvements

  • Refactored NowPlayingSheet.kt: Simplified architecture focusing on sheet behavior and mode switching rather than tab management
  • Better gesture handling: Improved drag detection and predictive back support
  • Dynamic theming: Enhanced color scheme transitions based on artwork

Loading States & Skeletons

  • New shimmer system (Shimmer.kt): Implements loading skeleton UI with animated shimmer effect
  • Skeleton components: Added SkeletonLine, TrackRowSkeleton, AlbumCardSkeleton, AlbumStripSkeleton for consistent loading states
  • Detail screen improvements (DetailScreens.kt): Displays skeletons while loading, preventing layout shifts

Queue Panel Enhancements

  • Redesigned queue list (QueuePanel.kt): Improved visual hierarchy with better spacing and typography
  • Playback mode controls: Added shuffle and repeat mode toggles with visual indicators
  • Better item interactions: Enhanced swipe-to-dismiss and drag-handle affordances

Navigation & Transitions

  • New transition system (Transitions.kt): Implements Material Design shared axis transitions for screen navigation
  • Scroll-to-top behavior (ScrollToTopOnReselect): Tabs scroll to top when reselected
  • Improved bottom bar (BottomBar.kt): Better state management and scroll integration

Testing & Accessibility

  • Screenshot testing (AppScreenshotTest.kt): New visual regression testing framework
  • Enhanced queue tests (QueueScreenTest.kt): Improved test coverage for queue functionality
  • Accessibility improvements: Better semantics for new UI elements, including state descriptions and custom actions

Visual Polish

  • Improved animations: Added fade, scale, and content size animations throughout
  • Better typography: Enhanced font weights and text styling
  • Color animations: Smooth color transitions for interactive elements
  • Gradient effects: Added visual depth with gradient overlays

Resource Updates

  • New string resources (strings_player.xml, strings_queue.xml): Localization strings for new UI elements
  • Motion conventions (Motion.kt): Updated animation specifications for new components

Notable Implementation Details

  • Loading skeletons use a single ShimmerHost to drive animations efficiently across multiple skeleton elements
  • The player sheet uses AnchoredDraggable for smooth gesture-driven interactions
  • Mode switching uses AnimatedContent for smooth transitions between lyrics, queue, and about views
  • Detail screens show skeleton content while loading to prevent layout shifts and provide better perceived performance

https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7

…d stable playlist reorder

Shimmer skeletons (one sweep per host, draw-phase only, static under reduced
motion) replace blank and false-empty states on Home, Library tabs and detail
pages; detail pages show their top bar at once. Paged lists keep index keys
with content types so skeletons turn into items in place, and album skeletons
match the card's size. Artwork remembers resolved paths and crossfades in.
Library lists take the bar height as content padding. Playlist drag moves
locally with id+occurrence keys and commits one move on drop. Home keys its
history re-query on the track id and animates its rows. Search focuses the
field on the first visit only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
…rtup jump

- NavHost: Material shared X axis for pushes/pops (predictive back scrubs the
  pop), quick directional fade-through for bar/rail switches, plain short
  fades with reduced motion; replaces the 700 ms default crossfade.
- Nav bar height known on the first frame (64 dp + nav inset), measurement
  only corrects it; bar on surfaceContainer.
- Re-tapping the selected place pops to its root, or emits
  LocalTabReselected (ScrollToTopOnReselect helpers) at the root.
- Snackbar host lives in the shell: above the mini player and bar, beside
  the rail on wide layouts, easing down as the full player opens.
- Full-player album/artist links collapse the sheet as they navigate;
  devicesOpen survives rotation.
- LocalPlayerVisible; BottomContentInset only reserves mini-player room
  while something is playing.
- Theme: every colour role animates (no-bounce spring) so accent, dark
  mode and artwork-seed changes crossfade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
Floating mini-player pill with a drawn progress ring and marquee text; the
pill's margin and corners morph into the full-screen sheet. Sheet progress and
playback position are read only in layout/draw lambdas, so drags and ticks no
longer recompose the player. One always-present theme call with an animated
artwork colour scheme (no subtree rebuild at 5%), blurred-artwork backdrop
with gradient fallback, measured flying hero artwork (thumb to slot), paused
artwork shrink, Metrolist transport row with press weights and bounce,
wavy seek bar with tap-to-seek and held seek target, no-bounce sheet spring,
saveable sheet state, animated pill in/out, queue stops auto-scrolling while
the user browses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
The player's endless animations keep compose busy, so an auto-advancing
test clock could run through the snackbar's whole lifetime between checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
One list: History (oldest first, Clear), Now playing, Playing next (Clear),
Continue playing from the context, then autoplay. It opens at Now playing,
with a tail spacer so history is only revealed by scrolling up, and follows
the current track unless the user touched the list in the last 8 s. A fixed
header holds equal-width tonal toggles for shuffle, repeat (off/all/one) and
autoplay. Rows are transparent over the player's backdrop, keep drag, swipe
and the remove/move accessibility actions. QueueList(modifier, contentPadding)
is the embeddable API; QueuePanel wraps it. Saved queues and the undo history
move to the Recent queues screen (undo history in a sheet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
…er with modes

Mini player: a floating card (12 dp margins, 16 dp corners, soft shadow,
600 dp max width) in the nav-bar container colour, 48 dp rounded artwork,
play/pause + next, a 3 dp progress line along its bottom edge; the sheet's
clip is the card, so it still grows into the full player. The navigation bar
is transparent over an eased surface scrim; content runs under both
(BottomContentInset / BottomOverlayInset include the bar).

Full player (owner's mockup, Material 3 Expressive): "Playing from" + queue
source and a collapse chevron; one artwork that moves between the big slot
and a 56 dp thumbnail beside the title as the mode changes; Lyrics / Queue /
About replace the artwork in place (tabs with selected state, persisted in
NowPlayingSheetState and its Saver); favourite, add to playlist, More;
wavy seek bar with elapsed/total; shape-morphing play/pause (cookie <->
rounded square) with squishing tonal skip buttons; sleep timer and Connect
flank the mode pills. About shows the track's details and the rating. The
flying artwork lands on whichever slot the artwork is in. Lyrics embed
without their own background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
…s under the bar by semantics

The full player's one artwork is placed and sized in the layout phase (only
while the mode or paused size animates), so its bounds match what shows.
Settings rows scrolled to the viewport's edge now sit under the transparent
navigation bar, so the tests click them through semantics.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
…ar the bar

Queue rows are transparent now, so a resting swipe-to-remove background
showed through as solid red rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
…rating in place of the star

- Queue toggles no longer fade with the list's top edge
- Remove the favourite star; the 5-star rating sits under the title in
  artwork mode (About keeps it in the other modes)
- Tighter title / artist spacing (the links' 48 dp targets tuck under the title)
- The bottom scrim fades out half-way up the floating mini player

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
…s on the thumbnail

The artist links' touch targets are trimmed evenly above and below, so the
title/artist block centres against the thumbnail and buttons; the block
keeps 12 dp below for the targets to reach into.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
Conflict in NowPlayingPage.kt: keep the redesigned player and move main's
long-press-to-take-over-playback onto the Connect button, now in the header.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2Tf8awF8aEeE7VRtRTuQ7
@ingoau
ingoau merged commit 603094b into main Sep 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants