Skip to content

Play what's kept on this phone, on the phone - #64

Open
hatstand wants to merge 8 commits into
mainfrom
claude/project-thread-wugi27-phone-player
Open

hatstand wants to merge 8 commits into
mainfrom
claude/project-thread-wugi27-phone-player

Conversation

@hatstand

@hatstand hatstand commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Builds on #63 (Keep on this phone), and through it #62, #61 and #57. Until they merge, review only its own commits: "Play what's kept on this phone, on the phone" (1623bd7) and the fix after it (f8d7b36).

It's part of media sync, which keeps music from Clementine on the phone to play offline. The design doc describes the whole of it.

What it does

Like the rest of media sync, this only shows in builds with the testing features, and needs something kept on the phone first. It does on iOS what Android-Remote#364 does on Android, with the same strings and notes for translators.

  • On this phone: tapping something in Kept on this phone opens its songs on the phone, in its order, with how it stands, Play and Shuffle, and each song's artist, album and length. Tapping a song plays the songs from it. The song playing is marked.
  • Playing: PhonePlayer (in ClementineKit) plays them with AVQueuePlayer, as music: in the background, and on AirPlay or Bluetooth like any other. While it has a song, the lock screen and Control Center show it and their buttons control it, rather than Clementine.
  • One player at a time: starting to play on the phone pauses Clementine if it's playing.

Not yet

  • The app's own player: the player screen and mini player still show Clementine. Choosing where to play, and a queue for the phone, come next.
  • Covers: synced songs have none yet, so the lock screen shows none.

Tests

PhonePlayerTests: reading a kept song's tags, what to show when it has none, and the order songs play in.


Generated by Claude Code

The phone's record of what it keeps for offline listening: the sync
rules, the songs and covers it has downloaded, which rules want which
songs, and plays made on the phone, all kept per Clementine by its
server id. A song is stored once however many rules want it, and goes
once no rule wants it and it isn't pinned. It has the same tables as
the Android client's, and nothing uses it yet.

The database wrapper learns NULLs, blobs and typed rows for it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R2bAq6kZW6eyymkA3zsd4p
SyncEngine brings the phone's songs in line with the rules for one
Clementine: it asks for each rule's manifest, downloads the songs that are
new or changed into the synced songs' folder as Artist/Album/NN Title, and
deletes the songs no rule or pin wants any more. A song in several rules is
downloaded once, a rule that fails keeps its songs and lets the others carry
on, and a sync cut short keeps what it downloaded. It talks to Clementine
through SyncConnection, so the tests run it against a fake one.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R2bAq6kZW6eyymkA3zsd4p
RemoteSession.syncing says whether this Clementine can sync: it has
SERVER_FEATURE_SYNC and a server id, the build has the testing features,
and Clementine lets the phone download songs. When one connects, the
Syncer runs the sync engine against it: ClementineSyncConnection asks for
manifests over the session's connection, waiting at most a minute for each
source's answer, and fetches songs from Clementine's HTTP server, as the
renderer does. Songs go to Documents/Clementine/Synced, which the Downloads
tab leaves out of the songs on the phone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R2bAq6kZW6eyymkA3zsd4p
When Clementine syncs, touching and holding an artist or an album in the
library offers Keep on this phone, which makes a rule for it and syncs it.
An album is kept by album artist, as Clementine files it, so one album here
can be several rules. Downloads lists what's kept, with how its last sync
went, Sync now, and Remove from this phone, which asks first and deletes
the songs nothing else kept has. The tab and screen are called On this
phone when Clementine syncs or something is kept, and the rules of the
Clementine last connected show before connecting. The strings, and their
notes for translators, are the Android client's.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R2bAq6kZW6eyymkA3zsd4p
Tapping something in Kept on this phone opens its songs, with Play and
Shuffle, and each song's artist, album and length. Tapping a song plays the
songs from it, and the song playing is marked. PhonePlayer plays them with
AVQueuePlayer, as music, so they play in the background and on AirPlay or
Bluetooth; the lock screen and Control Center show and control it while it
has a song. Starting to play on the phone pauses Clementine if it's
playing, so only one plays. The strings, and their notes for translators,
are the Android client's.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R2bAq6kZW6eyymkA3zsd4p
@github-actions

Copy link
Copy Markdown

Screenshots

From run 40723775225, against a real Clementine. Left: main. Right: this pull request, light and dark.

Screen main This PR This PR, dark
01_connect
02_queue
03_player
04_connection
05_settings
06_library
07_library_album
08_search
09_outputs
10_internet
11_internet_radio
fold_outer_player –

Screens at a failure

dark_failure

failure

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