Deep-review round 3 of bug hunt 2026-09.
- loadSession checks, after its await, that it is still the newest call and the player is still
mounted. A late answer used to replace what was playing (Next twice quickly: the slower transcode
landed last and played the middle item under the last one's title, recording its progress there)
or attach a stream to the detached <video> after Back, never destroyed.
- The <video>'s clock is trusted only once the new session has answered. go()'s pause() fires a
timeupdate AFTER the reset to 0 (measured in Chrome), so the previous item's position was sent as
the next item's subtitle position and saved as its progress (final, pushed to Plex).
- Next settles the item being left (final checkpoint + reopen-cache patch) before switching: the
progress cleanup ran with the position already reset and skipped, so every Next dropped the last
stretch watched.
- A seek-restart puts its target into the position state too; the ref alone was re-synced back to
the pre-seek spot by the restart's own render.
- The unmount teardown captures the <video> at mount: React detaches refs before an unmount's
cleanups, so the stop/detach never ran.
- The tracks panel exposes the selected audio/subtitle track via aria-pressed.
Verified in real Chrome on localdev (Westworld S1E6 → Next): the item left was settled at 783 s, the
next asked for subtitles at its own start (0), and no progress was written for it.