From 0c951506356d5eda37ffdb9d7ec31f5939a6c647 Mon Sep 17 00:00:00 2001 From: Nicolas Varrot Date: Thu, 12 Feb 2026 10:37:07 +0000 Subject: [PATCH] feat: add elapsed time counter to thinking indicator Shows how long the agent has been thinking (e.g. '5s', '1m 23s'). Timer appears after 2 seconds to avoid flicker on fast responses. Helps users gauge if a request is still processing or stuck. --- src/components/TypingIndicator.tsx | 27 ++++++++++++++++++++++++++- src/lib/i18n.ts | 2 ++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/components/TypingIndicator.tsx b/src/components/TypingIndicator.tsx index 652a066..c513e26 100644 --- a/src/components/TypingIndicator.tsx +++ b/src/components/TypingIndicator.tsx @@ -1,6 +1,28 @@ +import { useState, useEffect, useRef } from 'react'; import { Bot } from 'lucide-react'; +import { useT } from '../hooks/useLocale'; + +function formatElapsed(seconds: number): string { + if (seconds < 60) return `${seconds}s`; + const m = Math.floor(seconds / 60); + const s = seconds % 60; + return `${m}m ${s.toString().padStart(2, '0')}s`; +} export function TypingIndicator() { + const t = useT(); + const [elapsed, setElapsed] = useState(0); + const startRef = useRef(Date.now()); + + useEffect(() => { + startRef.current = Date.now(); + setElapsed(0); + const interval = setInterval(() => { + setElapsed(Math.floor((Date.now() - startRef.current) / 1000)); + }, 1000); + return () => clearInterval(interval); + }, []); + return (
@@ -11,7 +33,10 @@ export function TypingIndicator() { - Thinking… + {t('chat.thinking')} + {elapsed >= 2 && ( + {formatElapsed(elapsed)} + )}
diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index 80d07d8..9514aad 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -42,6 +42,7 @@ const en = { 'chat.stop': 'Stop', 'chat.scrollToBottom': 'New messages', 'chat.messages': 'Chat messages', + 'chat.thinking': 'Thinking…', // Sidebar 'sidebar.title': 'Sessions', @@ -121,6 +122,7 @@ const fr: Record = { 'chat.stop': 'Arrêter', 'chat.scrollToBottom': 'Nouveaux messages', 'chat.messages': 'Messages du chat', + 'chat.thinking': 'Réflexion…', 'sidebar.title': 'Sessions', 'sidebar.empty': 'Aucune session',