Skip to content

feat(desktop): coalesce burst feed notifications into one toast - #6768

Open
mfethe1 wants to merge 1 commit into
block:mainfrom
mfethe1:upstream/HW-011
Open

feat(desktop): coalesce burst feed notifications into one toast#6768
mfethe1 wants to merge 1 commit into
block:mainfrom
mfethe1:upstream/HW-011

Conversation

@mfethe1

@mfethe1 mfethe1 commented Aug 25, 2026

Copy link
Copy Markdown

A burst of feed items produced one OS notification and one sound per item, so ten items meant ten toasts.

This buffers eligible feed items for a bounded 2s window and flushes once:

  • 2+ items collapse into a single count-only summary
  • a lone item keeps the existing single-item format, so the common case is unchanged

The summary is derived only from counts and the relay's existing needs_action partition — no item content, channel name, or pubkey reaches the toast.

Scope: the feed producer only. The WebSocket producer is deliberately untouched, so an item arriving via WS during an open window can still raise its own toast. That is a known, deliberate limitation of this slice rather than an oversight — keeping it narrow avoids colliding with #5806, which owns hooks.ts and app/useAppShellDesktopNotifications.ts.

3 files, +252/-1. New logic is a pure module (lib/coalesce.ts) with 6 unit tests.

Checks

  • pnpm typecheck — clean
  • pnpm check:px-text, check:pubkey-truncation — clean
  • notifications suite — 79/79
  • full desktop suite on this branch's base — green

pnpm check:file-sizes is red on main today for ChannelPane.tsx / ChannelScreen.tsx; this PR touches neither and adds no lines to either.

Not verified (stated explicitly)

  • No screenshots. The change affects macOS OS-level notification toasts, which need an interactive launch with notification permission to capture. I could not produce visual evidence, so the rendered toast is unverified by image.
  • No fake-timer test for the buffer/flush timer path. The feature has no React-hook test harness (every sibling test is a pure module test), so the timer path is covered by typecheck and by the pure-module tests around it, not by a test that advances time. That is the weakest point of the change and the place most worth reviewer attention.

Overlap

#5806 also touches use-feed-desktop-notifications.ts (open, last updated 2026-08-22). It does not add lib/coalesce.ts. No open PR implements notification coalescing/digest policy — the other notification PRs are delivery-layer (sound, toast delivery, permission, click routing). Happy to rebase if #5806 lands first.

@mfethe1
mfethe1 requested a review from a team as a code owner August 25, 2026 08:49
The feed notification hook delivered one OS notification and one sound per
eligible item, so a burst of ten items produced ten toasts. Buffer eligible
items for a bounded 2s window and flush once: two or more items collapse into
a single count-only summary, while a lone item keeps its existing single-item
format so the common case is unchanged.

The summary is derived from counts and the relay's existing needs_action
partition only - no item content, channel name, or pubkey reaches the toast.

Scoped to the feed producer; the WebSocket producer is deliberately untouched.

Signed-off-by: Michael Feth <michael@jira-flow.com>
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.

1 participant