SarahXia0405's picture
Update web/src/components/Message.tsx
037dc25 verified
// web/src/components/Message.tsx
import React from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import type { Message as MessageType, LearningMode } from "../App";
interface MessageProps {
message: MessageType;
// existing props you are already passing in ChatArea
showSenderInfo?: boolean;
userId?: string;
isLoggedIn: boolean;
learningMode: LearningMode;
docType?: string;
lastUserText?: string;
}
export function Message({
message,
showSenderInfo,
userId,
isLoggedIn,
learningMode,
docType,
lastUserText,
}: MessageProps) {
const isUser = message.role === "user";
// If you already have avatar / sender rendering logic, keep it.
// The only critical change is content rendering below.
return (
<div className={`flex gap-3 ${isUser ? "justify-end" : "justify-start"}`}>
{!isUser && (
<div className="w-8 h-8 rounded-full bg-gradient-to-br from-purple-500 to-blue-500 flex items-center justify-center flex-shrink-0">
<span className="text-white text-sm">C</span>
</div>
)}
<div className={`max-w-[85%] ${isUser ? "text-right" : "text-left"}`}>
{/* Optional sender info (group mode) */}
{showSenderInfo && message.sender && !isUser && (
<div className="text-xs text-muted-foreground mb-1">
{message.sender.name}
</div>
)}
<div
className={[
"rounded-2xl px-4 py-3 border",
isUser
? "bg-primary text-primary-foreground border-primary/20"
: "bg-muted text-foreground border-border",
].join(" ")}
>
{/* ✅ THE FIX: render markdown instead of plain text */}
<ReactMarkdown
remarkPlugins={[remarkGfm]}
className={[
// prose improves markdown typography; max-w-none prevents narrow column
"prose prose-sm max-w-none",
// keep readable in chat bubble
"prose-p:my-2 prose-li:my-1 prose-ul:my-2 prose-ol:my-2",
// make headings not too large inside bubble
"prose-h1:text-base prose-h2:text-base prose-h3:text-sm",
// avoid code blocks overflowing
"prose-pre:overflow-x-auto",
// inherit bubble colors
isUser ? "prose-invert" : "",
].join(" ")}
>
{message.content || ""}
</ReactMarkdown>
{/* If you already render references, keep your original block here */}
{message.references && message.references.length > 0 && (
<div className="mt-3 pt-3 border-t border-border/50 text-xs text-muted-foreground space-y-1">
<div className="font-medium">References</div>
{message.references.map((r, idx) => (
<div key={idx} className="truncate">
{r}
</div>
))}
</div>
)}
{/* If you already have feedback buttons inside Message, keep them here.
Do not change logic—only keep UI. */}
</div>
</div>
{isUser && (
<div className="w-8 h-8 rounded-full bg-primary flex items-center justify-center flex-shrink-0">
<span className="text-primary-foreground text-sm">U</span>
</div>
)}
</div>
);
}