feat(player): shift+. / shift+, keyboard shortcuts for playback rate

YouTube-parity hotkeys. Shift+. (">") steps playback up by 0.25 to a
max of 2x; Shift+, ("<") steps it down to a min of 0.25x. "." / ","
alone also work when the browser doesn't surface Shift for the
underlying character — e.g. non-US keyboard layouts.

Theater (T), PiP (I), Fullscreen (F), Play/pause (K / space), Mute
(M), Seek (J / L / arrows), % seek (0-9) were already wired — this
closes the remaining Phase 4 hotkey gap.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-10-21 12:08:05 +03:00
1 parent 22d6b1507d
commit 574c9581bb
1 file changed
+19
@@ -1343,6 +1343,25 @@ document.addEventListener('keydown', e => {
e.preventDefault(); seekRelative(-10); flashDbl(dblLeft); showControls(); break;
case 'l': case 'L':
e.preventDefault(); seekRelative(10); flashDbl(dblRight); showControls(); break;
case '>':
case '.':
// YouTube parity: shift+. (which produces ">") steps playback
// rate up in 0.25 jumps. "." alone also works for keyboards
// where ">" needs a modifier the browser doesn't surface.
if (e.shiftKey || e.key === '>') {
e.preventDefault();
video.playbackRate = Math.min(2, Math.round((video.playbackRate + 0.25) * 100) / 100);
showControls();
}
break;
case '<':
case ',':
if (e.shiftKey || e.key === '<') {
e.preventDefault();
video.playbackRate = Math.max(0.25, Math.round((video.playbackRate - 0.25) * 100) / 100);
showControls();
}
break;
case 'ArrowLeft':
e.preventDefault(); seekRelative(-5); showControls(); break;
case 'ArrowRight':