/** * Browser View Panel * * Displays live screenshots from each agent's browser session. * Subscribes to screenshot streaming on mount, unsubscribes on unmount. */ import { useEffect, useState } from 'react' import { Monitor, X, Maximize2, Code, FlaskConical } from 'lucide-react' import { Badge } from '@/components/ui/badge' import { AGENT_MASCOTS } from '@/lib/types' import type { BrowserScreenshot } from '@/lib/types' interface BrowserViewPanelProps { screenshots: Map onSubscribe: () => void onUnsubscribe: () => void } export function BrowserViewPanel({ screenshots, onSubscribe, onUnsubscribe }: BrowserViewPanelProps) { const [expandedSession, setExpandedSession] = useState(null) // Subscribe on mount, unsubscribe on unmount useEffect(() => { onSubscribe() return () => onUnsubscribe() }, [onSubscribe, onUnsubscribe]) const screenshotList = Array.from(screenshots.values()) if (screenshotList.length === 0) { return (
No active browser sessions Screenshots will appear when agents open browsers
) } const expanded = expandedSession ? screenshots.get(expandedSession) : null return (
{/* Expanded overlay */} {expanded && (
setExpandedSession(null)} >
e.stopPropagation()} >
{expanded.agentType === 'coding' ? ( ) : ( )} {AGENT_MASCOTS[expanded.agentIndex % AGENT_MASCOTS.length]} {expanded.agentType} {expanded.featureName}
{`Browser
)} {/* Screenshot grid — responsive 1/2/3 columns */}
{screenshotList.map((screenshot) => (
{/* Card header */}
{screenshot.agentType === 'coding' ? ( ) : ( )} {AGENT_MASCOTS[screenshot.agentIndex % AGENT_MASCOTS.length]} {screenshot.agentType} {screenshot.featureName}
{/* Screenshot image — capped height for compact grid */}
setExpandedSession(screenshot.sessionName)} > {`Browser
{/* Timestamp footer */}
{new Date(screenshot.timestamp).toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit', })}
))}
) }