Skip to content

Commit

Permalink
fix: update type definitions and improve ref handling in BlockMessage…
Browse files Browse the repository at this point in the history
…s and Messages components
  • Loading branch information
athrael-soju committed Dec 19, 2024
1 parent b688765 commit 277d63c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 18 deletions.
10 changes: 5 additions & 5 deletions components/block-messages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ interface BlockMessagesProps {
votes: Array<Vote> | undefined;
messages: Array<Message>;
setMessages: (
messages: Message[] | ((messages: Message[]) => Message[]),
messages: Message[] | ((messages: Message[]) => Message[])
) => void;
reload: (
chatRequestOptions?: ChatRequestOptions,
chatRequestOptions?: ChatRequestOptions
) => Promise<string | null | undefined>;
isReadonly: boolean;
blockStatus: UIBlock['status'];
Expand All @@ -35,7 +35,7 @@ function PureBlockMessages({

return (
<div
ref={messagesContainerRef}
ref={messagesContainerRef as React.RefObject<HTMLDivElement>}
className="flex flex-col gap-4 h-full items-center overflow-y-scroll px-4 pt-20"
>
{messages.map((message, index) => (
Expand All @@ -56,7 +56,7 @@ function PureBlockMessages({
))}

<div
ref={messagesEndRef}
ref={messagesEndRef as React.RefObject<HTMLDivElement>}
className="shrink-0 min-w-[24px] min-h-[24px]"
/>
</div>
Expand All @@ -65,7 +65,7 @@ function PureBlockMessages({

function areEqual(
prevProps: BlockMessagesProps,
nextProps: BlockMessagesProps,
nextProps: BlockMessagesProps
) {
if (
prevProps.blockStatus === 'streaming' &&
Expand Down
8 changes: 4 additions & 4 deletions components/messages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ interface MessagesProps {
votes: Array<Vote> | undefined;
messages: Array<Message>;
setMessages: (
messages: Message[] | ((messages: Message[]) => Message[]),
messages: Message[] | ((messages: Message[]) => Message[])
) => void;
reload: (
chatRequestOptions?: ChatRequestOptions,
chatRequestOptions?: ChatRequestOptions
) => Promise<string | null | undefined>;
isReadonly: boolean;
isBlockVisible: boolean;
Expand All @@ -35,7 +35,7 @@ function PureMessages({

return (
<div
ref={messagesContainerRef}
ref={messagesContainerRef as React.RefObject<HTMLDivElement>}
className="flex flex-col min-w-0 gap-6 flex-1 overflow-y-scroll pt-4"
>
{/* {messages.length === 0 && <Overview />} */}
Expand All @@ -62,7 +62,7 @@ function PureMessages({
messages[messages.length - 1].role === 'user' && <ThinkingMessage />}

<div
ref={messagesEndRef}
ref={messagesEndRef as React.RefObject<HTMLDivElement>}
className="shrink-0 min-w-[24px] min-h-[24px]"
/>
</div>
Expand Down
44 changes: 35 additions & 9 deletions components/use-scroll-to-bottom.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,55 @@
import { useEffect, useRef, type RefObject } from 'react';

export function useScrollToBottom<T extends HTMLElement>(): [
RefObject<T>,
RefObject<T>,
RefObject<T | null>,
RefObject<T | null>
] {
const containerRef = useRef<T>(null);
const endRef = useRef<T>(null);
const containerRef = useRef<T | null>(null);
const endRef = useRef<T | null>(null);
const shouldScrollRef = useRef(true);

useEffect(() => {
const container = containerRef.current;
const end = endRef.current;

if (container && end) {
// Initial scroll
end.scrollIntoView({ behavior: 'instant', block: 'end' });

// Check if user has scrolled up
const handleScroll = () => {
if (!container) return;

const isAtBottom =
Math.abs(
container.scrollHeight -
container.scrollTop -
container.clientHeight
) < 10;

shouldScrollRef.current = isAtBottom;
};

const observer = new MutationObserver(() => {
end.scrollIntoView({ behavior: 'instant', block: 'end' });
// Only scroll if we're at the bottom or it's a new message
if (shouldScrollRef.current) {
end.scrollIntoView({ behavior: 'instant', block: 'end' });
}
});

observer.observe(container, {
childList: true,
subtree: true,
attributes: true,
characterData: true,
subtree: true, // Watch nested changes
characterData: true, // Watch text changes
});

return () => observer.disconnect();
// Add scroll listener
container.addEventListener('scroll', handleScroll);

return () => {
observer.disconnect();
container.removeEventListener('scroll', handleScroll);
};
}
}, []);

Expand Down

0 comments on commit 277d63c

Please sign in to comment.