import { useState, useMemo, useEffect, useRef, useCallback } from 'react'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; interface PerformanceStats { totalMessages: number; renderedMessages: number; virtualizationEnabled: boolean; } interface RoomPerformanceMonitorProps { messageCount: number; renderedCount?: number; } const AUTO_CLOSE_DELAY = 5000; // auto-close after 5 seconds when stats are shown export function RoomPerformanceMonitor({ messageCount, renderedCount }: RoomPerformanceMonitorProps) { const [showStats, setShowStats] = useState(false); const autoCloseTimerRef = useRef | null>(null); // Auto-close after AUTO_CLOSE_DELAY when stats are visible useEffect(() => { if (!showStats) return; autoCloseTimerRef.current = setTimeout(() => { setShowStats(false); }, AUTO_CLOSE_DELAY); return () => { if (autoCloseTimerRef.current) clearTimeout(autoCloseTimerRef.current); }; }, [showStats]); const stats = useMemo(() => ({ totalMessages: messageCount, renderedMessages: renderedCount ?? messageCount, virtualizationEnabled: renderedCount !== undefined && renderedCount < messageCount, }), [messageCount, renderedCount]); // --- Drag state --- const panelRef = useRef(null); const draggingRef = useRef(false); const dragStartRef = useRef({ x: 0, y: 0 }); const handleDragStart = useCallback((e: React.MouseEvent) => { // Don't start drag if clicking the close button if ((e.target as HTMLElement).closest('button')) return; draggingRef.current = true; dragStartRef.current = { x: e.clientX, y: e.clientY }; e.preventDefault(); }, []); useEffect(() => { const onMouseMove = (e: MouseEvent) => { if (!draggingRef.current) return; const panel = panelRef.current; if (!panel) return; const dx = e.clientX - dragStartRef.current.x; const dy = e.clientY - dragStartRef.current.y; const rect = panel.getBoundingClientRect(); panel.style.left = `${rect.left + dx}px`; panel.style.top = `${rect.top + dy}px`; panel.style.right = 'auto'; panel.style.bottom = 'auto'; dragStartRef.current = { x: e.clientX, y: e.clientY }; }; const onMouseUp = () => { draggingRef.current = false; }; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); return () => { document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); }; }, []); if (!showStats && import.meta.env.PROD) { return ( ); } return (
{/* Draggable header */}

Performance Stats

Total messages: {stats.totalMessages}
Rendered: {stats.renderedMessages}
{stats.virtualizationEnabled && (
Skipped: {stats.totalMessages - stats.renderedMessages}
)}
Virtualization: {stats.virtualizationEnabled ? '✓ Enabled' : '✗ Disabled'}
{stats.virtualizationEnabled && (
âš¡ Rendering {((stats.renderedMessages / stats.totalMessages) * 100).toFixed(0)}% of messages
)}
); }