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 8f1a1c6
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 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
2 changes: 1 addition & 1 deletion nx-dev/nx-dev/pages/ai-chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function AiDocs(): JSX.Element {
maxVideoPreview: -1,
}}
/>
<div id="shell" className="flex h-full flex-col">
<div id="shell" className="flex h-[100dvh] flex-col">
<div className="w-full flex-shrink-0">
<DocumentationHeader isNavOpen={navIsOpen} toggleNav={toggleNav} />
</div>
Expand Down

0 comments on commit 8f1a1c6

Please sign in to comment.