把运行中回合的秒级计时下移到耗时文案组件

- apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectConversation/DirectProjectConversation.tsx 新增 DirectTurnElapsed,自己持有 1 秒 tick 与已耗时渲染
- apps/ai-game-creator-shell/src/view/project-development/chat/DirectProjectChatView.tsx 删除 turnUsageNow state 与其 interval,不再把每秒 tick 传给会话区
- 原先每秒 tick 触发的是整个聊天视图重渲染(含 Markdown 回合列表、工具调用组与队列芯片),现在只重渲染耗时那一小块
This commit is contained in:
2026-09-19 23:16:42 +08:00
parent 50291a5e77
commit 263588af6a
2 changed files with 29 additions and 21 deletions
@@ -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<ApprovalMode>('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}
/>
@@ -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<HTMLDivElement>;
}) {
@@ -64,18 +67,32 @@ export function DirectProjectConversation({
<header>
<span aria-hidden="true" />
<strong></strong>
{activeTurnStartedAt > 0 ? (
<em className="project-chat-process-elapsed">
{`已耗时 ${
formatTurnDuration(
Math.max(0, turnUsageNow - activeTurnStartedAt),
) ?? '0秒'
}`}
</em>
) : null}
<DirectTurnElapsed startedAt={activeTurnStartedAt} />
</header>
</AgentMessageContent>
) : 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 (
<em className="project-chat-process-elapsed">
{`已耗时 ${formatTurnDuration(Math.max(0, now - startedAt)) ?? '0秒'}`}
</em>
);
}