| '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> |
| ) |
| } |
|
|