mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fix(playback): dismiss the side panel from the exposed edge gutter
The inset card leaves the hot zone's left strip visible beside it, above the scrim, so a click there re-ran show() instead of dismissing. A completed primary press in the zone now closes an open panel; hovering there still counts as inside, since a hover-opened panel leaves the pointer resting in that strip. The playing episode row also keeps its cyan tint on hover/focus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
07d3f48bc2
commit
5ff9de0acb
4 files changed
+27
-1
No files matched your search
@@ -732,7 +732,10 @@ neither opens nor arms the hint: the zone re-arms on the next real
|
||||
scrim and below the panel while open, preserving the pointer target until
|
||||
the opening animation covers it. A delayed fullscreen paint therefore cannot
|
||||
turn a stationary edge hover into a synthetic mouse-leave that closes the
|
||||
panel. The zone stops above the controls bar (`bottom: max(25%, 140px)`) so
|
||||
panel. The open card is inset from the edge, so the zone's left strip stays
|
||||
exposed beside it: hovering there still counts as inside (a hover-opened
|
||||
panel leaves the pointer resting in that strip), but a completed primary
|
||||
press there closes the panel as the scrim would. The zone stops above the controls bar (`bottom: max(25%, 140px)`) so
|
||||
the leftmost transport button never loses a click or tap to it. The `C` key
|
||||
opens it too and focuses the search field — or, for a host without one, the
|
||||
panel itself (`tabindex="-1"`), so the next Tab reaches its first control
|
||||
|
||||
+11
@@ -547,6 +547,17 @@ describe('FullscreenChannelPanelComponent', () => {
|
||||
expect(query('host-list')?.textContent?.trim()).toBe('');
|
||||
});
|
||||
|
||||
it('closes on a click in the edge gutter the inset card leaves exposed', () => {
|
||||
setFullscreen(stage);
|
||||
openByHover();
|
||||
hotZone()?.dispatchEvent(pointerEvent('pointerdown'));
|
||||
hotZone()?.dispatchEvent(pointerEvent('pointerup'));
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(isOpen()).toBe(false);
|
||||
expect(query('host-list')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('closes on the scrim but keeps the list mounted for the next opening', () => {
|
||||
setFullscreen(stage);
|
||||
openByHover();
|
||||
|
||||
+6
@@ -230,6 +230,8 @@ export class FullscreenChannelPanelComponent implements OnDestroy {
|
||||
* pointerup, not pointerdown: the hot zone must still be the click
|
||||
* target when the press completes, so the click that follows dies on it
|
||||
* instead of reaching the video's click-to-pause.
|
||||
* While the panel is open the zone is still exposed in the card's left
|
||||
* inset, above the scrim, so a click there dismisses like the scrim does.
|
||||
*/
|
||||
onHotZonePointerDown(event: PointerEvent): void {
|
||||
this.hotZonePressPointerId =
|
||||
@@ -242,6 +244,10 @@ export class FullscreenChannelPanelComponent implements OnDestroy {
|
||||
if (pressed === null || pressed !== event.pointerId) {
|
||||
return;
|
||||
}
|
||||
if (this.state.open()) {
|
||||
this.state.hide();
|
||||
return;
|
||||
}
|
||||
this.state.show('pointer');
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -167,6 +167,12 @@
|
||||
.episode-panel__item--playing {
|
||||
background: rgba(92, 214, 255, 0.14);
|
||||
cursor: default;
|
||||
|
||||
// Keep the cue while the row is hovered or focused.
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
background: rgba(92, 214, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
// Watched rows step back so the unwatched ones read as "what's left".
|
||||
|
||||
Reference in new issue
Block a user