Make watched/resume state display deterministic#1611
Conversation
damontecres
left a comment
There was a problem hiding this comment.
I have not fully reviewed these changes, but please consider replacing the pseudo-subscription class PlaybackResultCache for a flow based one that ViewModels can collect from.
There is an example of this in MediaManagementService. It publishes deleted items on a flow. Then ViewModels in the entire nav backstack can collect it, if they want, to update their state in the background even before the user goes back to the page.
f4252fb to
2e47a7c
Compare
|
Great idea! This reminds me of Qt/PySide's Signal/Slot mechanism. Nice to see the same pattern here. Will implement this! 😄 |
2e47a7c to
f2f9649
Compare
|
Done — replaced PlaybackResultCache with a flow-based PlaybackResultService that publishes outcomes on a SharedFlow, modelled on MediaManagementService. ViewModels across the back stack now collect it and update their state in the background, so the home rows and library grid no longer pull on resume. Manually verified on the emulator (resume bar after partial playback, finished items dropping out of "continue watching", manual mark-unwatched). Tests adjusted: PatchWatchingRowTests now covers the non-consuming lookup, and a new PlaybackResultServiceTest covers the flow contract. assembleDefaultDebug, testDefaultDebugUnitTest and pre-commit (ktlint) all pass. Nicer too: the state is updated live in the background and is already correct on return, rather than catching up after the fact. |
07ba20b to
146a937
Compare
146a937 to
929c098
Compare
…the server Derive the resume percentage locally for freshly-played items, refresh the home rows on resume, and remember manual watched toggles, so grids and the continue-watching row reflect the new state immediately rather than racing the asynchronous server playback-stopped report.
929c098 to
f5fc34e
Compare
|
Work's a bit slow on my end, so I figured I'd shoot for a review here. Reading through I think I spotted a bug, and it happened to land in a flow I actually use (marking an item unwatched to reset its progress), so rather than guess I spun up an emulator to check, and it does behave the way I expected. The main fix works great: play partway, back out, and the resume bar shows on the grid right away. The unwatch path is where it goes sideways though. Repro with a movie that has a resume bar: mark it watched, then mark it unwatched, then back to the grid. The bar is still sitting on the tile at the old position, even though the detail page (fresh from the server) correctly shows no resume. It only clears once you leave the grid and come back. Walking the chain: Threading the cleared percentage through from |
Description
The played/watched state is not displayed reliably. The watched status is sometimes not updated in time, so the tile is only correct after leaving it and coming back.
This can be avoided entirely, because the player's final state is fully known in the client. The state stored on the server is still used when leaving the current view.
This affects the resume progress on grids and the "continue watching" row, as well as manually marking an item watched/unwatched.
Related issues
Bug fix — described above.
Testing
Manually verified on the Android TV emulator and a Fire TV Stick (Fire OS / Android 7.1.2):
Unit tests added: WithLocalPlaybackTests (resume-percentage derivation) and PatchWatchingRowTests (row patch/drop logic). assembleDefaultDebug and testDefaultDebugUnitTest pass; pre-commit (ktlint) is clean.
These unit tests cover the decision logic only. The end-to-end wiring — the lifecycle resume trigger, the actual UI rendering and the timing — can only be verified by an instrumented/integration test (emulator + a fake data layer).
@damontecres Would you welcome a separate PR/discussion to set that up?
AI or LLM usage
The analysis and the fix were done by me with AI assistance (Claude). I wrote the description's substance; the English wording was polished/translated with AI. I understand the code and can maintain it.