Files
aryx/src/renderer/hooks/useElapsedTimer.ts
T
David KayaandCopilot e79cbe8df9 feat: improve agent status and thinking indicator UX
- Show agent activity label in chat header (Thinking…, Using bash…, etc.)
  instead of an anonymous pulsing dot
- Fix ThinkingProcess elapsed timer to tick live every second using
  useElapsedTimer hook instead of stale useMemo computation
- Show completed/failed subagents for 3s grace period with fade-out
  transition instead of instantly hiding them
- Transition activity labels to Completed state for 1.5s grace period
  on session idle instead of abrupt removal
- Eliminate message flash during thinking reclassification by folding
  trailing pending assistant messages into the thinking group
  optimistically when they follow existing thinking messages
- Stabilize ThinkingProcess isActive flag by checking for pending
  messages in the group rather than relying solely on array position
- Skip rendering empty pending messages inside ThinkingProcess steps

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-07 08:44:18 +02:00

40 lines
1.1 KiB
TypeScript

import { useEffect, useState } from 'react';
function formatElapsed(startMs: number): string {
const seconds = Math.max(0, Math.floor((Date.now() - startMs) / 1000));
if (seconds < 60) return `${seconds}s`;
const minutes = Math.floor(seconds / 60);
const remainder = seconds % 60;
return `${minutes}m ${remainder}s`;
}
/**
* Returns a live-ticking elapsed-time string while `active` is true.
* Freezes the display when `active` becomes false.
*/
export function useElapsedTimer(startedAt: string | undefined, active: boolean): string | undefined {
const startMs = startedAt ? new Date(startedAt).getTime() : undefined;
const [elapsed, setElapsed] = useState<string | undefined>(() => {
if (!startMs) return undefined;
return formatElapsed(startMs);
});
useEffect(() => {
if (!startMs) {
setElapsed(undefined);
return;
}
// Always sync to current value immediately
setElapsed(formatElapsed(startMs));
if (!active) return;
const id = setInterval(() => setElapsed(formatElapsed(startMs)), 1000);
return () => clearInterval(id);
}, [startMs, active]);
return elapsed;
}