From 77950e48c76f4a3b29d01831d43039caba29888a Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 18 十一月 2025 14:12:42 +0800
Subject: [PATCH] 修改
---
app/components/base/chat/chat-with-history/chat-wrapper.tsx | 194 +++++++++++++----------------------------------
1 files changed, 55 insertions(+), 139 deletions(-)
diff --git a/app/components/base/chat/chat-with-history/chat-wrapper.tsx b/app/components/base/chat/chat-with-history/chat-wrapper.tsx
index 63de135..7725920 100644
--- a/app/components/base/chat/chat-with-history/chat-wrapper.tsx
+++ b/app/components/base/chat/chat-with-history/chat-wrapper.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useMemo, useState } from 'react'
+import { useCallback, useEffect, useMemo } from 'react'
import Chat from '../chat'
import type {
ChatConfig,
@@ -9,20 +9,14 @@
import { useChat } from '../chat/hooks'
import { getLastAnswer, isValidGeneratedAnswer } from '../utils'
import { useChatWithHistoryContext } from './context'
-import { InputVarType } from '@/app/components/workflow/types'
-import { TransferMethod } from '@/types/app'
-import InputsForm from '@/app/components/base/chat/chat-with-history/inputs-form'
+import Header from './header'
+import ConfigPanel from './config-panel'
import {
fetchSuggestedQuestions,
getUrl,
stopChatMessageResponding,
} from '@/service/share'
-import AppIcon from '@/app/components/base/app-icon'
import AnswerIcon from '@/app/components/base/answer-icon'
-import SuggestedQuestions from '@/app/components/base/chat/chat/answer/suggested-questions'
-import { Markdown } from '@/app/components/base/markdown'
-import cn from '@/utils/classnames'
-import type { FileEntity } from '../../file-uploader/types'
const ChatWrapper = () => {
const {
@@ -30,10 +24,8 @@
appPrevChatTree,
currentConversationId,
currentConversationItem,
- currentConversationInputs,
inputsForms,
newConversationInputs,
- newConversationInputsRef,
handleNewConversationCompleted,
isMobile,
isInstalledApp,
@@ -43,10 +35,6 @@
currentChatInstanceRef,
appData,
themeBuilder,
- sidebarCollapseState,
- clearChatList,
- setClearChatList,
- setIsResponding,
} = useChatWithHistoryContext()
const appConfig = useMemo(() => {
const config = appParams || {}
@@ -66,51 +54,17 @@
setTargetMessageId,
handleSend,
handleStop,
- isResponding: respondingState,
+ isResponding,
suggestedQuestions,
} = useChat(
appConfig,
{
- inputs: (currentConversationId ? currentConversationInputs : newConversationInputs) as any,
+ inputs: (currentConversationId ? currentConversationItem?.inputs : newConversationInputs) as any,
inputsForm: inputsForms,
},
appPrevChatTree,
taskId => stopChatMessageResponding('', taskId, isInstalledApp, appId),
- clearChatList,
- setClearChatList,
)
- const inputsFormValue = currentConversationId ? currentConversationInputs : newConversationInputsRef?.current
- const inputDisabled = useMemo(() => {
- let hasEmptyInput = ''
- let fileIsUploading = false
- const requiredVars = inputsForms.filter(({ required }) => required)
- if (requiredVars.length) {
- requiredVars.forEach(({ variable, label, type }) => {
- if (hasEmptyInput)
- return
-
- if (fileIsUploading)
- return
-
- if (!inputsFormValue?.[variable])
- hasEmptyInput = label as string
-
- if ((type === InputVarType.singleFile || type === InputVarType.multiFiles) && inputsFormValue?.[variable]) {
- const files = inputsFormValue[variable]
- if (Array.isArray(files))
- fileIsUploading = files.find(item => item.transferMethod === TransferMethod.local_file && !item.uploadedId)
- else
- fileIsUploading = files.transferMethod === TransferMethod.local_file && !files.uploadedId
- }
- })
- }
- if (hasEmptyInput)
- return true
-
- if (fileIsUploading)
- return true
- return false
- }, [inputsFormValue, inputsForms])
useEffect(() => {
if (currentChatInstanceRef.current)
@@ -118,15 +72,11 @@
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
- useEffect(() => {
- setIsResponding(respondingState)
- }, [respondingState, setIsResponding])
-
const doSend: OnSend = useCallback((message, files, isRegenerate = false, parentAnswer: ChatItem | null = null) => {
const data: any = {
query: message,
files,
- inputs: currentConversationId ? currentConversationInputs : newConversationInputs,
+ inputs: currentConversationId ? currentConversationItem?.inputs : newConversationInputs,
conversation_id: currentConversationId,
parent_message_id: (isRegenerate ? parentAnswer?.id : getLastAnswer(chatList)?.id) || null,
}
@@ -140,85 +90,59 @@
isPublicAPI: !isInstalledApp,
},
)
- }, [chatList, handleNewConversationCompleted, handleSend, currentConversationId, currentConversationInputs, newConversationInputs, isInstalledApp, appId])
+ }, [
+ chatList,
+ handleNewConversationCompleted,
+ handleSend,
+ currentConversationId,
+ currentConversationItem,
+ newConversationInputs,
+ isInstalledApp,
+ appId,
+ ])
- const doRegenerate = useCallback((chatItem: ChatItemInTree, editedQuestion?: { message: string, files?: FileEntity[] }) => {
- const question = editedQuestion ? chatItem : chatList.find(item => item.id === chatItem.parentMessageId)!
+ const doRegenerate = useCallback((chatItem: ChatItemInTree) => {
+ const question = chatList.find(item => item.id === chatItem.parentMessageId)!
const parentAnswer = chatList.find(item => item.id === question.parentMessageId)
- doSend(editedQuestion ? editedQuestion.message : question.content,
- editedQuestion ? editedQuestion.files : question.message_files,
- true,
- isValidGeneratedAnswer(parentAnswer) ? parentAnswer : null,
- )
+ doSend(question.content, question.message_files, true, isValidGeneratedAnswer(parentAnswer) ? parentAnswer : null)
}, [chatList, doSend])
- const messageList = useMemo(() => {
- if (currentConversationId)
- return chatList
- return chatList.filter(item => !item.isOpeningStatement)
- }, [chatList, currentConversationId])
-
- const [collapsed, setCollapsed] = useState(!!currentConversationId)
-
const chatNode = useMemo(() => {
- if (!inputsForms.length)
- return null
- if (isMobile) {
- if (!currentConversationId)
- return <InputsForm collapsed={collapsed} setCollapsed={setCollapsed} />
- return null
- }
- else {
- return <InputsForm collapsed={collapsed} setCollapsed={setCollapsed} />
- }
- }, [inputsForms.length, isMobile, currentConversationId, collapsed])
-
- const welcome = useMemo(() => {
- const welcomeMessage = chatList.find(item => item.isOpeningStatement)
- if (respondingState)
- return null
- if (currentConversationId)
- return null
- if (!welcomeMessage)
- return null
- if (!collapsed && inputsForms.length > 0)
- return null
- if (welcomeMessage.suggestedQuestions && welcomeMessage.suggestedQuestions?.length > 0) {
+ if (inputsForms.length) {
return (
- <div className='flex min-h-[50vh] items-center justify-center px-4 py-12'>
- <div className='flex max-w-[720px] grow gap-4'>
- <AppIcon
- size='xl'
- iconType={appData?.site.icon_type}
- icon={appData?.site.icon}
- background={appData?.site.icon_background}
- imageUrl={appData?.site.icon_url}
- />
- <div className='w-0 grow'>
- <div className='body-lg-regular grow rounded-2xl bg-chat-bubble-bg px-4 py-3 text-text-primary'>
- <Markdown content={welcomeMessage.content} />
- <SuggestedQuestions item={welcomeMessage} />
+ <>
+ <Header
+ isMobile={isMobile}
+ title={currentConversationItem?.name || ''}
+ />
+ {
+ !currentConversationId && (
+ <div className={`mx-auto w-full max-w-[720px] ${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>
- </div>
- </div>
- </div>
+ )
+ }
+ </>
)
}
+
return (
- <div className={cn('flex h-[50vh] flex-col items-center justify-center gap-3 py-12')}>
- <AppIcon
- size='xl'
- iconType={appData?.site.icon_type}
- icon={appData?.site.icon}
- background={appData?.site.icon_background}
- imageUrl={appData?.site.icon_url}
- />
- <div className='max-w-[768px] px-4'>
- <Markdown className='!body-2xl-regular !text-text-tertiary' content={welcomeMessage.content} />
- </div>
- </div>
+ <Header
+ isMobile={isMobile}
+ title={currentConversationItem?.name || ''}
+ />
)
- }, [appData?.site.icon, appData?.site.icon_background, appData?.site.icon_type, appData?.site.icon_url, chatList, collapsed, currentConversationId, inputsForms.length, respondingState])
+ }, [
+ currentConversationId,
+ inputsForms,
+ currentConversationItem,
+ isMobile,
+ ])
const answerIcon = (appData?.site && appData.site.use_icon_as_answer_icon)
? <AnswerIcon
@@ -231,27 +155,22 @@
return (
<div
- className='h-full overflow-hidden bg-chatbot-bg'
+ className='h-full bg-chatbot-bg overflow-hidden'
>
<Chat
appData={appData}
config={appConfig}
- chatList={messageList}
- isResponding={respondingState}
- chatContainerInnerClassName={`mx-auto pt-6 w-full max-w-[768px] ${isMobile && 'px-4'}`}
+ chatList={chatList}
+ isResponding={isResponding}
+ chatContainerInnerClassName={`mx-auto pt-6 w-full max-w-[720px] ${isMobile && 'px-4'}`}
chatFooterClassName='pb-4'
- chatFooterInnerClassName={`mx-auto w-full max-w-[768px] ${isMobile ? 'px-2' : 'px-4'}`}
+ chatFooterInnerClassName={`mx-auto w-full max-w-[720px] ${isMobile && 'px-4'}`}
onSend={doSend}
- inputs={currentConversationId ? currentConversationInputs as any : newConversationInputs}
+ inputs={currentConversationId ? currentConversationItem?.inputs as any : newConversationInputs}
inputsForm={inputsForms}
onRegenerate={doRegenerate}
onStopResponding={handleStop}
- chatNode={
- <>
- {chatNode}
- {welcome}
- </>
- }
+ chatNode={chatNode}
allToolIcons={appMeta?.tool_icons || {}}
onFeedback={handleFeedback}
suggestedQuestions={suggestedQuestions}
@@ -259,9 +178,6 @@
hideProcessDetail
themeBuilder={themeBuilder}
switchSibling={siblingMessageId => setTargetMessageId(siblingMessageId)}
- inputDisabled={inputDisabled}
- isMobile={isMobile}
- sidebarCollapseState={sidebarCollapseState}
/>
</div>
)
--
Gitblit v1.8.0