Update PlaygroundForm and Sidebar components

This commit is contained in:
n4ze3m 2024-02-07 00:48:59 +05:30
parent 58966355c3
commit c1efb2d5cb
4 changed files with 65 additions and 14 deletions

View File

@ -1,5 +1,5 @@
import { useForm } from "@mantine/form" import { useForm } from "@mantine/form"
import { useMutation } from "@tanstack/react-query" import { useMutation, useQueryClient } from "@tanstack/react-query"
import React from "react" import React from "react"
import useDynamicTextareaSize from "~hooks/useDynamicTextareaSize" import useDynamicTextareaSize from "~hooks/useDynamicTextareaSize"
import PhotoIcon from "@heroicons/react/24/outline/PhotoIcon" import PhotoIcon from "@heroicons/react/24/outline/PhotoIcon"
@ -50,12 +50,19 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
} }
}, [dropedFile]) }, [dropedFile])
useDynamicTextareaSize(textareaRef, form.values.message, 120) useDynamicTextareaSize(textareaRef, form.values.message, 300)
const { onSubmit, selectedModel, chatMode } = useMessageOption() const { onSubmit, selectedModel, chatMode, clearChat } = useMessageOption()
const queryClient = useQueryClient()
const { mutateAsync: sendMessage, isPending: isSending } = useMutation({ const { mutateAsync: sendMessage, isPending: isSending } = useMutation({
mutationFn: onSubmit mutationFn: onSubmit,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["fetchChatHistory"]
})
}
}) })
return ( return (
@ -82,7 +89,9 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
</div> </div>
<div className="flex"> <div className="flex">
<Tooltip title="New Chat"> <Tooltip title="New Chat">
<button className="text-gray-500 dark:text-gray-100 mr-3"> <button
onClick={clearChat}
className="text-gray-500 dark:text-gray-100 mr-3">
<ArrowPathIcon className="h-5 w-5" /> <ArrowPathIcon className="h-5 w-5" />
</button> </button>
</Tooltip> </Tooltip>

View File

@ -1,10 +1,17 @@
import { useQuery } from "@tanstack/react-query" import { useQuery } from "@tanstack/react-query"
import { PageAssitDatabase } from "~libs/db" import {
PageAssitDatabase,
formatToChatHistory,
formatToMessage
} from "~libs/db"
import { Empty, Skeleton } from "antd" import { Empty, Skeleton } from "antd"
import { useMessageOption } from "~hooks/useMessageOption"
type Props = {} type Props = {}
export const Sidebar = ({}: Props) => { export const Sidebar = ({}: Props) => {
const { setMessages, setHistory, setHistoryId } = useMessageOption()
const { data: chatHistories, status } = useQuery({ const { data: chatHistories, status } = useQuery({
queryKey: ["fetchChatHistory"], queryKey: ["fetchChatHistory"],
queryFn: async () => { queryFn: async () => {
@ -15,7 +22,7 @@ export const Sidebar = ({}: Props) => {
}) })
return ( return (
<div className="overflow-y-auto h-[calc(100%-60px)]"> <div className="overflow-y-auto">
{status === "success" && chatHistories.length === 0 && ( {status === "success" && chatHistories.length === 0 && (
<div className="flex justify-center items-center mt-20 overflow-hidden"> <div className="flex justify-center items-center mt-20 overflow-hidden">
<Empty description="No history yet" /> <Empty description="No history yet" />
@ -34,11 +41,18 @@ export const Sidebar = ({}: Props) => {
{status === "success" && chatHistories.length > 0 && ( {status === "success" && chatHistories.length > 0 && (
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
{chatHistories.map((chat, index) => ( {chatHistories.map((chat, index) => (
<div <button
onClick={async () => {
const db = new PageAssitDatabase()
const history = await db.getChatHistory(chat.id)
setHistoryId(chat.id)
setHistory(formatToChatHistory(history))
setMessages(formatToMessage(history))
}}
key={index} key={index}
className="flex py-2 px-2 cursor-pointer items-center gap-3 relative rounded-md truncate hover:pr-4 group transition-opacity duration-300 ease-in-out bg-gray-100 dark:bg-[#232222] dark:text-gray-100 text-gray-800 border hover:bg-gray-200 dark:hover:bg-[#2d2d2d] dark:border-gray-800"> className="flex text-start py-2 px-2 cursor-pointer items-start gap-3 relative rounded-md truncate hover:pr-4 group transition-opacity duration-300 ease-in-out bg-gray-100 dark:bg-[#232222] dark:text-gray-100 text-gray-800 border hover:bg-gray-200 dark:hover:bg-[#2d2d2d] dark:border-gray-800">
<span className="flex-grow truncate">{chat.title}</span> <span className="flex-grow truncate">{chat.title}</span>
</div> </button>
))} ))}
</div> </div>
)} )}

View File

@ -95,7 +95,7 @@ export const useMessageOption = () => {
const abortControllerRef = React.useRef<AbortController | null>(null) const abortControllerRef = React.useRef<AbortController | null>(null)
const clearChat = () => { const clearChat = () => {
stopStreamingRequest() // stopStreamingRequest()
setMessages([]) setMessages([])
setHistory([]) setHistory([])
setHistoryId(null) setHistoryId(null)

View File

@ -1,4 +1,7 @@
im import {
type ChatHistory as ChatHistoryType,
type Message as MessageType
} from "~store/option"
type HistoryInfo = { type HistoryInfo = {
id: string id: string
@ -13,6 +16,7 @@ type Message = {
role: string role: string
content: string content: string
images?: string[] images?: string[]
sources?: string[]
createdAt: number createdAt: number
} }
@ -84,8 +88,6 @@ const generateID = () => {
}) })
} }
export const saveHistory = async (title: string) => { export const saveHistory = async (title: string) => {
const id = generateID() const id = generateID()
const createdAt = Date.now() const createdAt = Date.now()
@ -109,3 +111,29 @@ export const saveMessage = async (
await db.addMessage(message) await db.addMessage(message)
return message return message
} }
export const formatToChatHistory = (
messages: MessageHistory
): ChatHistoryType => {
messages.sort((a, b) => a.createdAt - b.createdAt)
return messages.map((message) => {
return {
content: message.content,
role: message.role as "user" | "assistant" | "system",
images: message.images
}
})
}
export const formatToMessage = (messages: MessageHistory): MessageType[] => {
messages.sort((a, b) => a.createdAt - b.createdAt)
return messages.map((message) => {
return {
isBot: message.role === "assistant",
message: message.content,
name: message.name,
sources: message?.sources || [],
images: message.images || []
}
})
}