scroll btn (#256)

* feat: added scroll down button

when the use scrolls up on the chat a button will appear on the bottom right side of the screen. It will smoothly scroll down to the bottom of the chat when the button was pressed.

* remove env

---------

Co-authored-by: dasunNimantha <dasun4@pm.me>
This commit is contained in:
Mckay Wrigley 2023-03-28 02:52:45 -06:00 committed by GitHub
parent a73ef2b8cf
commit 1f9d17f8bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 2 deletions

View File

@ -1,4 +1,5 @@
import { Conversation, Message } from '@/types/chat'; import { Conversation, Message } from '@/types/chat';
import { IconArrowDown } from '@tabler/icons-react';
import { KeyValuePair } from '@/types/data'; import { KeyValuePair } from '@/types/data';
import { ErrorMessage } from '@/types/error'; import { ErrorMessage } from '@/types/error';
import { OpenAIModel } from '@/types/openai'; import { OpenAIModel } from '@/types/openai';
@ -58,8 +59,10 @@ export const Chat: FC<Props> = memo(
}) => { }) => {
const { t } = useTranslation('chat'); const { t } = useTranslation('chat');
const [currentMessage, setCurrentMessage] = useState<Message>(); const [currentMessage, setCurrentMessage] = useState<Message>();
const [autoScrollEnabled, setAutoScrollEnabled] = useState(true); const [autoScrollEnabled, setAutoScrollEnabled] = useState<boolean>(true);
const [showSettings, setShowSettings] = useState<boolean>(false); const [showSettings, setShowSettings] = useState<boolean>(false);
const [showScrollDownButton, setShowScrollDownButton] =
useState<boolean>(false);
const messagesEndRef = useRef<HTMLDivElement>(null); const messagesEndRef = useRef<HTMLDivElement>(null);
const chatContainerRef = useRef<HTMLDivElement>(null); const chatContainerRef = useRef<HTMLDivElement>(null);
@ -80,12 +83,21 @@ export const Chat: FC<Props> = memo(
if (scrollTop + clientHeight < scrollHeight - bottomTolerance) { if (scrollTop + clientHeight < scrollHeight - bottomTolerance) {
setAutoScrollEnabled(false); setAutoScrollEnabled(false);
setShowScrollDownButton(true);
} else { } else {
setAutoScrollEnabled(true); setAutoScrollEnabled(true);
setShowScrollDownButton(false);
} }
} }
}; };
const handleScrollDown = () => {
chatContainerRef.current?.scrollTo({
top: chatContainerRef.current.scrollHeight,
behavior: 'smooth',
});
};
const handleSettings = () => { const handleSettings = () => {
setShowSettings(!showSettings); setShowSettings(!showSettings);
}; };
@ -103,6 +115,8 @@ export const Chat: FC<Props> = memo(
}; };
const throttledScrollDown = throttle(scrollDown, 250); const throttledScrollDown = throttle(scrollDown, 250);
// appear scroll down button only when user scrolls up
useEffect(() => { useEffect(() => {
throttledScrollDown(); throttledScrollDown();
setCurrentMessage( setCurrentMessage(
@ -172,6 +186,7 @@ export const Chat: FC<Props> = memo(
<div <div
className="max-h-full overflow-x-hidden" className="max-h-full overflow-x-hidden"
ref={chatContainerRef} ref={chatContainerRef}
onScroll={handleScroll}
> >
{conversation.messages.length === 0 ? ( {conversation.messages.length === 0 ? (
<> <>
@ -285,6 +300,16 @@ export const Chat: FC<Props> = memo(
/> />
</> </>
)} )}
{showScrollDownButton && (
<div className="absolute bottom-0 right-0 mb-4 mr-4 pb-20">
<button
className="flex h-7 w-7 items-center justify-center rounded-full bg-white shadow-md hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-[#515152d7]"
onClick={handleScrollDown}
>
<IconArrowDown className="h-4 w-4" />
</button>
</div>
)}
</div> </div>
); );
}, },