84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
import { memo } from 'react'
|
|
import type { UserInteraction as UserInteractionData } from '../../../types'
|
|
import { InteractionWrapper } from './InteractionWrapper'
|
|
import { ChoiceInteraction } from './ChoiceInteraction'
|
|
import { BrowserTakeoverInteraction } from './BrowserTakeoverInteraction'
|
|
import { SlideFormInteraction } from './SlideFormInteraction'
|
|
|
|
export { InteractionWrapper } from './InteractionWrapper'
|
|
export { InteractionButtons } from './InteractionButtons'
|
|
export { ChoiceInteraction } from './ChoiceInteraction'
|
|
export { BrowserTakeoverInteraction } from './BrowserTakeoverInteraction'
|
|
export { SlideFormInteraction } from './SlideFormInteraction'
|
|
|
|
interface UserInteractionProps {
|
|
userInteraction: UserInteractionData
|
|
disabled?: boolean
|
|
isLatest?: boolean
|
|
onSendMessage?: (content: string) => void
|
|
}
|
|
|
|
/**
|
|
* 用户交互主入口组件
|
|
* 根据 userInteraction.type 分发到对应的交互子组件
|
|
*/
|
|
export const UserInteractionWidget = memo(
|
|
({ userInteraction, disabled, isLatest, onSendMessage }: UserInteractionProps) => {
|
|
const {
|
|
type,
|
|
content,
|
|
choice_options,
|
|
questions,
|
|
browser_type,
|
|
expected_user_action,
|
|
take_over_type,
|
|
messageTime,
|
|
} = userInteraction as UserInteractionData & { messageTime?: string }
|
|
|
|
let inner: React.ReactNode = null
|
|
|
|
// 浏览器接管交互:与 Remix 一致,优先根据 expected_user_action 判断
|
|
if (
|
|
expected_user_action === 'take_over_web_browser' ||
|
|
type === 'browser_takeover' ||
|
|
type === 'browser_use_takeover'
|
|
) {
|
|
if (take_over_type !== 'reback') {
|
|
inner = (
|
|
<BrowserTakeoverInteraction
|
|
disabled={disabled}
|
|
browser_type={browser_type}
|
|
onSendMessage={onSendMessage}
|
|
/>
|
|
)
|
|
}
|
|
} else if (choice_options?.length) {
|
|
inner = (
|
|
<ChoiceInteraction
|
|
choice_options={choice_options}
|
|
disabled={disabled}
|
|
onSendMessage={onSendMessage}
|
|
/>
|
|
)
|
|
} else if (questions?.length) {
|
|
inner = (
|
|
<SlideFormInteraction
|
|
questions={questions}
|
|
disabled={disabled}
|
|
messageTime={messageTime}
|
|
onSendMessage={onSendMessage}
|
|
/>
|
|
)
|
|
}
|
|
|
|
// 有文本内容或有交互子组件时才渲染
|
|
if (!inner && !content?.trim()) return null
|
|
|
|
return (
|
|
<InteractionWrapper content={content} isLatest={isLatest}>
|
|
{inner}
|
|
</InteractionWrapper>
|
|
)
|
|
},
|
|
)
|