initial
This commit is contained in:
56
apps/web/src/components/MessageBubble.tsx
Normal file
56
apps/web/src/components/MessageBubble.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { Message } from '@/api/types';
|
||||
import { ToolCallCard } from './ToolCallCard';
|
||||
import { CodeBlock, splitCodeBlocks } from './CodeBlock';
|
||||
|
||||
interface Props {
|
||||
message: Message;
|
||||
}
|
||||
|
||||
export function MessageBubble({ message }: Props) {
|
||||
if (message.role === 'tool') {
|
||||
return <ToolCallCard message={message} />;
|
||||
}
|
||||
|
||||
if (message.role === 'user') {
|
||||
return (
|
||||
<div className="flex justify-end">
|
||||
<div className="max-w-[80%] rounded-lg bg-primary text-primary-foreground px-3 py-2 text-sm whitespace-pre-wrap">
|
||||
{message.content}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const isStreaming = message.status === 'streaming';
|
||||
const failed = message.status === 'failed';
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
{message.tool_calls?.map((tc) => (
|
||||
<ToolCallCard key={tc.id} toolCall={tc} />
|
||||
))}
|
||||
{(message.content.length > 0 || (!message.tool_calls?.length && isStreaming)) && (
|
||||
<div className="max-w-[90%] text-sm leading-relaxed space-y-2">
|
||||
{splitCodeBlocks(message.content).map((seg, i) =>
|
||||
seg.kind === 'code' ? (
|
||||
<CodeBlock key={i} code={seg.value} lang={seg.lang} />
|
||||
) : (
|
||||
<div key={i} className="whitespace-pre-wrap">
|
||||
{seg.value}
|
||||
{isStreaming && i === splitCodeBlocks(message.content).length - 1 && (
|
||||
<span className="inline-block w-1.5 h-3.5 align-baseline bg-muted-foreground/60 animate-pulse ml-0.5" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
{message.content.length === 0 && isStreaming && (
|
||||
<span className="inline-block w-1.5 h-3.5 align-baseline bg-muted-foreground/60 animate-pulse" />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{failed && (
|
||||
<div className="text-xs text-destructive">message failed</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user