Nightly: SSE-Client-Handling verbessert (separater Hook, Snapshot/Party-Set + Ping); UI synchronisiert State pro Guild

This commit is contained in:
vibe-bot 2025-08-10 00:11:38 +02:00
parent 21b4e9bd0c
commit c1f4d0f3a0
2 changed files with 27 additions and 13 deletions

View file

@ -975,9 +975,13 @@ app.get('/api/events', (req: Request, res: Response) => {
// Snapshot senden
try { res.write(`data: ${JSON.stringify({ type: 'snapshot', party: Array.from(partyActive) })}\n\n`); } catch {}
// Ping, damit Proxies die Verbindung offen halten
const ping = setInterval(() => { try { res.write(':\n\n'); } catch {} }, 15_000);
sseClients.add(res);
req.on('close', () => {
sseClients.delete(res);
clearInterval(ping);
try { res.end(); } catch {}
});
});

View file

@ -45,6 +45,7 @@ export default function App() {
return `https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/svg/${codePoints}.svg`;
}
const [showBroccoli, setShowBroccoli] = useState<boolean>(false);
const [partyActiveGuilds, setPartyActiveGuilds] = useState<string[]>([]);
const selectedCount = useMemo(() => Object.values(selectedSet).filter(Boolean).length, [selectedSet]);
const [clock, setClock] = useState<string>(() => new Intl.DateTimeFormat('de-DE', { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'Europe/Berlin' }).format(new Date()));
const [totalPlays, setTotalPlays] = useState<number>(0);
@ -74,22 +75,31 @@ export default function App() {
const h = await fetch('/api/health').then(r => r.json()).catch(() => null);
if (h && typeof h.totalPlays === 'number') setTotalPlays(h.totalPlays);
} catch {}
// SSE: Partymode Status global synchronisieren
const unsub = subscribeEvents((msg)=>{
})();
}, []);
// SSE: Partymode-Status global synchronisieren (sauberes Cleanup)
useEffect(() => {
const unsub = subscribeEvents((msg) => {
if (msg?.type === 'party') {
const [gid] = (selected||'').split(':');
if (gid && msg.guildId === gid) {
setChaosMode(!!msg.active);
}
setPartyActiveGuilds((prev) => {
const s = new Set(prev);
if (msg.active) s.add(msg.guildId); else s.delete(msg.guildId);
return Array.from(s);
});
} else if (msg?.type === 'snapshot') {
const [gid] = (selected||'').split(':');
if (gid) setChaosMode(msg.party?.includes(gid));
setPartyActiveGuilds(Array.isArray(msg.party) ? msg.party : []);
}
});
return () => { try { unsub(); } catch {} };
})();
}, []);
// Aus aktivem Guild-Status die lokale Anzeige setzen
useEffect(() => {
const gid = selected ? selected.split(':')[0] : '';
setChaosMode(gid ? partyActiveGuilds.includes(gid) : false);
}, [selected, partyActiveGuilds]);
// Uhrzeit (Berlin) aktualisieren
useEffect(() => {
const fmt = new Intl.DateTimeFormat('de-DE', { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'Europe/Berlin' });