# 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-core` covers the common set; `material-icons-extended` has 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.json` regen (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()` 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 " 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 ""` 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 ` and `readpicture ` (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.