fix: resolve scroll flickering on message send and improve thinking state animation (#1333)
This commit is contained in:
parent
d0b6f37aee
commit
a3802348fa
14 changed files with 225 additions and 174 deletions
|
|
@ -1,13 +1,11 @@
|
|||
import type { UseChatHelpers } from "@ai-sdk/react";
|
||||
import equal from "fast-deep-equal";
|
||||
import { AnimatePresence } from "framer-motion";
|
||||
import { ArrowDownIcon } from "lucide-react";
|
||||
import { memo, useEffect } from "react";
|
||||
import { memo } from "react";
|
||||
import { useMessages } from "@/hooks/use-messages";
|
||||
import type { Vote } from "@/lib/db/schema";
|
||||
import type { ChatMessage } from "@/lib/types";
|
||||
import { useDataStream } from "./data-stream-provider";
|
||||
import { Conversation, ConversationContent } from "./elements/conversation";
|
||||
import { Greeting } from "./greeting";
|
||||
import { PreviewMessage, ThinkingMessage } from "./message";
|
||||
|
||||
|
|
@ -31,7 +29,7 @@ function PureMessages({
|
|||
setMessages,
|
||||
regenerate,
|
||||
isReadonly,
|
||||
selectedModelId,
|
||||
selectedModelId: _selectedModelId,
|
||||
}: MessagesProps) {
|
||||
const {
|
||||
containerRef: messagesContainerRef,
|
||||
|
|
@ -45,62 +43,41 @@ function PureMessages({
|
|||
|
||||
useDataStream();
|
||||
|
||||
useEffect(() => {
|
||||
if (status === "submitted") {
|
||||
requestAnimationFrame(() => {
|
||||
const container = messagesContainerRef.current;
|
||||
if (container) {
|
||||
container.scrollTo({
|
||||
top: container.scrollHeight,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [status, messagesContainerRef]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="overscroll-behavior-contain -webkit-overflow-scrolling-touch flex-1 touch-pan-y overflow-y-scroll"
|
||||
className="relative flex-1 touch-pan-y overflow-y-auto"
|
||||
ref={messagesContainerRef}
|
||||
style={{ overflowAnchor: "none" }}
|
||||
>
|
||||
<Conversation className="mx-auto flex min-w-0 max-w-4xl flex-col gap-4 md:gap-6">
|
||||
<ConversationContent className="flex flex-col gap-4 px-2 py-4 md:gap-6 md:px-4">
|
||||
{messages.length === 0 && <Greeting />}
|
||||
<div className="mx-auto flex min-w-0 max-w-4xl flex-col gap-4 px-2 py-4 md:gap-6 md:px-4">
|
||||
{messages.length === 0 && <Greeting />}
|
||||
|
||||
{messages.map((message, index) => (
|
||||
<PreviewMessage
|
||||
chatId={chatId}
|
||||
isLoading={
|
||||
status === "streaming" && messages.length - 1 === index
|
||||
}
|
||||
isReadonly={isReadonly}
|
||||
key={message.id}
|
||||
message={message}
|
||||
regenerate={regenerate}
|
||||
requiresScrollPadding={
|
||||
hasSentMessage && index === messages.length - 1
|
||||
}
|
||||
setMessages={setMessages}
|
||||
vote={
|
||||
votes
|
||||
? votes.find((vote) => vote.messageId === message.id)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
||||
<AnimatePresence mode="wait">
|
||||
{status === "submitted" && <ThinkingMessage key="thinking" />}
|
||||
</AnimatePresence>
|
||||
|
||||
<div
|
||||
className="min-h-[24px] min-w-[24px] shrink-0"
|
||||
ref={messagesEndRef}
|
||||
{messages.map((message, index) => (
|
||||
<PreviewMessage
|
||||
chatId={chatId}
|
||||
isLoading={status === "streaming" && messages.length - 1 === index}
|
||||
isReadonly={isReadonly}
|
||||
key={message.id}
|
||||
message={message}
|
||||
regenerate={regenerate}
|
||||
requiresScrollPadding={
|
||||
hasSentMessage && index === messages.length - 1
|
||||
}
|
||||
setMessages={setMessages}
|
||||
vote={
|
||||
votes
|
||||
? votes.find((vote) => vote.messageId === message.id)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</ConversationContent>
|
||||
</Conversation>
|
||||
))}
|
||||
|
||||
{status === "submitted" && <ThinkingMessage />}
|
||||
|
||||
<div
|
||||
className="min-h-[24px] min-w-[24px] shrink-0"
|
||||
ref={messagesEndRef}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{!isAtBottom && (
|
||||
<button
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue