hmgill's picture
Update public/elements/TurnTimer.jsx
dccc14a verified
Raw
History Blame Contribute Delete
1.78 kB
// Live elapsed-time counter, mounted while the agent works.
//
// THE RESET BUG: this element re-mounts on every `answer.update()` — and a turn
// updates the message many times (status line, Meshy progress, streamed tokens).
// A React `useState(0)` starts over on each remount, so the timer kept snapping
// back to 00:00 and never showed the real elapsed time.
//
// Fix: keep the START TIME on `window`, keyed by turn id, and derive elapsed from
// it. Remounts then resume from the true start instead of restarting the clock.
// The component becomes stateless with respect to time; only the tick is state.
import { useEffect, useState } from "react";
export default function TurnTimer() {
const id = props.id;
const [, tick] = useState(0);
useEffect(() => {
window.__fossilTimer = window.__fossilTimer || {};
if (!window.__fossilTimer[id]) window.__fossilTimer[id] = Date.now();
const t = setInterval(() => {
if (window.__fossilTimerStopped?.[id]) { clearInterval(t); return; }
tick((v) => v + 1);
}, 1000);
return () => clearInterval(t);
}, [id]);
const start = window.__fossilTimer?.[id] || Date.now();
const s = Math.floor((Date.now() - start) / 1000);
const mm = String(Math.floor(s / 60)).padStart(2, "0");
const ss = String(s % 60).padStart(2, "0");
return (
<div className="inline-flex items-center gap-2 text-xs text-neutral-500">
<span className="relative flex h-2 w-2">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75" />
<span className="relative inline-flex rounded-full h-2 w-2 bg-emerald-500" />
</span>
<span className="font-mono tabular-nums">{mm}:{ss}</span>
<span>working…</span>
</div>
);
}