3.3 KiB
3.3 KiB
Plan — seek
Executes architecture/seek.md against quality/seek.md. One commit:
the change is a single thin path from key to sink, and half-wiring it
would leave a dead RPC.
A — The engine (where the only real logic is)
- A1 —
PlayerEngine::seek_target— a pure function of (current position, delta millis, known duration) returning the absolute target: saturating on both ends, 0 as the floor,duration - 1 sas the ceiling when the duration is known, no ceiling when it is 0. Extracted as a free function so the arithmetic is testable without an audio device. Verifies: G1, G5, G6, G7. - A2 — Rewrite
PlayerEngine::seek_toto route through the same helper, dropping theclamp(1s, duration)that panics whenever the duration is unknown or under a second. Verifies: G1. - A3 —
PlayerEngine::seek_by— readssink.get_pos(), applies A1, callstry_seek, and on success notifiesPlayerMessage::Elapsedwith the new position so a paused seek is visible. Refuses when stopped. Verifies: G4, G8, G9. - A4 —
PlayerEngineCommand::SeekBy+Player::seek_byon the existing bounded reply pattern. Verifies: G3. - A5 — Engine tests: extremes (
i64::MIN/MAX), zero duration, short track, composition, near-end saturation. Verifies: G1, G4–G7.
B — Wire and server
- B1 — Proto:
rpc Seek(SeekRequest) returns (SeekResponse)withsint32 delta_millis, documented with the clamping contract. Verifies: G10. - B2 —
PlaybackCommand::Seek { delta_millis }+ itsname()arm, and the playback handler that forwards toplayer.seek_byand warns on failure. No state. Verifies: G2, G12. - B3 —
RpcService::seekfollowing thechange_volumeshape (record the field, send, return empty). Verifies: G10. - B4 — Server test that the command reaches the player with the delta unchanged. Verifies: G11.
C — Clients
- C1 — TUI:
Action::SeekForward/SeekBackward,Ctrl-f/Ctrl-bbindings inScope::Globalwith help text,MessageFromUi::Seek(i64), thelib.rsarm,rpc.rswrapper,SEEK_STEPconstant, dispatch tests. Verifies: G13, G14, G15. - C2 — Web: the same two actions in
keymap.rs(global, withHELProws),Rpc::seek, theapp.rsdispatch arms, and⏪/⏩buttons in the transport bar. Verifies: G13, G14, G15. - C3 — CLI:
GlobalCmd::Seek { seconds: i32 }withallow_negative_numbers, and its executor arm. Verifies: G14.
D — Docs and gates
- D1 — Docs: key tables (
docs/src/clients/tui.md,docs/src/clients/web.md), the CLI page'sgloballist, and the within-track/end-of-track/HLS sentences indocs/src/queue.md. Verifies: G16. - D2 — Gates: workspace tests,
check-features,cargo fmt, a wasm build ofcbd-web, and the book build. Verifies: G17. - D3 —
plan/summary.mdentry, then commit.
Deferred (recorded, not dropped)
- Absolute seek + click-to-seek on the web progress gauge (the gauge is already rendered; needs one proto field and a click handler).
- Configurable step size, and a larger step on
</>. - Chapter-aware seek for podcasts/audiobooks — no provider exposes chapter marks through the library model.