Skip to content

feat(player): tablet-portrait player + mini player#164

Merged
ghenry22 merged 18 commits into
masterfrom
feat/tablet-portrait-player
Jun 2, 2026
Merged

feat(player): tablet-portrait player + mini player#164
ghenry22 merged 18 commits into
masterfrom
feat/tablet-portrait-player

Conversation

@ghenry22
Copy link
Copy Markdown
Owner

@ghenry22 ghenry22 commented Jun 2, 2026

Summary

Brings tablet-portrait parity to the player surfaces, ending with a dedicated tablet-portrait mini player — the last gap after the full-screen and split-view layouts already shipped.

Highlights

  • Tablet-portrait mini player — taller floating now-playing card: cover + favorite (left), centered title/artist over an inline draggable seek bar, prev/play/next transport. Symmetric side columns keep the centre column centred; branched in via useIsTabletPortrait. Phone and tablet-landscape are unchanged.
  • Tablet-portrait full player (PlayerTabletPortrait) — horizontal hero band (art + controls) over a Queue/Info/Lyrics section; /player routes here on tablet portrait.
  • Shared player hooks/components — extracted useShuffleOverlay, usePlayerActions, and shared FavoriteButton/BookmarkButton; all four player surfaces migrated onto them.
  • UpNextPanel — inline draggable queue/info/lyrics panel.
  • Plus: Download Full Library, Tuned-In tablet layouts + multi-decade builder (Intl timezone fix), Expo SDK 56 patch bumps, canonical cover-art IDs.

Testing

  • tsc --noEmit clean
  • Full jest suite green (7008 tests, 360 suites)
  • Mini player validated on-device (tablet portrait): layout, drag-seek, transport, favorite, tap-to-expand; phone + landscape unaffected

ghenry22 added 18 commits May 31, 2026 18:32
… hooks

New useShuffleOverlay/usePlayerActions hooks and ShuffleOverlay component;
consumers migrate in follow-up commits.
Consume useShuffleOverlay/usePlayerActions + <ShuffleOverlay/>; type the
shared animated styles as AnimatedStyle<ViewStyle>. Folds in this file's
earlier control-layout work (shuffle in the transport row, skip-interval
buttons in the secondary row, control spacing) since it shares the file.
…e hooks

Consume useShuffleOverlay/usePlayerActions + <ShuffleOverlay/> (alias the
shuffle overlay style to avoid colliding with the expand-entrance
overlayStyle). Fixes the literal 'Shuffling\u2026' overlay text via
t('shuffling'). Folds in this file's earlier control-layout work.
Consume useShuffleOverlay/usePlayerActions + <ShuffleOverlay/> (drops the
panel's entire reanimated import). Folds in this file's earlier change
removing the secondary-row/skip-interval/sleep-timer UI from the panel.
In-tree (non-modal) sliding panel for the tablet-portrait player; reuses
QueueItemRow/AlbumInfoContent/LyricsContent + the player data hooks. Driven
by a parent-owned panelHeight SharedValue + pan gesture on the drag handle.
Tablet-portrait now-playing: collapsing hero+controls over an inline
draggable UpNextPanel with PEEK/HALF/FULL detents; hero collapses into a
compact control strip at full. Reuses shared hooks + leaf components.
Hero is vertically sized so controls stay visible above the panel at HALF.
New useIsTabletPortrait hook (min screen dim >= 600 + portrait, matching
IS_TABLET); the /player route picks the tablet-portrait layout there, else
the phone PlayerView. Phone and tablet-landscape paths unchanged.
Consumers migrate in the follow-up commit.
Remove the four local copies (FavoriteButton/BookmarkButton/Expanded-/Panel-)
in favour of the shared components; each call site passes its own
favoriteButton padding + size. Drops now-dead favorite/bookmark imports.
Cover art (left) + title/progress/controls (right), centered in the space
above the sheet. Bigger art, grouped controls (capped cluster), shorter
default sheet (~44%), and 3 detents (low/default/full) so the sheet pulls
back down — the band re-centers as it moves.
Inset the secondary-row left slot 4px so the sleep-timer lines up under the
shuffle (which has built-in padding), and make the expanded player's bookmark
flush-right to match repeat. Applied to all three players.
…over-art IDs

- group/rename players under player/ (PlayerPhonePortrait, PlayerTabletPortrait, PlayerTabletLandscape, PlayerTabletSplitview, PlayerPhoneMini, PlayerModeContent); rename MoreOptionsSource values to player-* names
- tablet-portrait: drop the draggable sheet for a fixed split over one page-wide gradient with a centered Queue/Info/Lyrics toggle; AlbumInfoContent gains compilation/not-found placeholders + an animated skeleton
- cover-art: key off the entity ID via utils/coverArtId.ts everywhere (prefetch, downloads, store warmers, render); raw coverArt field retained
- image cache: log the previously-silent missing-id placeholder; filter falsy-id shelf items (undefined FlashList keys); clear failedRemoteIds on foreground/server-reachable so transient blips self-heal
- strip all console.* from production builds via babel-plugin-transform-remove-console
Patch-level updates within SDK 56 (expo, expo-router, expo-crypto, expo-notifications, expo-sharing, expo-location, expo-linking, expo-dev-client, expo-build-properties).
- For You re-flows into a responsive bento grid on tablets (lead mix spans 2 cells); phone keeps the hero/medium/compact stack
- Build a Mix: multi-select decades (50s/60s + Earlier/Recent shortcuts), cross-product genre x decade fetch; embedded two-column panel on tablet with wrapping chip/decade clouds, sheet retained on phone
- shared business logic extracted to useMixBuilder hook; sheet and panel are presentation-only
- Jump Back In uses a 150px cover grid on tablet, scroller on phone
- larger Tuned In section titles + more spacing
- fix: set the @formatjs/intl-datetimeformat default timezone from the device (was defaulting to UTC), correcting the My Listening hour labels / peak-hour and all Intl-formatted times
One-tap download of the entire server library from Settings → Storage → Downloaded Music, reusing the standard download queue.

- refresh album/playlist lists, then enqueue every album followed by every playlist (sequential awaits; dedup + already-cached skipping handled by the existing enqueue path)
- shared logic in fullLibraryDownloadService + a small fullLibraryDownloadStore for live progress
- require an empty download queue before starting; if anything is queued, prompt the user to clear it first
- Cancel stops adding more AND clears the download queue (existing clearDownloadQueue)
- error feedback (alert) if preparing fails or items can't be queued
- card button uses the shared settingsStyles to match other settings actions
Taller floating now-playing card for tablets in portrait: cover art +
favorite (left), centered title/artist over an inline draggable seek bar,
and prev/play/next transport. Symmetric side columns keep the centre
column centred on the card. Branched in via useIsTabletPortrait; phone
and tablet-landscape unchanged.
@ghenry22 ghenry22 merged commit 3fda2b6 into master Jun 2, 2026
1 check passed
@ghenry22 ghenry22 deleted the feat/tablet-portrait-player branch June 2, 2026 11:22
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.

1 participant