Mark notification as read when accepting via toast
Toast accept/reject now calls markRead on the corresponding notification so it clears from unread in the notifications tab. Uses markReadRef to avoid stale closure in Sonner toast callbacks. Covers both success and 409 (already resolved) paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1e736eb333
commit
053c2ae85e
@ -9,7 +9,7 @@ import { getErrorMessage } from '@/lib/api';
|
||||
import type { AppNotification } from '@/types';
|
||||
|
||||
export default function NotificationToaster() {
|
||||
const { notifications, unreadCount } = useNotifications();
|
||||
const { notifications, unreadCount, markRead } = useNotifications();
|
||||
const { respond } = useConnections();
|
||||
const queryClient = useQueryClient();
|
||||
const maxSeenIdRef = useRef(0);
|
||||
@ -20,9 +20,11 @@ export default function NotificationToaster() {
|
||||
// Always call the latest respond — Sonner toasts capture closures at creation time
|
||||
const respondRef = useRef(respond);
|
||||
respondRef.current = respond;
|
||||
const markReadRef = useRef(markRead);
|
||||
markReadRef.current = markRead;
|
||||
|
||||
const handleConnectionRespond = useCallback(
|
||||
async (requestId: number, action: 'accept' | 'reject', toastId: string | number) => {
|
||||
async (requestId: number, action: 'accept' | 'reject', toastId: string | number, notificationId: number) => {
|
||||
// Guard against double-clicks (Sonner toasts are static, no disabled prop)
|
||||
if (respondingRef.current.has(requestId)) return;
|
||||
respondingRef.current.add(requestId);
|
||||
@ -37,11 +39,13 @@ export default function NotificationToaster() {
|
||||
await respondRef.current({ requestId, action });
|
||||
toast.dismiss(loadingId);
|
||||
toast.success(action === 'accept' ? 'Connection accepted' : 'Request declined');
|
||||
markReadRef.current([notificationId]).catch(() => {});
|
||||
} catch (err) {
|
||||
toast.dismiss(loadingId);
|
||||
// 409 means the request was already resolved (e.g. accepted via notification center)
|
||||
if (axios.isAxiosError(err) && err.response?.status === 409) {
|
||||
toast.success(action === 'accept' ? 'Connection already accepted' : 'Request already resolved');
|
||||
markReadRef.current([notificationId]).catch(() => {});
|
||||
} else {
|
||||
toast.error(getErrorMessage(err, 'Failed to respond to request'));
|
||||
}
|
||||
@ -119,14 +123,14 @@ export default function NotificationToaster() {
|
||||
</p>
|
||||
<div className="flex items-center gap-2 mt-3">
|
||||
<button
|
||||
onClick={() => handleConnectionRespond(requestId, 'accept', id)}
|
||||
onClick={() => handleConnectionRespond(requestId, 'accept', id, notification.id)}
|
||||
className="flex items-center gap-1 px-3 py-1.5 text-xs font-medium rounded-md bg-accent text-accent-foreground hover:bg-accent/90 transition-colors"
|
||||
>
|
||||
<Check className="h-3.5 w-3.5" />
|
||||
Accept
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleConnectionRespond(requestId, 'reject', id)}
|
||||
onClick={() => handleConnectionRespond(requestId, 'reject', id, notification.id)}
|
||||
className="flex items-center gap-1 px-3 py-1.5 text-xs font-medium rounded-md text-muted-foreground hover:bg-card-elevated transition-colors"
|
||||
>
|
||||
<X className="h-3.5 w-3.5" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user