From 2ffee3bf64d4559c0b6a543f222698014a553e38 Mon Sep 17 00:00:00 2001 From: BetaHuhn Date: Tue, 5 Sep 2023 12:29:42 +0200 Subject: [PATCH] fix: auto scrolling --- src/components/MessageItem.tsx | 169 ++++++++++++++++----------------- src/hooks/useChatScroll.ts | 20 ++++ src/routes/ChatRoute.tsx | 15 +-- 3 files changed, 112 insertions(+), 92 deletions(-) create mode 100644 src/hooks/useChatScroll.ts diff --git a/src/components/MessageItem.tsx b/src/components/MessageItem.tsx index 1225677..6febef2 100644 --- a/src/components/MessageItem.tsx +++ b/src/components/MessageItem.tsx @@ -21,7 +21,6 @@ import { Message, detaDB } from "../db"; import "../styles/markdown.scss"; import { CreatePromptModal } from "./CreatePromptModal"; import { LogoIcon } from "./Logo"; -import { ScrollIntoView } from "./ScrollIntoView"; import { notifications } from "@mantine/notifications"; export function MessageItem({ message, onDeleted, handleUseMessage }: { message: Message, onDeleted: (key: string) => void, handleUseMessage: (key: string) => void }) { @@ -49,94 +48,92 @@ export function MessageItem({ message, onDeleted, handleUseMessage }: { message: } return ( - - setExpanded(true)} - style={{ cursor: 'pointer' }} - sx={{ - '&:hover': { - border: '1px solid #acacac' - } - }} - > - - {message.role === "user" && ( - - - - )} - {message.role === "assistant" && } - - ( - - ), - code: ({ node, inline, ...props }) => - inline ? ( - - ) : ( - - - - {({ copied, copy }) => ( - setExpanded(true)} + style={{ cursor: 'pointer' }} + sx={{ + '&:hover': { + border: '1px solid #acacac' + } + }} + > + + {message.role === "user" && ( + + + + )} + {message.role === "assistant" && } + + ( +
+ ), + code: ({ node, inline, ...props }) => + inline ? ( + + ) : ( + + + + {({ copied, copy }) => ( + + - - - - - )} - - - ), - }} - /> - - + + + + )} + + + ), + }} + /> + + - + - - - {wordCount} words - - + + + {wordCount} words + + - - - - handleUseMessage(message.content)}> - - - - - {({ copied, copy }) => ( - - - - - - )} - - - - - - - - - - - + + + + handleUseMessage(message.content)}> + + + + + {({ copied, copy }) => ( + + + + + + )} + + + + + + + + + + ); } diff --git a/src/hooks/useChatScroll.ts b/src/hooks/useChatScroll.ts new file mode 100644 index 0000000..2713cd0 --- /dev/null +++ b/src/hooks/useChatScroll.ts @@ -0,0 +1,20 @@ +import React, { useState } from 'react' + +export function useChatScroll(dep: T, elem = document.documentElement) { + const [autoScroll, setAutoScroll] = useState(true) + + document.onscroll = () => { + const scrollBottom = Math.floor(elem.scrollTop + elem.clientHeight) + const val = scrollBottom >= elem.scrollHeight - 70 + + setAutoScroll(val) + } + + React.useEffect(() => { + if (elem && autoScroll) { + elem.scrollTop = elem.scrollHeight; + } + }, [dep, autoScroll]); + + return { autoScroll, setAutoScroll } +} \ No newline at end of file diff --git a/src/routes/ChatRoute.tsx b/src/routes/ChatRoute.tsx index 4db949d..617a45f 100644 --- a/src/routes/ChatRoute.tsx +++ b/src/routes/ChatRoute.tsx @@ -25,6 +25,7 @@ import { useChat, useChats, usePrompts, useSettings } from "../hooks/contexts"; import { CreatePromptModal } from "../components/CreatePromptModal"; import { config } from "../utils/config"; import { useHotkeys } from "@mantine/hooks"; +import { useChatScroll } from "../hooks/useChatScroll"; export function ChatRoute() { const chatId = useChatId(); @@ -44,11 +45,8 @@ export function ChatRoute() { dataFetch(); }, [chatId]); + - // const messages = useLiveQuery(() => { - // if (!chatId) return []; - // return db.messages.where("chatId").equals(chatId).sortBy("createdAt"); - // }, [chatId]); const userMessages = messages ?.filter((message) => message.role === "user") @@ -59,11 +57,14 @@ export function ChatRoute() { const [submitting, setSubmitting] = useState(false); const [generating, setGenerating] = useState(false); const [coolDown, setCoolDown] = useState(false); + const [hasGenerated, setHasGenerated] = useState(false); const [chatStream, setChatStream] = useState(null); const [promptKey, setPromptKey] = useState(null); const [newPromptTitle, setNewPromptTitle] = useState(null); const [selectedModel, setSelectedModel] = useState(null); + const { setAutoScroll } = useChatScroll(messages) + const { setChats } = useChats() const { chat, setChat } = useChat() @@ -151,6 +152,7 @@ export function ChatRoute() { setMessages(current => [...current, userMessage as unknown as Message]) setContent(""); setPromptKey(null); + setHasGenerated(true) const systemMessage = await detaDB.messages.put({ chatId, @@ -161,6 +163,7 @@ export function ChatRoute() { setMessages(current => [...current, systemMessage as unknown as Message]) setGenerating(true) + setAutoScroll(true) const messageId = systemMessage!.key as string const chatCompletionStream = createStreamChatCompletion( @@ -290,7 +293,7 @@ export function ChatRoute() { } const undoGeneration = async () => { - if (!generating) return + if (!generating && !hasGenerated) return if (chatStream) { chatStream.abort() setChatStream(null) @@ -363,7 +366,7 @@ export function ChatRoute() { return ( <> - + {messages?.map((message) => ( ))}