import { useEffect, useRef } from "react"; import { type SlowRpcAckRequest, useSlowRpcAckRequests } from "../rpc/requestLatencyState"; import { toastManager } from "./ui/toast"; function describeSlowRequests(requests: ReadonlyArray): string { const count = requests.length; // Thresholds vary per method, so report the smallest one the batch has passed. const thresholdSeconds = Math.round( Math.min(...requests.map((request) => request.thresholdMs)) / 1000, ); return `${count} request${count === 1 ? "" : "s"} waiting longer than ${thresholdSeconds}s.`; } function SlowRequestDetails({ requests }: { requests: ReadonlyArray }) { return ( ); } export function SlowRpcRequestToastCoordinator() { const slowRequests = useSlowRpcAckRequests(); const toastIdRef = useRef | null>(null); useEffect(() => { if (slowRequests.length === 0) { if (toastIdRef.current !== null) { toastManager.close(toastIdRef.current); toastIdRef.current = null; } return; } const nextToast = { data: { expandableContent: , expandableDescriptionTrigger: true, expandableLabels: { collapse: "Hide requests", expand: "Show requests" }, }, description: describeSlowRequests(slowRequests), timeout: 0, title: "Some requests are slow", type: "warning" as const, }; if (toastIdRef.current === null) { toastIdRef.current = toastManager.add(nextToast); } else { toastManager.update(toastIdRef.current, nextToast); } }, [slowRequests]); useEffect( () => () => { if (toastIdRef.current !== null) { toastManager.close(toastIdRef.current); } }, [], ); return null; }