fix(subtitles): re-annotate invalidated text during autoplay priming

Autoplay priming called onSubtitleChange after a cache miss, which only asks
whether the text is new. When the miss came from an invalidation (mining a
card while the line is on screen) the text was unchanged, so nothing was
scheduled and the line stayed unannotated for as long as it was displayed.
refreshCurrentSubtitle checks the cache generation as well, so it re-tokenizes
for the new generation; the resume fallback is kept for the case where it
genuinely has nothing to do.

refreshCurrentSubtitle also returned false for empty text while a run was in
flight, even though that run goes on to emit the empty subtitle. It now
reports the pending emit so callers do not release the prefetch pause early.

The priming tests now drive the real subtitle processing controller instead of
a stub. The previous stub encoded the wrong assumption about unchanged text
and so could not catch either bug.
This commit is contained in:
2026-08-04 00:21:06 -07:00
parent 2003efa235
commit c9baaeea17
5 changed files with 165 additions and 41 deletions
@@ -125,9 +125,13 @@ export function createAutoplaySubtitlePrimingRuntime(deps: AutoplaySubtitlePrimi
// Provisional raw emit: keep prefetch paused until the tokenized payload
// for this line is delivered by the processing controller.
emitSubtitlePayload({ text, tokens: null }, { resumePrefetch: false });
if (!subtitleProcessingController.onSubtitleChange(text)) {
// Cache miss on text the controller already holds (it was invalidated
// under us): nothing will be tokenized, so no emit is coming.
// refreshCurrentSubtitle, not onSubtitleChange: the cache miss above can be
// an invalidation (mining a card) on text the controller still holds, and
// onSubtitleChange treats unchanged text as nothing to do, which would
// leave this line permanently unannotated. refreshCurrentSubtitle also
// re-tokenizes for a new cache generation.
if (!subtitleProcessingController.refreshCurrentSubtitle(text)) {
// Nothing scheduled, so no emit is coming to release the pause.
deps.getSubtitlePrefetchService()?.resume();
}
return true;