import { useState, useEffect, useRef } from "react"; import { api } from "../api"; interface Props { /** Whether to actively poll for logs */ active: boolean; } export default function LogViewer({ active }: Props) { const [lines, setLines] = useState([]); const containerRef = useRef(null); const cursorRef = useRef(0); useEffect(() => { if (!active) return; setLines([]); cursorRef.current = 0; const interval = setInterval(async () => { try { const res = await api.pollLogs(cursorRef.current); if (res.lines.length > 0) { setLines((prev) => { const next = [...prev, ...res.lines]; return next.length > 200 ? next.slice(-200) : next; }); } cursorRef.current = res.cursor; } catch { // ignore polling errors } }, 800); return () => clearInterval(interval); }, [active]); useEffect(() => { if (containerRef.current) { containerRef.current.scrollTop = containerRef.current.scrollHeight; } }, [lines]); if (!active && lines.length === 0) return null; return (
{lines.length === 0 && active && ( Waiting for logs... )} {lines.map((line, i) => (
{line}
))}
); }