File size: 3,407 Bytes
037dc25
 
 
 
 
 
760b33c
 
 
60f8c0d
037dc25
 
 
d76cdcf
60f8c0d
037dc25
d76cdcf
 
60f8c0d
 
 
037dc25
60f8c0d
d76cdcf
60f8c0d
d76cdcf
037dc25
60f8c0d
037dc25
760b33c
037dc25
 
760b33c
037dc25
 
760b33c
 
 
037dc25
760b33c
037dc25
 
 
 
 
760b33c
 
 
 
037dc25
 
 
 
 
 
760b33c
037dc25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
760b33c
037dc25
760b33c
037dc25
 
 
760b33c
 
 
037dc25
 
 
760b33c
 
 
 
60f8c0d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// 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>
  );
}