88 lines
4.1 KiB
Markdown
88 lines
4.1 KiB
Markdown
# 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
|
|
|
|
---
|
|
|
|
## [x] 1. Proper icons
|
|
|
|
Done. Replaced the placeholder unicode glyphs in `NowPlayingScreen.kt` with real
|
|
Material icons (`Icons.Filled.SkipPrevious/PlayArrow/Pause/SkipNext/VolumeUp`,
|
|
plus `Repeat`/`Shuffle` leading icons on the chips) from
|
|
`androidx.compose.material:material-icons-extended`.
|
|
|
|
- That artifact bundles thousands of vectors, so the **debug** APK grew ~7 MB
|
|
(expected — debug can't shrink). Enabled **R8 + resource shrinking** on the
|
|
`release` build type, which strips the unused icons: release APK is ~1.2 MB.
|
|
- Considered `material-icons-core` (too small — no media icons) and bundling
|
|
individual vector drawables (leaner but manual); the extended dep + R8 was the
|
|
best effort/quality trade.
|
|
|
|
## [ ] 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()` to
|
|
`SettingsRepository`).
|
|
- 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 `setvol` to the server (`MpdClient.setVolume`);
|
|
this is mostly a UX/affordance change: a cast icon, "Casting to <host>" 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` (or `list album`), and
|
|
`find album "<name>"` to fetch an album's tracks; add to the queue with
|
|
`add`/`findadd`. Extend `MpdCommands` + `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>` and
|
|
`readpicture <uri> <offset>` (embedded art). **`MpdConnection` already 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 custom `MpdArtFetcher` could feed it. Dependency → `deps.json` regen.
|
|
|
|
## [ ] 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 throws
|
|
`MpdConnectionException("connection closed mid-response")`; the idle loop's
|
|
`catch (IOException)` calls `failAndClose()` → `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 parked `idle` should count as active, but the *command* connection
|
|
sits silent; a periodic `ping` keepalive 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.
|