Files
encore/docs/TODO.md
T
2026-07-27 00:16:46 -04:00

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-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 "<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.