mirror of
https://gitee.com/dify_ai/dify.git
synced 2024-12-02 11:18:19 +08:00
parent
9adbeadeec
commit
fb62017e50
@ -12,13 +12,12 @@ import AppUnavailable from '../../base/app-unavailable'
|
||||
import useConversation from './hooks/use-conversation'
|
||||
import s from './style.module.css'
|
||||
import { ToastContext } from '@/app/components/base/toast'
|
||||
import Sidebar from '@/app/components/share/chatbot/sidebar'
|
||||
import ConfigScene from '@/app/components/share/chatbot/config-scence'
|
||||
import Header from '@/app/components/share/header'
|
||||
import { /* delConversation, */ fetchAppInfo, fetchAppParams, fetchChatList, fetchConversations, fetchSuggestedQuestions, pinConversation, sendChatMessage, stopChatMessageResponding, unpinConversation, updateFeedback } from '@/service/share'
|
||||
import { fetchAppInfo, fetchAppParams, fetchChatList, fetchConversations, fetchSuggestedQuestions, sendChatMessage, stopChatMessageResponding, updateFeedback } from '@/service/share'
|
||||
import type { ConversationItem, SiteInfo } from '@/models/share'
|
||||
import type { PromptConfig, SuggestedQuestionsAfterAnswerConfig } from '@/models/debug'
|
||||
import type { Feedbacktype, IChatItem } from '@/app/components/app/chat'
|
||||
import type { Feedbacktype, IChatItem } from '@/app/components/app/chat/type'
|
||||
import Chat from '@/app/components/app/chat'
|
||||
import { changeLanguage } from '@/i18n/i18next-config'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
@ -26,7 +25,7 @@ import Loading from '@/app/components/base/loading'
|
||||
import { replaceStringWithValues } from '@/app/components/app/configuration/prompt-value-panel'
|
||||
import { userInputsFormToPromptVariables } from '@/utils/model-config'
|
||||
import type { InstalledApp } from '@/models/explore'
|
||||
// import Confirm from '@/app/components/base/confirm'
|
||||
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
|
||||
|
||||
export type IMainProps = {
|
||||
isInstalledApp?: boolean
|
||||
@ -52,8 +51,6 @@ const Main: FC<IMainProps> = ({
|
||||
const [promptConfig, setPromptConfig] = useState<PromptConfig | null>(null)
|
||||
const [inited, setInited] = useState<boolean>(false)
|
||||
const [plan, setPlan] = useState<string>('basic') // basic/plus/pro
|
||||
// in mobile, show sidebar by click button
|
||||
const [isShowSidebar, { setTrue: showSidebar, setFalse: hideSidebar }] = useBoolean(false)
|
||||
// Can Use metadata(https://beta.nextjs.org/docs/api-reference/metadata) to set title. But it only works in server side client.
|
||||
useEffect(() => {
|
||||
if (siteInfo?.title) {
|
||||
@ -124,37 +121,6 @@ const Main: FC<IMainProps> = ({
|
||||
|
||||
setControlUpdateConversationList(Date.now())
|
||||
}
|
||||
|
||||
const handlePin = async (id: string) => {
|
||||
await pinConversation(isInstalledApp, installedAppInfo?.id, id)
|
||||
notify({ type: 'success', message: t('common.api.success') })
|
||||
noticeUpdateList()
|
||||
}
|
||||
|
||||
const handleUnpin = async (id: string) => {
|
||||
await unpinConversation(isInstalledApp, installedAppInfo?.id, id)
|
||||
notify({ type: 'success', message: t('common.api.success') })
|
||||
noticeUpdateList()
|
||||
}
|
||||
const [isShowConfirm, { setTrue: showConfirm, setFalse: hideConfirm }] = useBoolean(false)
|
||||
const [toDeleteConversationId, setToDeleteConversationId] = useState('')
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
setToDeleteConversationId(id)
|
||||
hideSidebar() // mobile
|
||||
showConfirm()
|
||||
}
|
||||
|
||||
// const didDelete = async () => {
|
||||
// await delConversation(isInstalledApp, installedAppInfo?.id, toDeleteConversationId)
|
||||
// notify({ type: 'success', message: t('common.api.success') })
|
||||
// hideConfirm()
|
||||
// if (currConversationId === toDeleteConversationId)
|
||||
// handleConversationIdChange('-1')
|
||||
|
||||
// noticeUpdateList()
|
||||
// }
|
||||
|
||||
const [suggestedQuestionsAfterAnswerConfig, setSuggestedQuestionsAfterAnswerConfig] = useState<SuggestedQuestionsAfterAnswerConfig | null>(null)
|
||||
const [speechToTextConfig, setSpeechToTextConfig] = useState<SuggestedQuestionsAfterAnswerConfig | null>(null)
|
||||
|
||||
@ -235,20 +201,6 @@ const Main: FC<IMainProps> = ({
|
||||
}
|
||||
useEffect(handleConversationSwitch, [currConversationId, inited])
|
||||
|
||||
const handleConversationIdChange = (id: string) => {
|
||||
if (id === '-1') {
|
||||
createNewChat()
|
||||
setConversationIdChangeBecauseOfNew(true)
|
||||
}
|
||||
else {
|
||||
setConversationIdChangeBecauseOfNew(false)
|
||||
}
|
||||
// trigger handleConversationSwitch
|
||||
setCurrConversationId(id, appId)
|
||||
setIsShowSuggestion(false)
|
||||
hideSidebar()
|
||||
}
|
||||
|
||||
/*
|
||||
* chat info. chat is under conversation.
|
||||
*/
|
||||
@ -416,6 +368,7 @@ const Main: FC<IMainProps> = ({
|
||||
const [suggestQuestions, setSuggestQuestions] = useState<string[]>([])
|
||||
const [messageTaskId, setMessageTaskId] = useState('')
|
||||
const [hasStopResponded, setHasStopResponded, getHasStopResponded] = useGetState(false)
|
||||
const [shouldReload, setShouldReload] = useState(false)
|
||||
|
||||
const handleSend = async (message: string) => {
|
||||
if (isResponsing) {
|
||||
@ -500,7 +453,9 @@ const Main: FC<IMainProps> = ({
|
||||
setIsShowSuggestion(true)
|
||||
}
|
||||
},
|
||||
onError() {
|
||||
onError(errorMessage, errorCode) {
|
||||
if (['provider_not_initialize', 'completion_request_error'].includes(errorCode as string))
|
||||
setShouldReload(true)
|
||||
setResponsingFalse()
|
||||
// role back placeholder answer
|
||||
setChatList(produce(getChatList(), (draft) => {
|
||||
@ -525,31 +480,11 @@ const Main: FC<IMainProps> = ({
|
||||
notify({ type: 'success', message: t('common.api.success') })
|
||||
}
|
||||
|
||||
const renderSidebar = () => {
|
||||
if (!appId || !siteInfo || !promptConfig)
|
||||
return null
|
||||
return (
|
||||
<Sidebar
|
||||
list={conversationList}
|
||||
isClearConversationList={isClearConversationList}
|
||||
pinnedList={pinnedConversationList}
|
||||
isClearPinnedConversationList={isClearPinnedConversationList}
|
||||
onMoreLoaded={onMoreLoaded}
|
||||
onPinnedMoreLoaded={onPinnedMoreLoaded}
|
||||
isNoMore={!hasMore}
|
||||
isPinnedNoMore={!hasPinnedMore}
|
||||
onCurrentIdChange={handleConversationIdChange}
|
||||
currentId={currConversationId}
|
||||
copyRight={siteInfo.copyright || siteInfo.title}
|
||||
isInstalledApp={isInstalledApp}
|
||||
installedAppId={installedAppInfo?.id}
|
||||
siteInfo={siteInfo}
|
||||
onPin={handlePin}
|
||||
onUnpin={handleUnpin}
|
||||
controlUpdateList={controlUpdateConversationList}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
)
|
||||
const handleReload = () => {
|
||||
setCurrConversationId('-1', appId, false)
|
||||
setChatNotStarted()
|
||||
setShouldReload(false)
|
||||
createNewChat()
|
||||
}
|
||||
|
||||
const difyIcon = (
|
||||
@ -571,24 +506,9 @@ const Main: FC<IMainProps> = ({
|
||||
icon_background={siteInfo.icon_background}
|
||||
isEmbedScene={true}
|
||||
isMobile={isMobile}
|
||||
// onShowSideBar={showSidebar}
|
||||
// onCreateNewChat={() => handleConversationIdChange('-1')}
|
||||
/>
|
||||
|
||||
<div className={'flex bg-white overflow-hidden'}>
|
||||
{/* sidebar */}
|
||||
{/* {!isMobile && renderSidebar()} */}
|
||||
{/* {isMobile && isShowSidebar && (
|
||||
<div className='fixed inset-0 z-50'
|
||||
style={{ backgroundColor: 'rgba(35, 56, 118, 0.2)' }}
|
||||
onClick={hideSidebar}
|
||||
>
|
||||
<div className='inline-block' onClick={e => e.stopPropagation()}>
|
||||
{renderSidebar()}
|
||||
</div>
|
||||
</div>
|
||||
)} */}
|
||||
{/* main */}
|
||||
<div className={cn(
|
||||
isInstalledApp ? s.installedApp : 'h-[calc(100vh_-_3rem)]',
|
||||
'flex-grow flex flex-col overflow-y-auto',
|
||||
@ -606,7 +526,22 @@ const Main: FC<IMainProps> = ({
|
||||
onInputsChange={setCurrInputs}
|
||||
plan={plan}
|
||||
></ConfigScene>
|
||||
|
||||
{
|
||||
shouldReload && (
|
||||
<div className='flex items-center justify-between mb-5 px-4 py-2 bg-[#FEF0C7]'>
|
||||
<div className='flex items-center text-xs font-medium text-[#DC6803]'>
|
||||
<AlertTriangle className='mr-2 w-4 h-4' />
|
||||
{t('share.chat.temporarySystemIssue')}
|
||||
</div>
|
||||
<div
|
||||
className='flex items-center px-3 h-7 bg-white shadow-xs rounded-md text-xs font-medium text-gray-700 cursor-pointer'
|
||||
onClick={handleReload}
|
||||
>
|
||||
{t('share.chat.tryToSolve')}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
hasSetInputs && (
|
||||
<div className={cn(doShowSuggestion ? 'pb-[140px]' : (isResponsing ? 'pb-[113px]' : 'pb-[76px]'), 'relative grow h-[200px] pc:w-[794px] max-w-full mobile:w-full mx-auto mb-3.5 overflow-hidden')}>
|
||||
|
@ -27,6 +27,8 @@ const translation = {
|
||||
title: 'Delete conversation',
|
||||
content: 'Are you sure you want to delete this conversation?',
|
||||
},
|
||||
tryToSolve: 'Try to solve',
|
||||
temporarySystemIssue: 'Sorry, temporary system issue.',
|
||||
},
|
||||
generation: {
|
||||
tabs: {
|
||||
|
@ -23,6 +23,8 @@ const translation = {
|
||||
title: '删除对话',
|
||||
content: '您确定要删除此对话吗?',
|
||||
},
|
||||
tryToSolve: '尝试解决',
|
||||
temporarySystemIssue: '抱歉,临时系统问题。',
|
||||
},
|
||||
generation: {
|
||||
tabs: {
|
||||
|
@ -28,12 +28,13 @@ export type IOnDataMoreInfo = {
|
||||
taskId?: string
|
||||
messageId: string
|
||||
errorMessage?: string
|
||||
errorCode?: string
|
||||
}
|
||||
|
||||
export type IOnData = (message: string, isFirstMessage: boolean, moreInfo: IOnDataMoreInfo) => void
|
||||
export type IOnThought = (though: ThoughtItem) => void
|
||||
export type IOnCompleted = (hasError?: boolean) => void
|
||||
export type IOnError = (msg: string) => void
|
||||
export type IOnError = (msg: string, code?: string) => void
|
||||
|
||||
type IOtherOptions = {
|
||||
isPublicAPI?: boolean
|
||||
@ -102,6 +103,7 @@ const handleStream = (response: any, onData: IOnData, onCompleted?: IOnCompleted
|
||||
conversationId: undefined,
|
||||
messageId: '',
|
||||
errorMessage: bufferObj.message,
|
||||
errorCode: bufferObj.code,
|
||||
})
|
||||
hasError = true
|
||||
onCompleted && onCompleted(true)
|
||||
@ -345,7 +347,7 @@ export const ssePost = (url: string, fetchOptions: any, { isPublicAPI = false, o
|
||||
return handleStream(res, (str: string, isFirstMessage: boolean, moreInfo: IOnDataMoreInfo) => {
|
||||
if (moreInfo.errorMessage) {
|
||||
// debugger
|
||||
onError?.(moreInfo.errorMessage)
|
||||
onError?.(moreInfo.errorMessage, moreInfo.errorCode)
|
||||
if (moreInfo.errorMessage !== 'AbortError: The user aborted a request.')
|
||||
Toast.notify({ type: 'error', message: moreInfo.errorMessage })
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user