MCPcopy Index your code
hub / github.com/codeaashu/claude-code / useStalledAnimation

Function useStalledAnimation

src/components/Spinner/useStalledAnimation.ts:6–75  ·  view source on GitHub ↗
(
  time: number,
  currentResponseLength: number,
  hasActiveTools = false,
  reducedMotion = false,
)

Source from the content-addressed store, hash-verified

4// Driven by the parent's animation clock time instead of independent intervals,
5// so it slows down when the terminal is blurred.
6export function useStalledAnimation(
7 time: number,
8 currentResponseLength: number,
9 hasActiveTools = false,
10 reducedMotion = false,
11): {
12 isStalled: boolean
13 stalledIntensity: number
14} {
15 const lastTokenTime = useRef(time)
16 const lastResponseLength = useRef(currentResponseLength)
17 const mountTime = useRef(time)
18 const stalledIntensityRef = useRef(0)
19 const lastSmoothTime = useRef(time)
20
21 // Reset timer when new tokens arrive (check actual length change)
22 if (currentResponseLength > lastResponseLength.current) {
23 lastTokenTime.current = time
24 lastResponseLength.current = currentResponseLength
25 stalledIntensityRef.current = 0
26 lastSmoothTime.current = time
27 }
28
29 // Derive time since last token from animation clock
30 let timeSinceLastToken: number
31 if (hasActiveTools) {
32 timeSinceLastToken = 0
33 lastTokenTime.current = time
34 } else if (currentResponseLength > 0) {
35 timeSinceLastToken = time - lastTokenTime.current
36 } else {
37 timeSinceLastToken = time - mountTime.current
38 }
39
40 // Calculate stalled intensity based on time since last token
41 // Start showing red after 3 seconds of no new tokens (only when no tools are active)
42 const isStalled = timeSinceLastToken > 3000 && !hasActiveTools
43 const intensity = isStalled
44 ? Math.min((timeSinceLastToken - 3000) / 2000, 1) // Fade over 2 seconds
45 : 0
46
47 // Smooth intensity transition driven by animation frame ticks
48 if (!reducedMotion && (intensity > 0 || stalledIntensityRef.current > 0)) {
49 const dt = time - lastSmoothTime.current
50 if (dt >= 50) {
51 const steps = Math.floor(dt / 50)
52 let current = stalledIntensityRef.current
53 for (let i = 0; i < steps; i++) {
54 const diff = intensity - current
55 if (Math.abs(diff) < 0.01) {
56 current = intensity
57 break
58 }
59 current += diff * 0.1
60 }
61 stalledIntensityRef.current = current
62 lastSmoothTime.current = time
63 }

Callers 1

SpinnerAnimationRowFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected