import { useEffect, useState } from 'react'; import { cn } from '../../../../lib/utils'; type ClaudeStatusProps = { status: { text?: string; tokens?: number; can_interrupt?: boolean; } | null; onAbort?: () => void; isLoading: boolean; provider?: string; }; const ACTION_WORDS = ['Thinking', 'Processing', 'Analyzing', 'Working', 'Computing', 'Reasoning']; const SPINNER_CHARS = ['*', '+', 'x', '.']; export default function ClaudeStatus({ status, onAbort, isLoading, provider: _provider = 'claude', }: ClaudeStatusProps) { const [elapsedTime, setElapsedTime] = useState(0); const [animationPhase, setAnimationPhase] = useState(0); const [fakeTokens, setFakeTokens] = useState(0); useEffect(() => { if (!isLoading) { setElapsedTime(0); setFakeTokens(0); return; } const startTime = Date.now(); const tokenRate = 30 + Math.random() * 20; const timer = window.setInterval(() => { const elapsed = Math.floor((Date.now() - startTime) / 1000); setElapsedTime(elapsed); setFakeTokens(Math.floor(elapsed * tokenRate)); }, 1000); return () => window.clearInterval(timer); }, [isLoading]); useEffect(() => { if (!isLoading) { return; } const timer = window.setInterval(() => { setAnimationPhase((previous) => (previous + 1) % SPINNER_CHARS.length); }, 500); return () => window.clearInterval(timer); }, [isLoading]); if (!isLoading) { return null; } const actionIndex = Math.floor(elapsedTime / 3) % ACTION_WORDS.length; const statusText = status?.text || ACTION_WORDS[actionIndex]; const tokens = status?.tokens || fakeTokens; const canInterrupt = status?.can_interrupt !== false; const currentSpinner = SPINNER_CHARS[animationPhase]; return (
{currentSpinner}
{statusText}... ({elapsedTime}s) {tokens > 0 && ( <> | tokens {tokens.toLocaleString()} )} | esc to stop
{canInterrupt && onAbort && ( )}
); }