Files
vocero-client/vocero-frontend/src/components/Bubbles.tsx
T
alvaro abd03ed07d refactor: rename API and frontend projects to Vocero
Rename the project directories, Python distribution and import package, and npm package. Update launcher, Docker, tooling, tests, lockfiles, and documentation while preserving existing API contracts.

Make AGENTS.md self-contained and remove external skill and workflow references.
2026-10-06 19:26:55 -03:00

46 lines
1.4 KiB
TypeScript

import { memo, useEffect, useState } from "react";
import { renderMarkdown, type Message } from "../lib/messages";
function Bubble({ message, userName }: { message: Message; userName: string }) {
const [expiredText, setExpiredText] = useState<string | null>(null);
useEffect(() => {
if (message.partial) {
return;
}
const timer = setTimeout(() => {
setExpiredText(message.text);
}, 5000);
return () => {
clearTimeout(timer);
};
}, [message.text, message.partial]);
if (expiredText === message.text) {
return null;
}
return (
<div className={`bubble ${message.role} in`}>
<div className="bubble-role">
{message.role === "user" ? userName : message.role === "tool" ? "Herramienta" : "Vocero"}
</div>
{message.role === "assistant" ? (
<div
className="bubble-body markdown-content"
dangerouslySetInnerHTML={{ __html: renderMarkdown(message.text) }}
/>
) : (
<div className="bubble-body">{message.role === "tool" ? message.toolName : message.text}</div>
)}
</div>
);
}
export const Bubbles = memo(function Bubbles({ messages, userName }: { messages: Message[]; userName: string }) {
return (
<div className="bubble-stack" aria-hidden="true">
{messages.slice(-3).map((message) => (
<Bubble key={message.id} message={message} userName={userName} />
))}
</div>
);
});