diff --git a/apps/ai-game-creator-shell/src/view/project-development/chat/DirectProjectChatView.tsx b/apps/ai-game-creator-shell/src/view/project-development/chat/DirectProjectChatView.tsx index d8720c944..bd51ea53a 100644 --- a/apps/ai-game-creator-shell/src/view/project-development/chat/DirectProjectChatView.tsx +++ b/apps/ai-game-creator-shell/src/view/project-development/chat/DirectProjectChatView.tsx @@ -100,7 +100,6 @@ export function DirectProjectChatView({ const shouldFollowLatestRef = useRef(true); const [runtimeNotice, setRuntimeNotice] = useState(''); const [settingsOpen, setSettingsOpen] = useState(false); - const [turnUsageNow, setTurnUsageNow] = useState(() => Date.now()); const [approvalOpen, setApprovalOpen] = useState(false); const [approvalMode, setApprovalMode] = useState('strict'); const [approvalNotice, setApprovalNotice] = useState(''); @@ -183,13 +182,6 @@ export function DirectProjectChatView({ if (list) list.scrollTop = list.scrollHeight; }, [directEntries, localMessages]); - useEffect(() => { - if (!directTurnRunning) return; - setTurnUsageNow(Date.now()); - const timer = setInterval(() => setTurnUsageNow(Date.now()), 1000); - return () => clearInterval(timer); - }, [directTurnRunning]); - const directTurns = buildDirectChatTurns({ entries: directEntries, localMessages, @@ -231,7 +223,6 @@ export function DirectProjectChatView({ historyHasMore={historyHasMore} running={directTurnRunning} activeTurnStartedAt={activeTurnStartedAt} - turnUsageNow={turnUsageNow} onLoadEarlierHistory={() => void loadEarlierHistory()} onScroll={handleScroll} /> diff --git a/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectConversation/DirectProjectConversation.tsx b/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectConversation/DirectProjectConversation.tsx index 8a063a383..b982c84ae 100644 --- a/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectConversation/DirectProjectConversation.tsx +++ b/apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectConversation/DirectProjectConversation.tsx @@ -1,4 +1,9 @@ -import type { RefObject, UIEventHandler } from 'react'; +import { + type RefObject, + type UIEventHandler, + useEffect, + useState, +} from 'react'; import { AgentMessageContent } from '../../../../../../../../packages/shared/src/components/AgentMessageContent'; import type { DirectChatTurn } from '../../conversation/directTurnPresentation'; @@ -16,7 +21,6 @@ export function DirectProjectConversation({ historyHasMore, running, activeTurnStartedAt, - turnUsageNow, onLoadEarlierHistory, onScroll, }: { @@ -25,7 +29,6 @@ export function DirectProjectConversation({ historyHasMore: boolean; running: boolean; activeTurnStartedAt: number; - turnUsageNow: number; onLoadEarlierHistory: () => void; onScroll: UIEventHandler; }) { @@ -64,18 +67,32 @@ export function DirectProjectConversation({
) : null} ); } + +/** + * 运行中回合的已耗时。 + * + * 计时器只属于这一小块:秒级 tick 不该把整份回合列表(Markdown、工具组、队列芯片) + * 一起重渲染。 + */ +function DirectTurnElapsed({ startedAt }: { startedAt: number }) { + const [now, setNow] = useState(() => Date.now()); + useEffect(() => { + if (startedAt <= 0) return undefined; + setNow(Date.now()); + const timer = setInterval(() => setNow(Date.now()), 1000); + return () => clearInterval(timer); + }, [startedAt]); + if (startedAt <= 0) return null; + return ( + + {`已耗时 ${formatTurnDuration(Math.max(0, now - startedAt)) ?? '0秒'}`} + + ); +}