4.1 KiB
Roadmap / TODO
Near-term work after the working MVP (connect + auto-connect, now-playing with transport/volume/options, DataStore-persisted settings). Roughly ordered by priority; not a commitment.
Status legend: [ ] todo · [~] in progress · [x] done
[ ] 1. Proper icons
Replace the placeholder unicode glyphs (GlyphText in NowPlayingScreen.kt —
⏮ ▶ ⏸ ⏭ 🔈) with real Material icons.
- Preferred source: Google Material Symbols / Icons. In Compose the usual
route is the
androidx.compose.material:material-icons-*artifacts (Icons.Filled.PlayArrow,SkipNext,VolumeUp, …).material-icons-corecovers the common set;material-icons-extendedhas everything but is large — prefer core, or import only the specific vector assets we use. - Platform-bundled drawables (
android.R.drawable.ic_media_*) exist but look dated and vary by OEM — avoid; bundle our own for a consistent look. - Adding the dependency means a
deps.jsonregen (see README).
[ ] 2. Settings menu
A dedicated settings screen where the user can view every setting and reset it.
- Currently settings (host/port) are only editable by hitting Disconnect to get back to the connect form. Add a real settings route.
- Include a Reset action that clears DataStore (add a
clear()toSettingsRepository). - Will likely want simple navigation (Navigation-Compose, or a screen enum in
PlayerViewModel/AppScreen). - Room to grow: password field, connection timeout, theme, keep-screen-on.
[ ] 3. Cast-style volume control
When the MPD server is playing, present the volume control as a "casting" style remote-volume control — the way MALP (and Google Cast) do — making it visually clear you're controlling the server's output, not the phone's.
- Functionally we already send
setvolto the server (MpdClient.setVolume); this is mostly a UX/affordance change: a cast icon, "Casting to " label, distinct styling for remote vs local volume. - Reference behaviour: MALP.
[ ] 4. Library browse — albums
A screen to browse all albums on the server (artists can come later).
- MPD commands:
list album group albumartist(orlist album), andfind album "<name>"to fetch an album's tracks; add to the queue withadd/findadd. ExtendMpdCommands+MpdClient. - Grid or list of albums → tap to view/queue tracks.
[ ] 5. Album / artist images
Pull artwork for the now-playing track and for the album browse grid.
- MPD serves art over the protocol via
albumart <uri> <offset>andreadpicture <uri> <offset>(embedded art).MpdConnectionalready handles binary responses, so the transport groundwork is done — add the commands, loop over offsets to fetch the whole image, and decode. - Needs an image loader + caching. Coil (
io.coil-kt) is the standard Compose choice; a customMpdArtFetchercould feed it. Dependency →deps.jsonregen.
[ ] 6. BUG: idle connection drops after a few minutes → kicked to connect page
After a few minutes idling, the app surfaces "connection closed mid-response" and falls back to the connect screen. MALP does not do this.
- Error origin:
MpdConnection.readResponse()hits EOF and throwsMpdConnectionException("connection closed mid-response"); the idle loop'scatch (IOException)callsfailAndClose()→MpdConnectionState.Error→ UI shows the connect form. - Likely causes to investigate:
- Android Doze / WiFi power-save tearing down sockets when the screen is off or the app is backgrounded (most likely on a portable DAP/phone).
- MPD's
connection_timeout(default 60s) closing a connection it considers idle — a parkedidleshould count as active, but the command connection sits silent; a periodicpingkeepalive may be needed. - NAT/router idle-connection reaping (less likely on LAN).
- Fix direction: don't treat an idle-connection drop as a fatal error — instead
auto-reconnect transparently (re-open connections, re-issue
idle, resync state) and keep showing the player. Consider a keepalive ping and, for backgrounded playback control, a foreground service / partial wakelock.