mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-11 19:29:33 +00:00
fix(player): Space bar play/pause when focus is on sidebar or rail buttons (#593)
* fix(player): Space bar play/pause when focus is on sidebar or rail buttons When any <button> in the player rail (viz, audio, mixer, etc.), a sidebar nav link, or a popover control has keyboard focus, pressing Space was blocked by _shortcutDispatchBlocked → _isInsideInteractiveControl, which returns true for BUTTON elements. The Space shortcut never reached the shortcut dispatcher and togglePlay() was never called. The fix extends the same carve-out pattern already used for the section practice bar: when the player screen is active, Space is always dispatched through the shortcut system. The shortcut handler's preventDefault() stops the focused element from also activating, so this is not a double-trigger. * test(player): cover Space play/pause carve-out + add CHANGELOG entry Adds two Playwright regression tests for #593 in tests/browser/keyboard-shortcuts.spec.ts: - Space toggles play/pause when a player rail <button> has focus, and the focused button does NOT also activate (dispatcher preventDefault). Fails on base (Space blocked, played=0), passes with the carve-out. - Space in a player-screen text input still types a space and never reaches play/pause (locks the _isTextInput exemption ordering). Also records the fix under CHANGELOG [Unreleased] -> Fixed, per the project workflow that every PR updates the changelog. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(player): don't override Space inside modal dialogs over the player The player-screen Space carve-out keyed off the active *screen*, so it also hijacked Space inside a true modal dialog layered over the player (e.g. the keyboard-shortcuts help modal, edit modal): Space toggled playback behind the modal and preventDefault blocked the modal's focused control (Close) from activating — contradicting aria-modal semantics. Narrow the carve-out to skip focus inside a modal (role="dialog" aria-modal="true" or .feedBack-modal). Non-modal player popovers/toasts (loop A/B, arrangement pin, role=dialog aria-modal=false) are not dialogs and stay covered, so the original fix is unchanged for the cases it targeted. Adds a Playwright regression test (Space inside a modal reaches the modal's button, not play/pause) and updates the CHANGELOG entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: byrongamatos <xasiklas@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
byrongamatos
parent
d2569cc2a8
commit
64801d5735
@@ -445,6 +445,21 @@ function _shortcutDispatchBlocked(e) {
|
||||
// the popover's own keydown listener) — suppress the player-scope
|
||||
// "back to library" Esc so the user doesn't get bounced out of the player.
|
||||
if (e.key === 'Escape' && _sectionPracticePopoverOpen()) return true;
|
||||
// Space on the player screen should always play/pause, even if focus is on a
|
||||
// sidebar nav link, player rail button, popover control, or any other
|
||||
// interactive element — the shortcut dispatcher calls preventDefault so the
|
||||
// focused element won't also activate. Two exceptions keep native Space:
|
||||
// text inputs (already exempted above), and focus inside a true modal
|
||||
// dialog (role="dialog" aria-modal="true", or a .feedBack-modal overlay)
|
||||
// layered over the player — a modal traps interaction, so Space must reach
|
||||
// its focused control (e.g. the Close button) rather than toggle playback
|
||||
// behind it. Non-modal player popovers/toasts (loop A/B, arrangement pin,
|
||||
// role="dialog" aria-modal="false") are not modals and stay covered.
|
||||
if (_isSpaceKey(e) && _getCurrentContext().isPlayer &&
|
||||
!(e.target && e.target.closest &&
|
||||
e.target.closest('[role="dialog"][aria-modal="true"], .feedBack-modal'))) {
|
||||
return false;
|
||||
}
|
||||
return _isInsideInteractiveControl(e.target);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user