import { useEffect, useMemo, useState } from 'react'; import { useSession } from '../context/SessionContext.jsx'; import ChatMessageRow from './ChatMessageRow.jsx'; import ChatTypingRow from './ChatTypingRow.jsx'; const LIFETIME_MS = 3000; const DEFAULT_COLOR = '#2196f3'; function buildKey(alert) { if (alert.id) return alert.id; if (alert.timestamp) return `${alert.timestamp}-${alert.message}`; return `${alert.title || 'alert'}-${alert.message}`; } export default function AlertFeed({ scale = 1 }) { const { alerts } = useSession(); const [now, setNow] = useState(() => Date.now()); const latest = useMemo(() => alerts.slice(-3).map((alert) => ({ alert, key: buildKey(alert) })), [alerts]); useEffect(() => { if (!latest.length) return undefined; const interval = setInterval(() => setNow(Date.now()), 200); return () => clearInterval(interval); }, [latest.length]); const visible = latest .map((item) => ({ ...item, age: now - (item.alert.receivedAt ?? item.alert.timestamp ?? 0), })) .filter((item) => item.age <= LIFETIME_MS); if (!visible.length) return null; const containerStyle = scale === 1 ? undefined : { transform: `translateX(-50%) scale(${scale})`, transformOrigin: 'top center', }; const containerClass = scale === 1 ? 'pointer-events-none fixed top-0.5 left-1/2 z-50 flex -translate-x-1/2 flex-col gap-0.5' : 'pointer-events-none fixed top-0.5 left-1/2 z-50 flex flex-col gap-0.5'; return (
{alert.title || 'Alert'} ยท {alert.message}