Picker: arrow keys behave the same regardless of focus

Two complementary fixes:

1. Register the keydown handler on the capture phase. This ensures we
   run before the native HTML <video> element's built-in keyboard
   handler, so our preventDefault actually blocks the default seek.
   Without this, when focus was on the video, both handlers ran and
   the actual jump was the sum of both (±5 s ours + native = >1 min
   in some browsers).

2. Blur the video element on mouseup. After clicking the seekbar the
   video keeps keyboard focus, which made the symptom appear right
   after every scrub. Releasing focus on mouseup avoids that
   altogether.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Giorgio Gilestro 2026-05-01 14:46:41 +01:00
parent 5d50c8baaf
commit 16035bce36

View file

@ -461,7 +461,10 @@
loadCursor();
});
// Keyboard shortcuts
// Keyboard shortcuts.
// Reason: register on the *capture* phase so we run before the native
// <video> element's built-in handlers, which otherwise also seek by
// their own amount and double the actual jump.
document.addEventListener('keydown', (e) => {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
// Don't react to picker shortcuts while either modal is open.
@ -488,7 +491,13 @@
case 's': stop(); submit('skip'); break;
case 'u': stop(); submit('unusable'); break;
}
});
}, true); // capture phase — beats the native <video> keyboard handler
// After clicking the seekbar (or anywhere on the video), the player
// keeps keyboard focus and intercepts our arrow-key shortcuts. Blur it
// on mouseup so subsequent arrow presses go to our document-level
// handler unambiguously.
player.addEventListener('mouseup', () => player.blur());
// Welcome modal — show first time, dismissable; ? button reopens it.
const modalBackdrop = document.getElementById('modal-backdrop');