File size: 2,982 Bytes
7e0c4ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
'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'

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