Fix toast accept button: instant feedback + double-click guard
Toast buttons are static Sonner elements that can't bind React state, so clicks had no visual feedback and allowed duplicate mutations. Now: dismiss custom toast immediately, show loading toast, and block concurrent clicks via a ref-based Set guard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
60281caa64
commit
dff36f30c8
@ -14,16 +14,30 @@ export default function NotificationToaster() {
|
||||
const maxSeenIdRef = useRef(0);
|
||||
const initializedRef = useRef(false);
|
||||
const prevUnreadRef = useRef(0);
|
||||
// Track in-flight request IDs so repeated clicks are blocked
|
||||
const respondingRef = useRef<Set<number>>(new Set());
|
||||
|
||||
const handleConnectionRespond = useCallback(
|
||||
async (requestId: number, action: 'accept' | 'reject', toastId: string | number) => {
|
||||
// Guard against double-clicks (Sonner toasts are static, no disabled prop)
|
||||
if (respondingRef.current.has(requestId)) return;
|
||||
respondingRef.current.add(requestId);
|
||||
|
||||
// Immediately dismiss the custom toast and show a loading indicator
|
||||
toast.dismiss(toastId);
|
||||
const loadingId = toast.loading(
|
||||
action === 'accept' ? 'Accepting connection…' : 'Declining request…',
|
||||
);
|
||||
|
||||
try {
|
||||
await respond({ requestId, action });
|
||||
// onSuccess in useConnections already dismisses the custom toast and invalidates caches
|
||||
toast.dismiss(loadingId);
|
||||
toast.success(action === 'accept' ? 'Connection accepted' : 'Request declined');
|
||||
} catch (err) {
|
||||
toast.dismiss(toastId);
|
||||
toast.dismiss(loadingId);
|
||||
toast.error(getErrorMessage(err, 'Failed to respond to request'));
|
||||
} finally {
|
||||
respondingRef.current.delete(requestId);
|
||||
}
|
||||
},
|
||||
[respond],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user