67 lines
1.5 KiB
TypeScript
67 lines
1.5 KiB
TypeScript
|
|
'use client'
|
||
|
|
|
||
|
|
import { useChat, type Message } from 'ai/react'
|
||
|
|
|
||
|
|
import { cn } from '@/lib/utils'
|
||
|
|
import { ChatList } from '@/components/chat-list'
|
||
|
|
import { ChatPanel } from '@/components/chat-panel'
|
||
|
|
import { EmptyScreen } from '@/components/empty-screen'
|
||
|
|
import { ChatScrollAnchor } from '@/components/chat-scroll-anchor'
|
||
|
|
import { toast } from 'react-hot-toast'
|
||
|
|
import { usePatchFetch } from '@/lib/hooks/use-patch-fetch'
|
||
|
|
|
||
|
|
export interface ChatProps extends React.ComponentProps<'div'> {
|
||
|
|
initialMessages?: Message[]
|
||
|
|
id?: string
|
||
|
|
}
|
||
|
|
|
||
|
|
export function Chat({ id, initialMessages, className }: ChatProps) {
|
||
|
|
usePatchFetch()
|
||
|
|
|
||
|
|
const {
|
||
|
|
messages,
|
||
|
|
append,
|
||
|
|
reload,
|
||
|
|
stop,
|
||
|
|
isLoading,
|
||
|
|
input,
|
||
|
|
setInput,
|
||
|
|
setMessages
|
||
|
|
} = useChat({
|
||
|
|
initialMessages,
|
||
|
|
id,
|
||
|
|
body: {
|
||
|
|
id
|
||
|
|
},
|
||
|
|
onResponse(response) {
|
||
|
|
if (response.status === 401) {
|
||
|
|
toast.error(response.statusText)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
return (
|
||
|
|
<>
|
||
|
|
<div className={cn('pb-[200px] pt-4 md:pt-10', className)}>
|
||
|
|
{messages.length ? (
|
||
|
|
<>
|
||
|
|
<ChatList messages={messages} />
|
||
|
|
<ChatScrollAnchor trackVisibility={isLoading} />
|
||
|
|
</>
|
||
|
|
) : (
|
||
|
|
<EmptyScreen setInput={setInput} />
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
<ChatPanel
|
||
|
|
id={id}
|
||
|
|
isLoading={isLoading}
|
||
|
|
stop={stop}
|
||
|
|
append={append}
|
||
|
|
reload={reload}
|
||
|
|
messages={messages}
|
||
|
|
input={input}
|
||
|
|
setInput={setInput}
|
||
|
|
/>
|
||
|
|
</>
|
||
|
|
)
|
||
|
|
}
|