Spaces:
Running
Running
File size: 1,776 Bytes
4bae792 a7f19c4 4bae792 57f5158 4bae792 a7f19c4 4bae792 57f5158 4bae792 57f5158 4bae792 bbd714b a7f19c4 4bae792 | 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 | import { getUserColor } from "../../utils/userColor.js";
import ReactMarkdown from "react-markdown";
/**
* Render message content with @ mentions as styled tags
* Uses a simple color hash for unknown users instead of mock data
*/
export function renderMessageWithMentions(
content,
isDark,
onShowProfile,
isBot = false,
) {
if (!content) return content;
// Regex to match @username patterns (only letters, numbers, underscores - no spaces)
const mentionRegex = /@([a-zA-Z0-9À-ỹ_]+)/g;
const parts = [];
let lastIndex = 0;
let match;
while ((match = mentionRegex.exec(content)) !== null) {
// Add text before the mention
if (match.index > lastIndex) {
parts.push(
<span key={`text-${lastIndex}`}>
{content.substring(lastIndex, match.index)}
</span>,
);
}
// Extract the mentioned name
const mentionedName = match[1].trim();
// Get color for the mentioned user using the name-based hash
const mentionColor = getUserColor(mentionedName);
// Render the mention as colored text
parts.push(
<span
key={`mention-${match.index}`}
className="font-semibold cursor-pointer"
style={{
color: mentionColor,
}}
onClick={(e) => {
e.stopPropagation();
if (onShowProfile) {
onShowProfile(mentionedName);
}
}}
>
@{mentionedName}
</span>,
);
lastIndex = match.index + match[0].length;
}
// Add remaining text
if (lastIndex < content.length) {
parts.push(
<span key={`text-end-${lastIndex}`}>
<ReactMarkdown>{content.substring(lastIndex)}</ReactMarkdown>
</span>,
);
}
return parts.length > 0 ? parts : content;
}
|