From 7f358f63e3d13bb118837b6d52c1d8dbf8ef4549 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Mon, 13 Jul 2026 05:13:18 +0200 Subject: [PATCH] feat(notifications): coalesce identical notifications with a repeat count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold a burst of identical notifications (same level+title+message within a short window) into one entry with a ×N count instead of stacking copies — tames a crash-retry loop or a repeatedly-failing poll. Shown in the toast and centre. --- .../src/components/NotificationsPanel.tsx | 9 +++- frontend/src/components/Toaster.tsx | 9 +++- frontend/src/lib/notifications.ts | 50 +++++++++++++++++-- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/NotificationsPanel.tsx b/frontend/src/components/NotificationsPanel.tsx index 07fcf0e..4c14a12 100644 --- a/frontend/src/components/NotificationsPanel.tsx +++ b/frontend/src/components/NotificationsPanel.tsx @@ -320,7 +320,14 @@ function ClientActivityRow({
{n.title &&
{n.title}
} -
{n.message}
+
+ {n.message} + {n.repeat > 1 && ( + + ×{n.repeat} + + )} +
{relativeFromMs(n.ts)} {needsAction && ( diff --git a/frontend/src/components/Toaster.tsx b/frontend/src/components/Toaster.tsx index 0b94953..4f4af84 100644 --- a/frontend/src/components/Toaster.tsx +++ b/frontend/src/components/Toaster.tsx @@ -42,7 +42,14 @@ export default function Toaster() {
{toast.title &&
{toast.title}
} -
{toast.message}
+
+ {toast.message} + {toast.repeat > 1 && ( + + ×{toast.repeat} + + )} +
{toast.action && (