refactor(frontend): reuse ChatBubble for exploration drill-down
The drawer hand-rolled chat bubbles duplicating ChatBubble's shape. Add a mirrored layout prop (virtual user left, target right) and reuse the shared component.
This commit is contained in:
parent
ef4c094082
commit
b26c432f3a
@ -7,9 +7,11 @@ interface ChatBubbleProps {
|
||||
content: ReactNode
|
||||
meta?: ReactNode
|
||||
pending?: boolean
|
||||
/** 镜像布局:探索下钻里虚拟用户居左、被评对象居右(与常规聊天相反) */
|
||||
mirrored?: boolean
|
||||
}
|
||||
|
||||
export default function ChatBubble({ role, content, meta, pending }: ChatBubbleProps) {
|
||||
export default function ChatBubble({ role, content, meta, pending, mirrored }: ChatBubbleProps) {
|
||||
const isUser = role === 'user'
|
||||
const isAgent = role === 'agent'
|
||||
const isSystem = role === 'system'
|
||||
@ -17,8 +19,9 @@ export default function ChatBubble({ role, content, meta, pending }: ChatBubbleP
|
||||
const bg = isUser ? colors.chatUser : isAgent ? colors.chatAgent : colors.chatSystemError
|
||||
const border = isSystem ? '#ffccc7' : 'transparent'
|
||||
const textColor = isSystem ? '#cf1322' : colors.text
|
||||
const align = isUser ? 'flex-end' : 'flex-start'
|
||||
const radius = isUser ? '10px 10px 2px 10px' : '10px 10px 10px 2px'
|
||||
const alignRight = isSystem ? false : isUser ? !mirrored : !!mirrored
|
||||
const align = alignRight ? 'flex-end' : 'flex-start'
|
||||
const radius = alignRight ? '10px 10px 2px 10px' : '10px 10px 10px 2px'
|
||||
|
||||
const icon = isUser
|
||||
? <UserOutlined style={{ color: colors.primary }} />
|
||||
@ -29,7 +32,7 @@ export default function ChatBubble({ role, content, meta, pending }: ChatBubbleP
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', justifyContent: align, marginBottom: 6 }}>
|
||||
<div style={{ maxWidth: '82%', display: 'flex', flexDirection: 'column', alignItems: isUser ? 'flex-end' : 'flex-start', gap: 2 }}>
|
||||
<div style={{ maxWidth: '82%', display: 'flex', flexDirection: 'column', alignItems: alignRight ? 'flex-end' : 'flex-start', gap: 2 }}>
|
||||
<div style={{ display: 'flex', gap: 4, alignItems: 'center', fontSize: 11, color: colors.textMuted }}>
|
||||
{!isUser && icon}
|
||||
<span>{label}</span>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Collapse, Empty, Space, Spin, Tag } from 'antd'
|
||||
import { UserOutlined, RobotOutlined } from '@ant-design/icons'
|
||||
import ChatBubble from './ChatBubble'
|
||||
import {
|
||||
explorationApi,
|
||||
type ExplorationMessage,
|
||||
@ -78,33 +78,15 @@ function SessionDetail({ session, messages }: {
|
||||
<Empty description="暂无对话记录" image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
||||
)}
|
||||
{messages && messages.map((m) => (
|
||||
<div
|
||||
<ChatBubble
|
||||
key={m.id}
|
||||
style={{ display: 'flex', justifyContent: m.role === 'user' ? 'flex-start' : 'flex-end', marginBottom: 8 }}
|
||||
>
|
||||
{m.role === 'user' ? (
|
||||
<div style={{
|
||||
background: colors.chatUser, padding: '8px 14px',
|
||||
borderRadius: '12px 12px 12px 2px', maxWidth: '70%',
|
||||
fontSize: 13, lineHeight: 1.6,
|
||||
}}>
|
||||
<UserOutlined style={{ marginRight: 6, color: '#1677ff' }} />
|
||||
{m.content}
|
||||
</div>
|
||||
) : (
|
||||
<div style={{
|
||||
background: colors.chatAgent, padding: '8px 14px',
|
||||
borderRadius: '12px 12px 2px 12px', maxWidth: '70%',
|
||||
fontSize: 13, lineHeight: 1.6,
|
||||
}}>
|
||||
<RobotOutlined style={{ marginRight: 6, color: '#52c41a' }} />
|
||||
{m.content}
|
||||
{m.latency_ms != null && (
|
||||
<span style={{ color: colors.textMuted, fontSize: 11, marginLeft: 8 }}>{m.latency_ms}ms</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
role={m.role === 'user' ? 'user' : 'agent'}
|
||||
mirrored
|
||||
content={m.content}
|
||||
meta={m.role !== 'user' && m.latency_ms != null ? (
|
||||
<span style={{ color: colors.textMuted, fontSize: 11 }}>{m.latency_ms}ms</span>
|
||||
) : undefined}
|
||||
/>
|
||||
))}
|
||||
|
||||
{experience && (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user