diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-09-26 18:25:45 +0000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-09-26 18:25:45 +0000 |
| commit | 06939defdbf144e630b5435bba552a730461440b (patch) | |
| tree | 311267dc2109e1db24dcfc04176fab14d0b140e0 /tools | |
| parent | aa9c0a386f19bb58c50c81fd79d9509d2883cffe (diff) | |
Hide played episodes, and hand off to the video at the right moment
Two of Peter's asks.
Played episodes are hidden by default. An episode you have heard is done with,
and leaving it in the list buries the ones that are not. A global toggle on the
show screen brings them back, so a mis-tapped "played" can still be found --
stored in DataStore, which has been a declared dependency since phase 1 with
nothing using it. Android Auto always hides them regardless of the toggle: a
car list is scrolled blind at a traffic light.
Hand-off carries the position both ways. Out: "Watch from here" opens the video
on its own site at the point reached. In: a link shared from YouTube with a
timestamp on it was shared at that moment deliberately, so the episode starts
there rather than at the top. WatchLink does both and is pure, because an
unrecognised URL shape fails silently -- as a link that simply starts from the
beginning -- and YouTube produces a lot of shapes.
The button sits on the episode screen as well as the player. That was not the
first design, and testing changed it: the player-only version is unavailable
exactly when it is most wanted, because an episode YouTube declines to serve
never starts playing and so never reaches the player at all.
Verified on a device, round trip: youtu.be/dQw4w9WgXcQ?t=90 shared in stored a
position of 90000, the episode screen offered Watch, and tapping it fired
youtube.com/watch?v=dQw4w9WgXcQ&t=90s. Marking an episode played removed it
from the list, the toggle brought it back, and the preference survived a
restart. An ordinary podcast offers no hand-off, having no page to open.
Two things caught on the way. A crash: the episode cache was declared after the
init block that collects from a StateFlow, which emits synchronously, so it was
still null on the first emission -- caught by the launch check, now a plain
field declared with the others. And the played switch needed a contentDescription
distinct from its visible label, or it is ambiguous to pick -- the same trap the
drip switch hit.
Preferences joins the coverage exclusions: a Context, a file and a generated
Flow, deciding nothing. WatchLink is fully covered.
No permission changes, no schema change. 442 unit tests green, detekt and lint
clean, coverage steady at 90.13.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'tools')
0 files changed, 0 insertions, 0 deletions
