mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
Panel: de-dupe live notifications and expose recovery states on the board
Notification bell: the websocket stream was rendered with a plain filter, so a stream replay after a reconnect surfaced — and counted — the same notification twice, inflating the unread badge. De-duplicate by notification_id (newest copy wins, arrival order preserved) and key the list on the id instead of array index. PM kanban: the board had no columns for the recovery states (paused, needs-revision, awaiting-CEO-approval, cancelled), so a human had no way to drive a wedged task into them from the UI. Add those columns; dragging a card issues an admin status override, giving the CEO direct recovery from the board.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState, useCallback } from "react";
|
||||
import { useEffect, useRef, useState, useCallback, useMemo } from "react";
|
||||
import {
|
||||
WebSocketConnection,
|
||||
getWebSocketUrl
|
||||
@@ -185,8 +185,27 @@ export function useNotificationStream() {
|
||||
true
|
||||
);
|
||||
|
||||
// Filter to only notification events
|
||||
const notifications = messages.filter((m) => m.type === "notification");
|
||||
// Filter to notification events, de-duplicated by notification_id so a
|
||||
// stream replay (e.g. after a websocket reconnect) does not surface — or
|
||||
// count — the same notification twice. Walk newest→oldest keeping the most
|
||||
// recent copy of each id, then restore arrival order. Events without an id
|
||||
// (older payloads) are always kept.
|
||||
const notifications = useMemo(() => {
|
||||
const seen = new Set<string>();
|
||||
const deduped: NotificationMessage[] = [];
|
||||
for (let i = messages.length - 1; i >= 0; i--) {
|
||||
const m = messages[i];
|
||||
if (m.type !== "notification") continue;
|
||||
const id = m.notification_id;
|
||||
if (id) {
|
||||
if (seen.has(id)) continue;
|
||||
seen.add(id);
|
||||
}
|
||||
deduped.push(m);
|
||||
}
|
||||
deduped.reverse();
|
||||
return deduped;
|
||||
}, [messages]);
|
||||
|
||||
return {
|
||||
state,
|
||||
|
||||
Reference in New Issue
Block a user