import React, { useEffect, useState, useRef } from 'react'; interface DeathAlert { character_name: string; vitae: number; timestamp: string; } interface Props { deathAlerts: DeathAlert[]; } interface ActiveNotification { key: number; alert: DeathAlert; exiting: boolean; } let deathKey = 0; export const DeathNotification: React.FC = ({ deathAlerts }) => { const [active, setActive] = useState([]); const lastCount = useRef(0); useEffect(() => { if (deathAlerts.length > lastCount.current && lastCount.current > 0) { const newAlerts = deathAlerts.slice(lastCount.current); for (const alert of newAlerts) { const key = ++deathKey; setActive(prev => [...prev, { key, alert, exiting: false }]); // Sound try { const ctx = new AudioContext(); const osc = ctx.createOscillator(); const gain = ctx.createGain(); osc.connect(gain); gain.connect(ctx.destination); osc.frequency.value = 440; osc.type = 'sawtooth'; gain.gain.value = 0.2; osc.start(); gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.8); osc.stop(ctx.currentTime + 0.8); } catch {} // Auto-dismiss after 8s setTimeout(() => { setActive(prev => prev.map(n => n.key === key ? { ...n, exiting: true } : n)); setTimeout(() => setActive(prev => prev.filter(n => n.key !== key)), 500); }, 8000); } } lastCount.current = deathAlerts.length; }, [deathAlerts.length]); // eslint-disable-line react-hooks/exhaustive-deps if (active.length === 0) return null; return (
{active.map(n => (
☠️ CHARACTER DIED ☠️
{n.alert.character_name}
Vitae: {n.alert.vitae}%
))}
); };