diff --git a/frontend/src/components/PlayerModal.tsx b/frontend/src/components/PlayerModal.tsx index 4aa5bd09..b8c7d1dc 100644 --- a/frontend/src/components/PlayerModal.tsx +++ b/frontend/src/components/PlayerModal.tsx @@ -27,6 +27,7 @@ import { } from "lucide-react"; import Avatar from "./Avatar"; import AddToPlaylist from "./AddToPlaylist"; +import { PopoverSurface, useAnchoredPopover } from "./AnchoredPopover"; import { pushLayer, removeLayer, anyLayerAbove } from "../lib/layerStack"; import DownloadButton from "./DownloadButton"; import { api, type Video, type VideoStatus } from "../lib/api"; @@ -446,41 +447,21 @@ export default function PlayerModal({ } }; - // Lazy description (fetched only when the title is hovered). The popover is - // portaled to
with fixed positioning so the modal card's overflow-y-auto - // can't clip it. A small close grace lets the mouse travel title → popover. + // Lazy description (fetched only when the title is hovered). Anchored ABOVE the title so it grows + // upward over the player rather than downward off-screen / behind the OS taskbar — `flip` still + // rescues it when there is no room up there either, which the old fixed `bottom` could not. The + // hover-intent delay (only pop it if the pointer lingers, so a quick pass doesn't flash the card) + // and the travel grace are now the platform's, along with the safePolygon bridge that replaces the + // pair of hand-managed timers. const [showDesc, setShowDesc] = useState(false); - // `bottom` anchors the popover just above the title so it grows upward (over the - // player) instead of downward off-screen / behind the OS taskbar. - const [descRect, setDescRect] = useState<{ left: number; bottom: number; width: number } | null>( - null, - ); - const titleRef = useRef