import { useEffect, useRef, useState } from "react"; import { useEventContext } from "../../../state/events"; import { handleEventToast, mapEventToCategory, mapEventToSeverity, } from "../../toast-rules"; import { getUserConfig } from "../../../api/settings"; import type { UserConfig } from "../../../api/settings"; interface ToastConfig { notification_toast_level: string; notification_mute_categories: string[]; } export function EventToastBridge(): JSX.Element | null { const { events } = useEventContext(); const processedRef = useRef>(new Set()); const [config, setConfig] = useState(null); useEffect(() => { getUserConfig() .then((c) => { setConfig({ notification_toast_level: c.notification_toast_level ?? "all", notification_mute_categories: c.notification_mute_categories ?? [], }); }) .catch(() => { setConfig({ notification_toast_level: "all", notification_mute_categories: [], }); }); const handler = (e: Event) => { const detail = (e as CustomEvent>).detail; if (detail) { setConfig((prev) => ({ notification_toast_level: detail.notification_toast_level ?? prev?.notification_toast_level ?? "all", notification_mute_categories: detail.notification_mute_categories ?? prev?.notification_mute_categories ?? [], })); } }; window.addEventListener("userconfig:updated", handler); return () => window.removeEventListener("userconfig:updated", handler); }, []); useEffect(() => { if (!config) return; for (const event of events) { const key = `${event.correlation_id}:${event.timestamp}`; if (processedRef.current.has(key)) continue; processedRef.current.add(key); const category = mapEventToCategory(event); const severity = mapEventToSeverity(event); if (config.notification_toast_level === "none") continue; if (config.notification_toast_level === "errors" && severity !== "error") continue; if (config.notification_mute_categories.includes(category)) continue; handleEventToast(event); } }, [events, config]); return null; }