feat(ux): card unification, slim icon nav, filter/plex fixes (7-item batch)
1A ChannelPage "Full history" button no longer wraps (whitespace-nowrap). 1B Extract the manager's press-and-hold priority stepper into a shared PriorityStepper and add it to the channel detail header (subscribed, non-demo); backend channel_detail now returns the per-subscription `priority`. 2 Unify YouTube + Plex media cards onto one look/behaviour: drop the whole-card hover LIFT (VideoCard) — which also fixes the clipped-top bug — and instead the inner thumbnail/poster ZOOMS on hover (both); give the flat Plex posters the same glass-card 3D depth + accent hover border as the feed cards (shadow-md is a transparent no-op here, so it's glass-card that provides the depth); clamp Plex card titles to a fixed 2-line height so 1- vs 2-line titles align. 3 Nav rail is now always a slim icon-only column, flush to the left edge; each icon reveals a floating name label on hover (Tooltip gains `always` + `openDelay`, and a right side). Removed the pin/unpin toggle, the expand-on-hover mode and the navCollapsed pref plumbing. 4 Scope the side-panel peek-open HOVER to the tab handle + the card (not the whole full-height slot next to the rail), so approaching the nav no longer pops the filter open; focus stays container-wide. useHoverFocusWithin gains a hover-out grace period + split hover/focus handler groups. 5 Plex art backdrop fills the whole viewport (a fixed inset-0 layer behind the transparent app) instead of only the inset <main> box. 6 Plex season binge continues across seasons: the season view's play queue now spans the whole show (allKeys), so a season's last episode rolls into the next season's first (seasonKeys stays for "add season to playlist"). 7 When a Plex video/episode ends with nothing queued next, the player returns to the previous page (onEnded → onClose) instead of stranding a black screen.
This commit is contained in:
@@ -2,22 +2,29 @@ import { useState, useSyncExternalStore } from "react";
|
||||
import { PopoverSurface, useAnchoredPopover } from "./AnchoredPopover";
|
||||
import { hintsEnabled, subscribeHints } from "../lib/hints";
|
||||
|
||||
type Side = "top" | "bottom";
|
||||
type Side = "top" | "bottom" | "left" | "right";
|
||||
|
||||
/** Wrap any element to show a short glass hint caption on hover — but only while the
|
||||
/** Wrap any element to show a short glass hint caption on hover — by default only while the
|
||||
* app-wide hints toggle (Settings → Appearance) is on. Anchored by the R8 popover platform, so it
|
||||
* is never clipped by an overflow/stacking ancestor, flips when the preferred side runs out of room
|
||||
* and slides back inside the viewport near an edge. */
|
||||
* and slides back inside the viewport near an edge.
|
||||
* `always` bypasses the hints toggle (for a label that IS the primary affordance, e.g. the slim nav
|
||||
* rail's flyout names); `openDelay` waits before showing (a rest-on-the-icon feel). */
|
||||
export default function Tooltip({
|
||||
hint,
|
||||
side = "top",
|
||||
always = false,
|
||||
openDelay = 0,
|
||||
children,
|
||||
}: {
|
||||
hint: string;
|
||||
side?: Side;
|
||||
always?: boolean;
|
||||
openDelay?: number;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const enabled = useSyncExternalStore(subscribeHints, hintsEnabled, hintsEnabled);
|
||||
const hintsOn = useSyncExternalStore(subscribeHints, hintsEnabled, hintsEnabled);
|
||||
const enabled = always || hintsOn;
|
||||
const [open, setOpen] = useState(false);
|
||||
const pop = useAnchoredPopover({
|
||||
open: open && enabled && !!hint,
|
||||
@@ -25,9 +32,9 @@ export default function Tooltip({
|
||||
mode: "hover",
|
||||
placement: side,
|
||||
offset: 8,
|
||||
// Show/hide on contact, as the pre-platform tooltip did — the platform's 120/140 ms hover-intent
|
||||
// default suits interactive cards but makes a fast sweep across an icon row surface no hints.
|
||||
hoverDelay: { open: 0, close: 0 },
|
||||
// Show/hide on contact by default (as the pre-platform tooltip did); `openDelay` adds a
|
||||
// rest-before-show for labels that shouldn't flash on a fast sweep across an icon row.
|
||||
hoverDelay: { open: openDelay, close: 0 },
|
||||
});
|
||||
|
||||
if (!enabled || !hint) return <>{children}</>;
|
||||
|
||||
Reference in New Issue
Block a user