Files
test1/components/nova-sdk/message-list/message-item/user-interaction/index.tsx
2026-03-20 07:33:46 +00:00

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>
)
},
)