feat: chat autoscroll (#6)
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import type { Message } from 'ai';
|
||||
import type { LegacyRef } from 'react';
|
||||
import React from 'react';
|
||||
import React, { type LegacyRef, type RefCallback } from 'react';
|
||||
import { ClientOnly } from 'remix-utils/client-only';
|
||||
import { classNames } from '../../utils/classNames';
|
||||
import { IconButton } from '../ui/IconButton';
|
||||
@@ -10,6 +9,8 @@ import { SendButton } from './SendButton.client';
|
||||
|
||||
interface BaseChatProps {
|
||||
textareaRef?: LegacyRef<HTMLTextAreaElement> | undefined;
|
||||
messageRef?: RefCallback<HTMLDivElement> | undefined;
|
||||
scrollRef?: RefCallback<HTMLDivElement> | undefined;
|
||||
chatStarted?: boolean;
|
||||
isStreaming?: boolean;
|
||||
messages?: Message[];
|
||||
@@ -30,6 +31,8 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
(
|
||||
{
|
||||
textareaRef,
|
||||
messageRef,
|
||||
scrollRef,
|
||||
chatStarted = false,
|
||||
isStreaming = false,
|
||||
enhancingPrompt = false,
|
||||
@@ -47,7 +50,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
|
||||
return (
|
||||
<div ref={ref} className="relative flex h-full w-full overflow-hidden ">
|
||||
<div className="flex overflow-scroll w-full h-full">
|
||||
<div ref={scrollRef} className="flex overflow-scroll w-full h-full">
|
||||
<div id="chat" className="flex flex-col w-full h-full px-6">
|
||||
{!chatStarted && (
|
||||
<div id="intro" className="mt-[20vh] mb-14 max-w-3xl mx-auto">
|
||||
@@ -71,6 +74,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
{() => {
|
||||
return chatStarted ? (
|
||||
<Messages
|
||||
ref={messageRef}
|
||||
className="flex flex-col w-full flex-1 max-w-3xl px-4 pb-10 mx-auto z-1"
|
||||
messages={messages}
|
||||
isStreaming={isStreaming}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useChat } from 'ai/react';
|
||||
import { useAnimate } from 'framer-motion';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { useMessageParser, usePromptEnhancer } from '../../lib/hooks';
|
||||
import { useMessageParser, usePromptEnhancer, useSnapScroll } from '../../lib/hooks';
|
||||
import { chatStore } from '../../lib/stores/chat';
|
||||
import { workbenchStore } from '../../lib/stores/workbench';
|
||||
import { cubicEasingFn } from '../../utils/easings';
|
||||
@@ -87,6 +87,8 @@ export function Chat() {
|
||||
textareaRef.current?.blur();
|
||||
};
|
||||
|
||||
const [messageRef, scrollRef] = useSnapScroll();
|
||||
|
||||
return (
|
||||
<BaseChat
|
||||
ref={animationScope}
|
||||
@@ -97,6 +99,8 @@ export function Chat() {
|
||||
enhancingPrompt={enhancingPrompt}
|
||||
promptEnhanced={promptEnhanced}
|
||||
sendMessage={sendMessage}
|
||||
messageRef={messageRef}
|
||||
scrollRef={scrollRef}
|
||||
handleInputChange={handleInputChange}
|
||||
handleStop={abort}
|
||||
messages={messages.map((message, i) => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { Message } from 'ai';
|
||||
import { classNames } from '../../utils/classNames';
|
||||
import { AssistantMessage } from './AssistantMessage';
|
||||
import { UserMessage } from './UserMessage';
|
||||
import React from 'react';
|
||||
|
||||
interface MessagesProps {
|
||||
id?: string;
|
||||
@@ -10,11 +11,11 @@ interface MessagesProps {
|
||||
messages?: Message[];
|
||||
}
|
||||
|
||||
export function Messages(props: MessagesProps) {
|
||||
export const Messages = React.forwardRef<HTMLDivElement, MessagesProps>((props: MessagesProps, ref) => {
|
||||
const { id, isStreaming = false, messages = [] } = props;
|
||||
|
||||
return (
|
||||
<div id={id} className={props.className}>
|
||||
<div id={id} ref={ref} className={props.className}>
|
||||
{messages.length > 0
|
||||
? messages.map((message, i) => {
|
||||
const { role, content } = message;
|
||||
@@ -61,4 +62,4 @@ export function Messages(props: MessagesProps) {
|
||||
{isStreaming && <div className="text-center w-full i-svg-spinners:3-dots-fade text-4xl mt-4"></div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user