fix(anki): keep playback paused after overlay pause during timing review

- Treat overlay pause requests during an open media timing review as final: drop held resumes and the review's own playback restore
- Add cancelPlaybackResume to the media timing review runtime
- Test both paused and playing starting states
This commit is contained in:
2026-09-23 01:36:11 -07:00
parent 430120cc63
commit 33e694bc61
3 changed files with 41 additions and 9 deletions
+12 -8
View File
@@ -2051,20 +2051,24 @@ function isExplicitMpvSeekCommand(command: readonly (string | number)[]): boolea
return command[0] === 'seek' || command[0] === 'sub-seek';
}
function isMpvResumeCommand(command: readonly (string | number)[]): boolean {
return (
(command[0] === 'set_property' || command[0] === 'set') &&
command[1] === 'pause' &&
command[2] === 'no'
);
function getMpvPauseCommandValue(command: readonly (string | number)[]): 'yes' | 'no' | null {
if ((command[0] !== 'set_property' && command[0] !== 'set') || command[1] !== 'pause') {
return null;
}
return command[2] === 'yes' || command[2] === 'no' ? command[2] : null;
}
function sendRendererMpvCommand(rawCommand: (string | number)[]): void {
// Overlay auto-pause releases (popup closed, hover left) must not resume playback
// behind an open timing review; the review applies them when it closes.
if (isMpvResumeCommand(rawCommand) && mediaTimingReviewRuntime.deferPlaybackResume()) {
// behind an open timing review; the review applies them when it closes. A pause
// request during the review keeps playback paused after it closes.
const pauseValue = getMpvPauseCommandValue(rawCommand);
if (pauseValue === 'no' && mediaTimingReviewRuntime.deferPlaybackResume()) {
return;
}
if (pauseValue === 'yes') {
mediaTimingReviewRuntime.cancelPlaybackResume();
}
const command =
resolveSanitizedSubtitleSeekCommand(
rawCommand,