import { useEffect, useRef } from "react"; import { useNavigate } from "react-router-dom"; import { useToast } from "../context/ToastContext"; import { useNotifications } from "../hooks/notifications"; /** Всплывашки сверху экрана в момент прихода новых уведомлений (push-to-invalidate → pull). * Первый снимок списка не всплывает (чтобы не спамить при загрузке) — только новые id. * Показывает их общая стопка ToastProvider — там же, где сообщения приложения. */ export function NotificationToaster({ enabled }: { enabled: boolean }) { const { data } = useNotifications(enabled); const navigate = useNavigate(); const toast = useToast(); const seen = useRef | null>(null); useEffect(() => { if (!data) return; const items = data.items; if (seen.current === null) { seen.current = new Set(items.map((n) => n.id)); // первая загрузка — запомнить, не всплывать return; } const fresh = items.filter((n) => !seen.current!.has(n.id)); fresh.forEach((n) => seen.current!.add(n.id)); // Стопка добавляет новое наверх, поэтому идём с конца: первое в списке окажется сверху. [...fresh].reverse().forEach((n) => toast.notify({ title: n.title, body: n.body, onClick: n.link ? () => navigate(n.link!) : undefined, }), ); }, [data, toast, navigate]); return null; }