修复纯聊天流式回复滚动

恢复 standalone supervisor 聊天的流式消息自动跟随
保留用户上移后的滚动位置
统一使用底部阈值判断是否继续跟随
This commit is contained in:
2026-09-04 15:28:40 +08:00
parent 60a87a4303
commit 6591b04a56
@@ -5,8 +5,10 @@ import type {
FormEventHandler,
RefObject,
SetStateAction,
UIEvent,
UIEventHandler,
} from 'react';
import { useLayoutEffect, useRef } from 'react';
import type {
AgentRuntimeState,
@@ -33,6 +35,8 @@ type RuntimeControlProps = ComponentProps<
typeof ProjectSupervisorRuntimeControls
>;
const CHAT_SCROLL_BOTTOM_THRESHOLD = 24;
type SupervisorChatOnlyViewProps = {
chatAgentBusy: boolean;
chatInput: string;
@@ -95,6 +99,7 @@ export function SupervisorChatOnlyView({
visibleMessages,
workspaceStatus,
}: SupervisorChatOnlyViewProps) {
const shouldFollowLatestRef = useRef(true);
const running = Boolean(
chatAgentBusy || (runtime && !isAgentRuntimeTerminalState(runtime)),
);
@@ -107,6 +112,34 @@ export function SupervisorChatOnlyView({
: runtime
? projectSupervisorChatRuntimeStatus(runtime)
: projectWorkspaceStatusForDisplay(workspaceStatus);
useLayoutEffect(() => {
if (!running) {
return;
}
const messageList = messagesRef.current;
if (!messageList) {
return;
}
if (shouldFollowLatestRef.current) {
messageList.scrollTop = messageList.scrollHeight;
}
}, [
messagesRef,
running,
runtime?.updatedAt,
transientReply,
visibleMessages.length,
]);
function handleScroll(event: UIEvent<HTMLDivElement>) {
const messageList = event.currentTarget;
const distanceFromBottom =
messageList.scrollHeight -
messageList.scrollTop -
messageList.clientHeight;
shouldFollowLatestRef.current =
distanceFromBottom <= CHAT_SCROLL_BOTTOM_THRESHOLD;
onScroll(event);
}
const conversationLabel = directCodex
? '陶泥儿项目对话'
: '项目总控 Agent 纯聊天';
@@ -139,7 +172,7 @@ export function SupervisorChatOnlyView({
ref={messagesRef}
className="message-list supervisor-chat-only-message-list"
aria-label={directCodex ? '陶泥儿消息' : '项目总控消息'}
onScroll={onScroll}
onScroll={handleScroll}
>
{hiddenConversationCount > 0 ? (
<button