2026-05-07 02:41:01 +08:00
|
|
|
import { cn } from '@/lib/utils';
|
2026-05-07 03:22:15 +08:00
|
|
|
import { renderMarkdown } from '@/lib/markdown';
|
2026-05-07 02:41:01 +08:00
|
|
|
import type { Message } from '@/types';
|
|
|
|
|
|
|
|
|
|
export function ChatMessage({ message }: { message: Message }) {
|
|
|
|
|
const isUser = message.role === 'user';
|
2026-05-07 03:22:15 +08:00
|
|
|
const isEmpty = !message.content;
|
2026-05-07 02:41:01 +08:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className={cn('mb-4 flex', isUser ? 'justify-end' : 'justify-start')}>
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
2026-05-07 03:22:15 +08:00
|
|
|
'max-w-[80%] rounded-lg px-4 py-2.5',
|
|
|
|
|
isUser
|
|
|
|
|
? 'bg-zinc-800 text-zinc-100'
|
|
|
|
|
: 'bg-zinc-900 text-zinc-300 border border-zinc-800'
|
2026-05-07 02:41:01 +08:00
|
|
|
)}
|
|
|
|
|
>
|
2026-05-07 03:22:15 +08:00
|
|
|
{isEmpty ? (
|
|
|
|
|
<span className="text-zinc-600 italic text-xs">...</span>
|
|
|
|
|
) : isUser ? (
|
|
|
|
|
<p className="text-sm leading-relaxed whitespace-pre-wrap">{message.content}</p>
|
|
|
|
|
) : (
|
|
|
|
|
<div
|
|
|
|
|
className="markdown-body text-sm leading-relaxed"
|
|
|
|
|
dangerouslySetInnerHTML={{ __html: renderMarkdown(message.content) }}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-05-07 02:41:01 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|