fix(ui): restore channel and detail keyboard scrolling (#1542)

* fix(ui): restore channel and detail keyboard scrolling

* test(ui): drag below the Windows scrollbar arrow
This commit is contained in:
4gray authored and GitHub committed 2026-09-05 15:02:57 +02:00
1 parent 0ba5107561
commit eb602db5fc
44 files changed
+950 -49

No files matched your search

+25 -3
View File
@@ -120,9 +120,31 @@ the wrapper file that includes it.
Every interactive descendant of a drag region—including buttons, links,
inputs, overlays, and resize handles—requires `app-region: no-drag`. The shared
directive-generated `.resize-handle` does not set this centrally yet. Until
that debt is fixed, consumers in drag regions must cover the handle themselves
and must not assume it already opts out.
directive-generated `.resize-handle` sets this centrally in `resizable.scss`.
The shared live-layout sidebar reserves 8 px at its right edge so the inward
half of the 12 px resize handle cannot cover the channel scrollbar.
## Keyboard Scrolling and Channel Focus
`ChannelScrollFocusDirective` belongs on the actual channel scroll owner,
including virtual viewports and nonvirtual Favorites/Recent/Stalker lists.
Pointer selection focuses that owner without moving its scroll position.
ArrowUp/Down, PageUp/Down, Home/End and Space retain native scrolling there;
scroll keys do not bubble into document-level player shortcuts. A row's main
button remains separate from favorite/info actions, supports native Enter and
Space activation, and retains keyboard focus on activation. Tab/Shift+Tab use
the normal DOM order. Scrolling from a virtual row moves focus to its viewport
before CDK can recycle the row; asynchronous data updates never move focus.
Xtream aligns a newly selected channel only when it is outside the viewport;
updates to the same selected ID never re-align it. A smooth scroll to an
already visible row would otherwise cancel an immediate keyboard scroll.
In portal Live TV, ArrowRight on the selected category enters the visible
`live-channels` region; ArrowLeft from that region or a channel's main button
returns to the selected category in `portal-categories`. These IDs identify the
single mounted main pane, not fullscreen or overlay lists. Navigation does not
select a channel or start playback. Modified shortcuts, input fields, menus,
dialogs, player controls and hidden/inert panes keep their own behavior.
## Channel List Item
@@ -6,6 +6,23 @@ Related:
- [Embedded Inline Playback](./embedded-inline-playback.md)
## Detail Scroll and Focus
`PortalDetailShellComponent` is the single scroll owner for portal, collection,
M3U movie and offline detail surfaces. It is a named, focusable region with a
native scrollbar and stable gutter. Scrollbars follow the platform's visibility
policy; CSS must not hide them. Content that fits the pane needs no thumb.
On its first render, a browse shell takes focus only if it is still on the
page body or the enclosing workspace `main`; it does not steal focus from a
button, input, dialog or inert surface. Replacing a loading shell can hand off
page focus to the loaded shell, but metadata updates and browse/watch changes
do not refocus it. Initial watch playback keeps its existing focus behavior.
ArrowUp/Down, PageUp/Down, Home/End and Space on the shell scroll natively and
do not reach global player shortcuts. Descendant controls retain their native
keys and Tab order. Entering watch still scrolls to the top; Back and saved
catalog scroll positions retain the existing navigation contract below.
## Summary
- Xtream category browsing uses a route-first detail model.