fix(web/chat): gate assistant animation to live stream state

This commit is contained in:
Alix-007 2026-03-27 01:41:35 +08:00
parent 8260f743cd
commit 432d8adbbf
2 changed files with 12 additions and 9 deletions

View file

@ -12,20 +12,18 @@ const STREAM_FRAME_MS = 18
const STREAM_STEPS = 60
interface AssistantMessageProps {
messageId?: string
content: string
timestamp?: string | number
isStreaming?: boolean
}
export function AssistantMessage({
messageId = "",
content,
timestamp = "",
isStreaming = false,
}: AssistantMessageProps) {
const [isCopied, setIsCopied] = useState(false)
const [displayedContent, setDisplayedContent] = useState(
messageId.startsWith("hist-") ? content : "",
)
const [displayedContent, setDisplayedContent] = useState(content)
const timerRef = useRef<number | null>(null)
const displayedRef = useRef(displayedContent)
const formattedTimestamp =
@ -50,13 +48,12 @@ export function AssistantMessage({
}, [])
useEffect(() => {
const isHistoryMessage = messageId.startsWith("hist-")
if (timerRef.current !== null) {
window.clearInterval(timerRef.current)
timerRef.current = null
}
if (isHistoryMessage || content.trim() === "") {
if (!isStreaming || content.trim() === "") {
queueMicrotask(() => syncDisplayedContent(content))
return
}
@ -86,7 +83,7 @@ export function AssistantMessage({
timerRef.current = null
}
}, STREAM_FRAME_MS)
}, [content, messageId])
}, [content, isStreaming])
const handleCopy = () => {
navigator.clipboard.writeText(content).then(() => {

View file

@ -66,6 +66,12 @@ export function ChatPage() {
setIsAtBottom(scrollHeight - scrollTop <= clientHeight + 10)
}
const liveAssistantMessageId = isTyping
? [...messages]
.reverse()
.find((message) => message.role === "assistant")?.id
: undefined
const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
syncScrollState(e.currentTarget)
}
@ -150,9 +156,9 @@ export function ChatPage() {
<div key={msg.id} className="flex w-full">
{msg.role === "assistant" ? (
<AssistantMessage
messageId={msg.id}
content={msg.content}
timestamp={msg.timestamp}
isStreaming={msg.id === liveAssistantMessageId}
/>
) : (
<UserMessage content={msg.content} />