import { useContext, useEffect, useState } from 'react' import { ClockContext } from '../components/ClockContext.js' import type { DOMElement } from '../dom.js' import { useTerminalViewport } from './use-terminal-viewport.js' export function useAnimationFrame( intervalMs: number | null = 16, ): [ref: (element: DOMElement | null) => void, time: number] { const clock = useContext(ClockContext) const [viewportRef, { isVisible }] = useTerminalViewport() const [time, setTime] = useState(() => clock?.now() ?? 0) const active = isVisible && intervalMs !== null useEffect(() => { if (!clock || !active) return let lastUpdate = clock.now() const onChange = (): void => { const now = clock.now() if (now - lastUpdate >= intervalMs!) { lastUpdate = now setTime(now) } } // keepAlive: true — a visible animation owns the clock's awake state. return clock.subscribe(onChange, true) }, [clock, intervalMs, active]) return [viewportRef, time] }