Spaces:
Sleeping
Sleeping
'use client'; | |
import { useChat, type Message } from 'ai/react'; | |
import '@/app/globals.css'; | |
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 { useState } from 'react'; | |
import { Button } from './ui/button'; | |
import { Input } from './ui/input'; | |
import { toast } from 'react-hot-toast'; | |
import { usePathname, useRouter } from 'next/navigation'; | |
import { useAtom } from 'jotai'; | |
import { targetImageAtom } from '@/state'; | |
import Image from 'next/image'; | |
import { ThemeToggle } from './theme-toggle'; | |
export interface ChatProps extends React.ComponentProps<'div'> { | |
initialMessages?: Message[]; | |
id?: string; | |
} | |
export function Chat({ id, initialMessages, className }: ChatProps) { | |
const router = useRouter(); | |
const path = usePathname(); | |
const [targetImage, setTargetImage] = useAtom(targetImageAtom); | |
const { messages, append, reload, stop, isLoading, input, setInput } = | |
useChat({ | |
initialMessages, | |
id, | |
body: { | |
id, | |
image: targetImage, | |
}, | |
onResponse(response) { | |
if (response.status === 401) { | |
toast.error(response.statusText); | |
} | |
}, | |
}); | |
if (!targetImage) | |
return ( | |
<div className={cn('pb-[150px] pt-4 md:pt-10 h-full', className)}> | |
<EmptyScreen /> | |
</div> | |
); | |
return ( | |
<> | |
<div className={cn('pb-[150px] pt-4 md:pt-10 h-full', className)}> | |
<div className="flex h-full"> | |
<div className="w-1/2 relative border-r-2 border-gray-200"> | |
<div className="relative aspect-[1/1] w-full px-12"> | |
<Image | |
src={targetImage} | |
alt="target image" | |
layout="responsive" | |
objectFit="contain" | |
width={1000} | |
height={1000} | |
className="rounded-xl shadow-lg" | |
/> | |
<button | |
className="px-2 py-1 rounded-lg text-blue-500 border-2 border-blue-400 flex items-center mt-4" | |
onClick={() => setTargetImage(null)} | |
> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
fill="none" | |
viewBox="0 0 24 24" | |
stroke="currentColor" | |
className="size-4" | |
> | |
<path | |
strokeLinecap="round" | |
strokeLinejoin="round" | |
strokeWidth={2} | |
d="M15 19l-7-7 7-7" | |
/> | |
</svg> | |
Back | |
</button> | |
</div> | |
</div> | |
<div className="w-1/2 relative overflow-auto"> | |
<ChatList messages={messages} isLoading={isLoading} /> | |
</div> | |
</div> | |
<ChatScrollAnchor trackVisibility={isLoading} /> | |
</div> | |
<ChatPanel | |
id={id} | |
isLoading={isLoading} | |
stop={stop} | |
append={append} | |
reload={reload} | |
messages={messages} | |
input={input} | |
setInput={setInput} | |
/> | |
</> | |
); | |
} | |