Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
1.2 kB · 31 lines
TypeScript
at main
1234567891011121314151617181920212223242526272829303132import { useMemo } from 'react'import { stringWidth } from '../../ink/stringWidth.js'import { type DOMElement, useAnimationFrame } from '../../ink.js'import type { SpinnerMode } from './types.js'
export function useShimmerAnimation( mode: SpinnerMode, message: string, isStalled: boolean,): [ref: (element: DOMElement | null) => void, glimmerIndex: number] { const glimmerSpeed = mode === 'requesting' ? 50 : 200 // Pass null when stalled to unsubscribe from the clock — otherwise the // setInterval keeps firing at 20fps even when the shimmer isn't visible. // Notably, if the caller never attaches `ref` (e.g. conditional JSX), // useTerminalViewport stays at its initial isVisible:true and the // viewport-pause never kicks in, so this is the only stop mechanism. const [ref, time] = useAnimationFrame(isStalled ? null : glimmerSpeed) const messageWidth = useMemo(() => stringWidth(message), [message])
if (isStalled) { return [ref, -100] }
const cyclePosition = Math.floor(time / glimmerSpeed) const cycleLength = messageWidth + 20
if (mode === 'requesting') { return [ref, (cyclePosition % cycleLength) - 10] } return [ref, messageWidth + 10 - (cyclePosition % cycleLength)]}