Spaces:
Sleeping
Sleeping
| import { formatMarkdown, linkify } from '../../utils/markdown.jsx' | |
| import { API_BASE } from '../../utils/constants.js' | |
| function cleanContent(content) { | |
| if (!content) return '' | |
| return content.replace(/\[System Note:[\s\S]*?\]/g, '').trim() | |
| } | |
| function resolveImageUrl(url) { | |
| if (!url) return null | |
| if (url.startsWith('data:') || url.startsWith('http://') || url.startsWith('https://')) return url | |
| return `${API_BASE}${url}` | |
| } | |
| export default function MessageBubble({ message, onImageClick }) { | |
| const imgSrc = resolveImageUrl(message.image_url) || message.image | |
| const displayContent = cleanContent(message.content) | |
| if (message.role === 'assistant' && !displayContent && !imgSrc) { | |
| return null | |
| } | |
| return ( | |
| <div key={message.id} className={`message-bubble ${message.role}`}> | |
| {imgSrc && ( | |
| <div style={{ marginBottom: '8px' }}> | |
| <img | |
| src={imgSrc} | |
| alt="" | |
| onClick={() => onImageClick?.(imgSrc)} | |
| style={{ | |
| maxWidth: '120px', | |
| maxHeight: '100px', | |
| borderRadius: '6px', | |
| border: '1px solid #e5e7eb', | |
| objectFit: 'cover', | |
| cursor: 'pointer', | |
| }} | |
| /> | |
| </div> | |
| )} | |
| <div className="message-text"> | |
| {message.role === 'assistant' ? formatMarkdown(displayContent) : linkify(displayContent)} | |
| </div> | |
| </div> | |
| ) | |
| } | |