Skip to content

Commit

Permalink
feat(nx-dev): improve auto-scrolling so it does not interfere with us…
Browse files Browse the repository at this point in the history
…ers reading the content
  • Loading branch information
jaysoo committed Sep 15, 2023
1 parent 6242c87 commit 112011b
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions nx-dev/feature-ai/src/lib/feed-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
type JSX,
RefObject,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
Expand All @@ -28,8 +27,6 @@ export function FeedContainer(): JSX.Element {
const [startedReply, setStartedReply] = useState(false);
const [isStopped, setStopped] = useState(false);

const feedContainer: RefObject<HTMLDivElement> | undefined = useRef(null);

const {
messages,
setMessages,
Expand Down Expand Up @@ -57,14 +54,28 @@ export function FeedContainer(): JSX.Element {
},
});

const hasReply = useMemo(() => messages.length > 0, [messages]);

/*
* Determine whether we should scroll to the bottom of new messages.
* Scroll if:
* 1. New message has come in (length > previous length)
* 2. User is close to the bottom of the messages
*
* Otherwise, user is probably reading messages, so don't scroll.
*/
const scrollableWrapperRef: RefObject<HTMLDivElement> | undefined =
useRef(null);
const currentMessagesLength = useRef(0);
useEffect(() => {
if (feedContainer.current) {
const elements =
feedContainer.current.getElementsByClassName('feed-item');
elements[elements.length - 1].scrollIntoView({ behavior: 'smooth' });
if (!scrollableWrapperRef.current) return;
const el = scrollableWrapperRef.current;
let shouldScroll = false;
if (messages.length > currentMessagesLength.current) {
currentMessagesLength.current = messages.length;
shouldScroll = true;
} else if (el.scrollTop + el.clientHeight + 50 >= el.scrollHeight) {
shouldScroll = true;
}
if (shouldScroll) el.scrollTo(0, el.scrollHeight);
}, [messages, isLoading]);

const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
Expand Down Expand Up @@ -100,6 +111,7 @@ export function FeedContainer(): JSX.Element {
<>
{/*WRAPPER*/}
<div
ref={scrollableWrapperRef}
id="wrapper"
data-testid="wrapper"
className="relative flex flex-grow flex-col items-stretch justify-start overflow-y-scroll"
Expand All @@ -111,11 +123,7 @@ export function FeedContainer(): JSX.Element {
>
<div className="relative min-w-0 flex-auto">
{/*MAIN CONTENT*/}
<div
ref={feedContainer}
data-document="main"
className="relative pb-36"
>
<div data-document="main" className="relative pb-36">
<Feed
activity={!!messages.length ? messages : [assistantWelcome]}
onFeedback={handleFeedback}
Expand All @@ -139,7 +147,7 @@ export function FeedContainer(): JSX.Element {
onRegenerate={handleRegenerate}
input={input}
isGenerating={isLoading}
showNewChatCta={!isLoading && hasReply}
showNewChatCta={!isLoading && messages.length > 0}
showRegenerateCta={isStopped}
/>
</div>
Expand Down

0 comments on commit 112011b

Please sign in to comment.