Skip to content

feat(ui): announce a download in a flyout (LAZ-999) - #24131

Merged
r1chm8 merged 2 commits into
masterfrom
laz-999
Sep 10, 2026
Merged

r1chm8 merged 2 commits into
masterfrom
laz-999

Conversation

@r1chm8

@r1chm8 r1chm8 commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Adds the download flyout from LAZ-999: a panel that pops out beside the spine's download button when a download starts, and comes back on hover.

image

Why

Nothing in the UI confirmed that a download had actually started. The issue asks the flyout to do three things: confirm the download began, teach people where progress lives, and let them check it without losing their place.

How it works

The download button's click has to keep navigating to the Downloads page, so it can't become a Headless UI PopoverButton the way the notification bell is. Instead the flyout is a rich Tooltip, which gains two optional additions:

  • open / onOpenChange(open, reason) — a controlled open state, so the flyout can show itself with nothing on the trigger. Omit both and hover owns it exactly as before.
  • persistent — for a tooltip that shows itself rather than answering a hover: a press anywhere, or a neighbour in the same delay group opening, leaves it up. Escape still closes it. It's dropped the moment the pointer takes over, so from then on it behaves like any other tooltip.

Three hooks sit behind it in Spine/download_button/:

  • useDownloadProgress — lifted out of DownloadButton so the button and the flyout share one aggregate. Rebuilt as two narrow subscriptions plus a useMemo: it previously returned a fresh object from inside useSelector, re-rendering on every dispatch while the download adapter pushes batched progress about once a second per download.
  • useDownloadEta — samples one download's own received. Neither store field can give a per-file rate: downloads.speed is the aggregate across every download, and startTime is dead — nothing has written it since the init → started flip moved into the progress reducer, which is why SpeedOMeter already sorts on NaN there.
  • useDownloadFlyout — announces, dismisses itself after 5s, hands over to the pointer. Seeded at mount, so a session resuming with downloads already in flight doesn't announce them as news.

The arrow moved into a shared OverlayArrow + .nxm-overlay-arrow rule, and the notification tray now uses it. The tray's beak was a rotated square — a 90° tip, so necessarily 2:1, which could never match the tooltip's 12×8 SVG. The tray's anchor gap also went 8 → 16 (8 + arrow height, matching the tooltip's own offset), and that is what actually made the two panels' edges line up.

Two bugs found on the way

  • A disabled Tooltip wasn't inert. disabled only short-circuited the render; useHover, useFocus, useDismiss and useDelayGroup all still ran. The invisible tooltip claimed the delay group's currentId, the group closes whichever member isn't current, and that close cleared the real tooltip's pending open timeout — so the download button needed two hovers to show anything, its plain label included. disabled now reaches the interactions. ToolbarPanelButton uses the same tooltipDisabled trick, so this was latent there too.
  • useDownloadEta couldn't measure a fast cadence. It replaced its stored sample on every update before checking the interval, so a run of updates closer together than the threshold never added up to a measurable gap. It only worked at all because the real adapter throttles to ~1/s.

What changes visibly

  • A 320px flyout beside the download button: mod thumbnail, the file being downloaded, +N more for the rest of the queue, and time remaining. It shows a single "Download starting…" line until a name and a rate exist.
  • The notification tray sits 8px further from the bell and wears the tooltip's beak instead of its own.

@r1chm8
r1chm8 requested a review from a team as a code owner September 8, 2026 12:26
@r1chm8 r1chm8 self-assigned this Sep 8, 2026
erri120
erri120 previously approved these changes Sep 9, 2026
@r1chm8
r1chm8 marked this pull request as draft September 9, 2026 09:29
@r1chm8
r1chm8 marked this pull request as ready for review September 9, 2026 12:36
@r1chm8
r1chm8 marked this pull request as draft September 9, 2026 13:20
Nothing confirmed that a download had started; the flyout names the file
and its time left, then gets out of the way until hovered. Tooltip gains a
controlled open state and shares its arrow, so the tray's beak matches.
A pause now reports the percent still to fetch, and the clock keeps the leading
zero the downloads page has. The speed sits above the progress ring with a halo
behind it so it stays legible where the two cross, and hovering the button holds
the flyout open rather than letting its countdown close it. The notification
error icon joins the outlined set the other severities use.
@r1chm8
r1chm8 marked this pull request as ready for review September 9, 2026 13:50
@r1chm8
r1chm8 merged commit ef3f197 into master Sep 10, 2026
10 checks passed
@r1chm8
r1chm8 deleted the laz-999 branch September 10, 2026 07:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants