- import { useCallback, useEffect, useMemo } from 'react'
 - import Chat from '../chat'
 - import type {
 -   ChatConfig,
 -   ChatItem,
 -   ChatItemInTree,
 -   OnSend,
 - } from '../types'
 - import { useChat } from '../chat/hooks'
 - import { getLastAnswer, isValidGeneratedAnswer } from '../utils'
 - import { useEmbeddedChatbotContext } from './context'
 - import ConfigPanel from './config-panel'
 - import { isDify } from './utils'
 - import cn from '@/utils/classnames'
 - import {
 -   fetchSuggestedQuestions,
 -   getUrl,
 -   stopChatMessageResponding,
 - } from '@/service/share'
 - import LogoAvatar from '@/app/components/base/logo/logo-embedded-chat-avatar'
 - import AnswerIcon from '@/app/components/base/answer-icon'
 - 
 - const ChatWrapper = () => {
 -   const {
 -     appData,
 -     appParams,
 -     appPrevChatList,
 -     currentConversationId,
 -     currentConversationItem,
 -     inputsForms,
 -     newConversationInputs,
 -     handleNewConversationCompleted,
 -     isMobile,
 -     isInstalledApp,
 -     appId,
 -     appMeta,
 -     handleFeedback,
 -     currentChatInstanceRef,
 -     themeBuilder,
 -   } = useEmbeddedChatbotContext()
 -   const appConfig = useMemo(() => {
 -     const config = appParams || {}
 - 
 -     return {
 -       ...config,
 -       file_upload: {
 -         ...(config as any).file_upload,
 -         fileUploadConfig: (config as any).system_parameters,
 -       },
 -       supportFeedback: true,
 -       opening_statement: currentConversationId ? currentConversationItem?.introduction : (config as any).opening_statement,
 -     } as ChatConfig
 -   }, [appParams, currentConversationItem?.introduction, currentConversationId])
 -   const {
 -     chatList,
 -     setTargetMessageId,
 -     handleSend,
 -     handleStop,
 -     isResponding,
 -     suggestedQuestions,
 -   } = useChat(
 -     appConfig,
 -     {
 -       inputs: (currentConversationId ? currentConversationItem?.inputs : newConversationInputs) as any,
 -       inputsForm: inputsForms,
 -     },
 -     appPrevChatList,
 -     taskId => stopChatMessageResponding('', taskId, isInstalledApp, appId),
 -   )
 - 
 -   useEffect(() => {
 -     if (currentChatInstanceRef.current)
 -       currentChatInstanceRef.current.handleStop = handleStop
 -   }, [currentChatInstanceRef, handleStop])
 - 
 -   const doSend: OnSend = useCallback((message, files, isRegenerate = false, parentAnswer: ChatItem | null = null) => {
 -     const data: any = {
 -       query: message,
 -       files,
 -       inputs: currentConversationId ? currentConversationItem?.inputs : newConversationInputs,
 -       conversation_id: currentConversationId,
 -       parent_message_id: (isRegenerate ? parentAnswer?.id : getLastAnswer(chatList)?.id) || null,
 -     }
 - 
 -     handleSend(
 -       getUrl('chat-messages', isInstalledApp, appId || ''),
 -       data,
 -       {
 -         onGetSuggestedQuestions: responseItemId => fetchSuggestedQuestions(responseItemId, isInstalledApp, appId),
 -         onConversationComplete: currentConversationId ? undefined : handleNewConversationCompleted,
 -         isPublicAPI: !isInstalledApp,
 -       },
 -     )
 -   }, [
 -     chatList,
 -     handleNewConversationCompleted,
 -     handleSend,
 -     currentConversationId,
 -     currentConversationItem,
 -     newConversationInputs,
 -     isInstalledApp,
 -     appId,
 -   ])
 - 
 -   const doRegenerate = useCallback((chatItem: ChatItemInTree) => {
 -     const question = chatList.find(item => item.id === chatItem.parentMessageId)!
 -     const parentAnswer = chatList.find(item => item.id === question.parentMessageId)
 -     doSend(question.content, question.message_files, true, isValidGeneratedAnswer(parentAnswer) ? parentAnswer : null)
 -   }, [chatList, doSend])
 - 
 -   const chatNode = useMemo(() => {
 -     if (inputsForms.length) {
 -       return (
 -         <>
 -           {!currentConversationId && (
 -             <div className={cn('mx-auto w-full max-w-full tablet:px-4', isMobile && 'px-4')}>
 -               <div className='mb-6' />
 -               <ConfigPanel />
 -               <div
 -                 className='my-6 h-[1px]'
 -                 style={{ background: 'linear-gradient(90deg, rgba(242, 244, 247, 0.00) 0%, #F2F4F7 49.17%, rgba(242, 244, 247, 0.00) 100%)' }}
 -               />
 -             </div>
 -           )}
 -         </>
 -       )
 -     }
 - 
 -     return null
 -   }, [currentConversationId, inputsForms, isMobile])
 - 
 -   const answerIcon = isDify()
 -     ? <LogoAvatar className='relative shrink-0' />
 -     : (appData?.site && appData.site.use_icon_as_answer_icon)
 -       ? <AnswerIcon
 -         iconType={appData.site.icon_type}
 -         icon={appData.site.icon}
 -         background={appData.site.icon_background}
 -         imageUrl={appData.site.icon_url}
 -       />
 -       : null
 - 
 -   return (
 -     <Chat
 -       appData={appData}
 -       config={appConfig}
 -       chatList={chatList}
 -       isResponding={isResponding}
 -       chatContainerInnerClassName={cn('mx-auto w-full max-w-full tablet:px-4', isMobile && 'px-4')}
 -       chatFooterClassName='pb-4'
 -       chatFooterInnerClassName={cn('mx-auto w-full max-w-full tablet:px-4', isMobile && 'px-4')}
 -       onSend={doSend}
 -       inputs={currentConversationId ? currentConversationItem?.inputs as any : newConversationInputs}
 -       inputsForm={inputsForms}
 -       onRegenerate={doRegenerate}
 -       onStopResponding={handleStop}
 -       chatNode={chatNode}
 -       allToolIcons={appMeta?.tool_icons || {}}
 -       onFeedback={handleFeedback}
 -       suggestedQuestions={suggestedQuestions}
 -       answerIcon={answerIcon}
 -       hideProcessDetail
 -       themeBuilder={themeBuilder}
 -       switchSibling={siblingMessageId => setTargetMessageId(siblingMessageId)}
 -     />
 -   )
 - }
 - 
 - export default ChatWrapper
 
 
  |