mirror of
https://github.com/langgenius/dify.git
synced 2026-07-25 13:38:31 +08:00
184 lines
5.4 KiB
TypeScript
184 lines
5.4 KiB
TypeScript
'use client'
|
|
import type { FC } from 'react'
|
|
import type { TextGenerationTranslate } from '../types'
|
|
import type { PromptConfig } from '@/models/debug'
|
|
import type { SiteInfo } from '@/models/share'
|
|
import type { AppSourceType } from '@/service/share'
|
|
import type { VisionFile, VisionSettings } from '@/types/app'
|
|
import { Button } from '@langgenius/dify-ui/button'
|
|
import { toast } from '@langgenius/dify-ui/toast'
|
|
import { useCallback } from 'react'
|
|
import * as React from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import TextGenerationRes from '@/app/components/app/text-generate/item'
|
|
import Loading from '@/app/components/base/loading'
|
|
import NoData from '@/app/components/share/text-generation/no-data'
|
|
import { useResultRunState } from './hooks/use-result-run-state'
|
|
import { useResultSender } from './hooks/use-result-sender'
|
|
|
|
type IResultProps = {
|
|
isWorkflow: boolean
|
|
isCallBatchAPI: boolean
|
|
isPC: boolean
|
|
isMobile: boolean
|
|
appSourceType: AppSourceType
|
|
appId?: string
|
|
isError: boolean
|
|
isShowTextToSpeech: boolean
|
|
promptConfig: PromptConfig | null
|
|
moreLikeThisEnabled: boolean
|
|
inputs: Record<string, any>
|
|
controlSend?: number
|
|
controlRetry?: number
|
|
controlStopResponding?: number
|
|
onShowRes: () => void
|
|
handleSaveMessage: (messageId: string) => void
|
|
taskId?: number
|
|
onCompleted: (completionRes: string, taskId?: number, success?: boolean) => void
|
|
visionConfig: VisionSettings
|
|
completionFiles: VisionFile[]
|
|
siteInfo: SiteInfo | null
|
|
onRunStart: () => void
|
|
onRunControlChange?: (
|
|
control: {
|
|
onStop: () => Promise<void> | void
|
|
isStopping: boolean
|
|
} | null,
|
|
) => void
|
|
hideInlineStopButton?: boolean
|
|
}
|
|
const Result: FC<IResultProps> = ({
|
|
isWorkflow,
|
|
isCallBatchAPI,
|
|
isPC,
|
|
isMobile,
|
|
appSourceType,
|
|
appId,
|
|
isError,
|
|
isShowTextToSpeech,
|
|
promptConfig,
|
|
moreLikeThisEnabled,
|
|
inputs,
|
|
controlSend,
|
|
controlRetry,
|
|
controlStopResponding,
|
|
onShowRes,
|
|
handleSaveMessage,
|
|
taskId,
|
|
onCompleted,
|
|
visionConfig,
|
|
completionFiles,
|
|
siteInfo,
|
|
onRunStart,
|
|
onRunControlChange,
|
|
hideInlineStopButton = false,
|
|
}) => {
|
|
const { t } = useTranslation()
|
|
const translateResultKey = useCallback<TextGenerationTranslate>(
|
|
(selector, options) => t(selector, options),
|
|
[t],
|
|
)
|
|
const notify = useCallback(
|
|
({ type, message }: { type: 'error' | 'info' | 'success' | 'warning'; message: string }) => {
|
|
toast(message, { type })
|
|
},
|
|
[],
|
|
)
|
|
const runState = useResultRunState({
|
|
appId,
|
|
appSourceType,
|
|
controlStopResponding,
|
|
isWorkflow,
|
|
notify,
|
|
onRunControlChange,
|
|
})
|
|
const { handleSend } = useResultSender({
|
|
appId,
|
|
appSourceType,
|
|
completionFiles,
|
|
controlRetry,
|
|
controlSend,
|
|
inputs,
|
|
isCallBatchAPI,
|
|
isPC,
|
|
isWorkflow,
|
|
notify,
|
|
onCompleted,
|
|
onRunStart,
|
|
onShowRes,
|
|
promptConfig,
|
|
runState,
|
|
t: translateResultKey,
|
|
taskId,
|
|
visionConfig,
|
|
})
|
|
const isNoData = !runState.completionRes
|
|
const renderTextGenerationRes = () => (
|
|
<>
|
|
{!hideInlineStopButton && runState.isResponding && runState.currentTaskId && (
|
|
<div className={`mb-3 flex ${isPC ? 'justify-end' : 'justify-center'}`}>
|
|
<Button variant="secondary" disabled={runState.isStopping} onClick={runState.handleStop}>
|
|
{runState.isStopping ? (
|
|
<span aria-hidden className="mr-[5px] i-ri-loader-2-line h-3.5 w-3.5 animate-spin" />
|
|
) : (
|
|
<span aria-hidden className="mr-[5px] i-ri-stop-circle-fill h-3.5 w-3.5" />
|
|
)}
|
|
<span className="text-xs font-normal">
|
|
{t(($) => $['operation.stopResponding'], { ns: 'appDebug' })}
|
|
</span>
|
|
</Button>
|
|
</div>
|
|
)}
|
|
<TextGenerationRes
|
|
isWorkflow={isWorkflow}
|
|
workflowProcessData={runState.workflowProcessData}
|
|
isError={isError}
|
|
onRetry={handleSend}
|
|
content={runState.completionRes}
|
|
messageId={runState.messageId}
|
|
isInWebApp
|
|
moreLikeThis={moreLikeThisEnabled}
|
|
onFeedback={runState.handleFeedback}
|
|
feedback={runState.feedback}
|
|
onSave={handleSaveMessage}
|
|
isMobile={isMobile}
|
|
appSourceType={appSourceType}
|
|
installedAppId={appId}
|
|
// isLoading={isCallBatchAPI ? (!completionRes && isResponding) : false}
|
|
isLoading={false}
|
|
taskId={isCallBatchAPI ? ((taskId as number) < 10 ? `0${taskId}` : `${taskId}`) : undefined}
|
|
controlClearMoreLikeThis={runState.controlClearMoreLikeThis}
|
|
isShowTextToSpeech={isShowTextToSpeech}
|
|
hideProcessDetail
|
|
siteInfo={siteInfo}
|
|
/>
|
|
</>
|
|
)
|
|
return (
|
|
<>
|
|
{!isCallBatchAPI &&
|
|
!isWorkflow &&
|
|
(runState.isResponding && !runState.completionRes ? (
|
|
<div className="flex size-full items-center justify-center">
|
|
<Loading type="area" />
|
|
</div>
|
|
) : (
|
|
<>{isNoData ? <NoData /> : renderTextGenerationRes()}</>
|
|
))}
|
|
{!isCallBatchAPI &&
|
|
isWorkflow &&
|
|
(runState.isResponding && !runState.workflowProcessData ? (
|
|
<div className="flex size-full items-center justify-center">
|
|
<Loading type="area" />
|
|
</div>
|
|
) : !runState.workflowProcessData ? (
|
|
<NoData />
|
|
) : (
|
|
renderTextGenerationRes()
|
|
))}
|
|
{isCallBatchAPI && renderTextGenerationRes()}
|
|
</>
|
|
)
|
|
}
|
|
export default React.memo(Result)
|