feat(player): a roomier YouTube player, its panel shut on demand
- The full-height previous/next strips beside the card are gone: the panel's transport row and Shift+arrows step on their own, and the video gains the 7rem the strips' gutters took. - Close is one icon in the card's top-right corner (the wide panel's head, the stacked card's title row). - The panel's description is cut to three lines with More / Less (ClampedText now takes the linked text as children). - Wide, the panel shuts to a 2.75rem strip (close, open, previous, next) for a bigger video; it stays shut while the queue steps on, and a video opened from a card starts it open. Focus moves to the counterpart toggle. - The wheel has one meaning per place: over a panel (or the stacked card) with something to scroll it only scrolls, never falling through to the volume at the end; over the video, or a panel that fits, it is the volume. - A long channel name is cut on the panel's line instead of running the 20rem panel into a sideways scroll.
This commit is contained in:
@@ -77,7 +77,7 @@ function loadYouTubeApi(): Promise<YTNamespace> {
|
||||
* per video and always starts at 100, so the level lives in a ref and onReady re-applies it. Level 0 IS
|
||||
* the muted state (that's how YouTube's own control behaves), so there's no separate `muted` flag.
|
||||
* Mouse-wheel over the WHOLE modal (backdrop + card) adjusts volume, not just the small player area —
|
||||
* except over a `[data-wheel-scrolls]` panel that can still scroll that way. */
|
||||
* except over a `[data-wheel-scrolls]` panel that has anything to scroll, which keeps the wheel. */
|
||||
export function useYtVolume({
|
||||
playerRef,
|
||||
dialogRef,
|
||||
@@ -154,15 +154,17 @@ export function useYtVolume({
|
||||
const onWheelSpin = useEffectEvent((e: WheelEvent) => {
|
||||
// Ctrl/⌘+wheel is the browser's zoom gesture — never swallow it.
|
||||
if (e.ctrlKey || e.metaKey) return;
|
||||
// Over a panel that can still scroll that way, the wheel scrolls it: the wide player's side panel
|
||||
// holds the description, which a wheel spent on the volume could never be read past.
|
||||
const panel =
|
||||
e.target instanceof Element ? e.target.closest<HTMLElement>("[data-wheel-scrolls]") : null;
|
||||
// One gesture, one meaning (owner): over a panel with something to scroll the wheel only ever
|
||||
// scrolls it — at its end too, where it once fell through to the volume mid-spin. Over the video,
|
||||
// or a panel that fits, it is the volume. The nearer mark wins: the video inside a stacked card
|
||||
// that scrolls is still the volume.
|
||||
const zone =
|
||||
e.target instanceof Element
|
||||
? e.target.closest<HTMLElement>("[data-wheel-scrolls],[data-wheel-volume]")
|
||||
: null;
|
||||
if (
|
||||
panel &&
|
||||
(e.deltaY < 0
|
||||
? panel.scrollTop > 0
|
||||
: panel.scrollTop + panel.clientHeight < panel.scrollHeight - 1) // -1: sub-pixel heights
|
||||
zone?.hasAttribute("data-wheel-scrolls") &&
|
||||
zone.scrollHeight > zone.clientHeight + 1 // +1: sub-pixel heights
|
||||
)
|
||||
return;
|
||||
e.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user