'use client'; import { useEffect, useState } from 'react'; import type { ChatMessage } from '@shared/chat'; import { Badges } from '../../components/Badges'; import { MessageBody } from '../../components/MessageBody'; import { formatAmount } from '../../lib/format'; import { proxyImageUrl } from '../../lib/imageProxy'; import { DEFAULT_OPTIONS, parseOverlayOptions, type OverlayOptions } from '../../lib/overlayOptions'; import { useEvents } from '../../lib/useEvents'; const SWAP_MS = 220; function membershipLabel(message: ChatMessage): string { if (message.membershipGiftPurchase && message.giftCount) { return `Gifted ${message.giftCount} membership${message.giftCount > 1 ? 's' : ''}`; } return message.membershipLevel || 'New member'; } export default function OverlayPage() { const { selection } = useEvents(); const [options, setOptions] = useState(DEFAULT_OPTIONS); const [shown, setShown] = useState(null); const [leaving, setLeaving] = useState(false); const [expired, setExpired] = useState(false); useEffect(() => { setOptions(parseOverlayOptions(window.location.search)); document.body.classList.add('is-overlay'); return () => document.body.classList.remove('is-overlay'); }, []); // Swap with a short exit animation so a new pick never pops in over the old one. useEffect(() => { if ((selection?.id ?? null) === (shown?.id ?? null)) return; if (!shown || options.anim === 'none') { setShown(selection); setExpired(false); return; } setLeaving(true); const timer = setTimeout(() => { setShown(selection); setExpired(false); setLeaving(false); }, SWAP_MS); return () => clearTimeout(timer); }, [selection, shown, options.anim]); useEffect(() => { if (!options.hide || !shown) return; const timer = setTimeout(() => setExpired(true), options.hide * 1000); return () => clearTimeout(timer); }, [shown, options.hide]); const message = expired ? null : shown; const kind = message?.superChat ? 'super' : message?.membershipGift || message?.membershipGiftPurchase ? 'member' : 'chat'; return (
{message && (
{message.authorPhoto && } {message.author} {message.superChat && {formatAmount(message.superChat.amount, message.superChat.currency)}} {kind === 'member' && {membershipLabel(message)}}
{message.superChat?.stickerUrl && ( {message.superChat.stickerAlt { event.currentTarget.hidden = true; }} /> )}
)}
); }