hammerjohn's picture
Duplicate from hf4all/bingo
638aac3
'use client'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useAtom } from 'jotai'
import Image from 'next/image'
import { cn } from '@/lib/utils'
import { ChatList } from '@/components/chat-list'
import { ChatPanel } from '@/components/chat-panel'
import { WelcomeScreen } from '@/components/welcome-screen'
import { ChatScrollAnchor } from '@/components/chat-scroll-anchor'
import { ToneSelector } from './tone-selector'
import { ChatHeader } from './chat-header'
import { ChatSuggestions } from './chat-suggestions'
import { bingConversationStyleAtom } from '@/state'
import { ButtonScrollToBottom } from '@/components/button-scroll-to-bottom'
import StopIcon from '@/assets/images/stop.svg'
import { useBing } from '@/lib/hooks/use-bing'
import { ChatMessageModel } from '@/lib/bots/bing/types'
import { ChatNotification } from './chat-notification'
import { Settings } from './settings'
import { ChatHistory } from './chat-history'
export type ChatProps = React.ComponentProps<'div'> & { initialMessages?: ChatMessageModel[] }
export default function Chat({ className }: ChatProps) {
const [bingStyle, setBingStyle] = useAtom(bingConversationStyleAtom)
const {
messages,
sendMessage,
resetConversation,
stopGenerating,
setInput,
bot,
input,
generating,
isSpeaking,
uploadImage,
attachmentList,
setAttachmentList,
} = useBing()
useEffect(() => {
window.scrollTo({
top: document.body.offsetHeight,
behavior: 'smooth'
})
}, [])
return (
<div className="flex flex-1 flex-col">
<Settings />
<div className={cn('flex-1 pb-16', className)}>
<ChatHeader />
<WelcomeScreen setInput={setInput} />
<ToneSelector type={bingStyle} onChange={setBingStyle} />
{messages.length ? (
<>
<ChatList messages={messages} />
<ChatScrollAnchor trackVisibility={generating} />
<ChatNotification message={messages.at(-1)} bot={bot} />
<ChatSuggestions setInput={setInput} suggestions={messages.at(-1)?.suggestedResponses} />
{generating ? (
<div className="flex h-10 items-center justify-center my-4">
<button
onClick={stopGenerating}
className="typing-control-item stop"
>
<Image alt="stop" src={StopIcon} width={24} className="mr-1" />
<span>停止响应</span>
</button>
</div>
) : null}
</>
) : null}
</div>
<ChatPanel
className="pt-24 z-10"
isSpeaking={isSpeaking}
generating={generating}
sendMessage={sendMessage}
input={input}
setInput={setInput}
resetConversation={resetConversation}
uploadImage={uploadImage}
attachmentList={attachmentList}
setAttachmentList={setAttachmentList}
/>
<ButtonScrollToBottom />
</div>
)
}