New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement auto scroll when stream message #2839
Conversation
useEffect(() => { | ||
if (!chatContainerRef.current || !messagesEndRef.current) return; | ||
const { scrollTop, scrollHeight, clientHeight } = chatContainerRef.current; | ||
const threshold = 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a magic number, I tested on different screen widths and found this is the most optimal one lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can just always scroll to the bottom, OpenAI does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the lib they use already handles that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would probably keep this very simple and just add
messagesEndRef.current.scrollIntoView();
in the onToken
handler after the new frame, and for good measure one final time after the streaming has finished.
I personally prefer without the smooth scrolling, because the scrolling speed is inconsistent depending on whether you have a new line or not, but that's a preference.
Your solution is great but here are a few things I want to support for better UX
I can't find any simple way to support both of these. Only the let message: InferenceMessage | null;
if (status === 204) {
// message already processed, get it immediately
message = await get(API_ROUTES.GET_MESSAGE(chatId, assistant_message.id));
} else {
message = await handleChatEventStream({
stream: body!,
onError: console.error,
onPending: setQueueInfo,
onToken: async (text) => {
setQueueInfo(null);
setResponse(text);
messagesEndRef.current?.scrollIntoView();
await new Promise(requestAnimationFrame);
},
});
}
if (message) {
setMessages((messages) => [...messages, message!]);
}
messagesEndRef.current?.scrollIntoView(); |
Maybe we should go with my solution, remove the threshold check and ignore the UX...lolll |
useEffect(() => { | ||
if (!chatContainerRef.current || !messagesEndRef.current) return; | ||
const { scrollTop, scrollHeight, clientHeight } = chatContainerRef.current; | ||
const threshold = 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can just always scroll to the bottom, OpenAI does it?
@AbdBarho I just switch to the new implementation, works much better now |
Nice! I didn't see this when I opened #2880. This feature is a convenience, so it's not the end of the world if it handles corner-cases imperfectly. Just having the UI generally keep up with the output will make it much nicer to use. |
After trying a bunch of methods I found this is the easiest way to do it. Other approaches are way more complicated. Also found this lib https://github.com/compulim/react-scroll-to-bottom OAI also uses it, but it doesn't support SSR and unmaintained for years. This solution is not really reliable, if you paste a prompt with many lines (4 or above), it doesn't work. It would be if someone can patch the `react-scroll-to-bottom` to support SSR.
After trying a bunch of methods I found this is the easiest way to do it. Other approaches are way more complicated.
Also found this lib https://github.com/compulim/react-scroll-to-bottom OAI also uses it, but it doesn't support SSR and unmaintained for years.
This solution is not really reliable, if you paste a prompt with many lines (4 or above), it doesn't work. It would be if someone can patch the
react-scroll-to-bottom
to support SSR.