feat(MessageRecord): 添加微信表情符号解析功能
新增 parseEmojiText 方法用于解析文本中的表情符号格式[表情名称],并将其替换为对应的表情图片。当表情不存在时保持原文本显示。修改了文本消息的渲染逻辑以支持表情显示。
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
|||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
|
import { ChatRecord, ContractData, weChatGroup } from "@/pages/pc/ckbox/data";
|
||||||
import { formatWechatTime, parseWeappMsgStr } from "@/utils/common";
|
import { formatWechatTime, parseWeappMsgStr } from "@/utils/common";
|
||||||
|
import { getEmojiPath } from "@/components/EmojiSeclection/wechatEmoji";
|
||||||
import styles from "./MessageRecord.module.scss";
|
import styles from "./MessageRecord.module.scss";
|
||||||
import { useWeChatStore } from "@/store/module/weChat/weChat";
|
import { useWeChatStore } from "@/store/module/weChat/weChat";
|
||||||
import { useWebSocketStore } from "@/store/module/websocket/websocket";
|
import { useWebSocketStore } from "@/store/module/websocket/websocket";
|
||||||
@@ -49,6 +50,56 @@ const MessageRecord: React.FC<MessageRecordProps> = ({ contract }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 解析表情包文字格式[表情名称]并替换为img标签
|
||||||
|
const parseEmojiText = (text: string): React.ReactNode[] => {
|
||||||
|
const emojiRegex = /\[([^\]]+)\]/g;
|
||||||
|
const parts: React.ReactNode[] = [];
|
||||||
|
let lastIndex = 0;
|
||||||
|
let match;
|
||||||
|
|
||||||
|
while ((match = emojiRegex.exec(text)) !== null) {
|
||||||
|
// 添加表情前的文字
|
||||||
|
if (match.index > lastIndex) {
|
||||||
|
parts.push(text.slice(lastIndex, match.index));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表情名称并查找对应路径
|
||||||
|
const emojiName = match[1];
|
||||||
|
const emojiPath = getEmojiPath(emojiName as any);
|
||||||
|
|
||||||
|
if (emojiPath) {
|
||||||
|
// 如果找到表情,添加img标签
|
||||||
|
parts.push(
|
||||||
|
<img
|
||||||
|
key={`emoji-${match.index}`}
|
||||||
|
src={emojiPath}
|
||||||
|
alt={emojiName}
|
||||||
|
className={styles.emojiImage}
|
||||||
|
style={{
|
||||||
|
width: "20px",
|
||||||
|
height: "20px",
|
||||||
|
verticalAlign: "middle",
|
||||||
|
margin: "0 2px",
|
||||||
|
display: "inline",
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 如果没找到表情,保持原文字
|
||||||
|
parts.push(match[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastIndex = emojiRegex.lastIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加剩余的文字
|
||||||
|
if (lastIndex < text.length) {
|
||||||
|
parts.push(text.slice(lastIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts;
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const prevMessages = prevMessagesRef.current;
|
const prevMessages = prevMessagesRef.current;
|
||||||
|
|
||||||
@@ -139,7 +190,7 @@ const MessageRecord: React.FC<MessageRecordProps> = ({ contract }) => {
|
|||||||
case 1: // 文本消息
|
case 1: // 文本消息
|
||||||
return (
|
return (
|
||||||
<div className={styles.messageBubble}>
|
<div className={styles.messageBubble}>
|
||||||
<div className={styles.messageText}>{content}</div>
|
<div className={styles.messageText}>{parseEmojiText(content)}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -776,7 +827,9 @@ const MessageRecord: React.FC<MessageRecordProps> = ({ contract }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 5. 默认按文本消息处理
|
// 5. 默认按文本消息处理
|
||||||
return <div className={styles.messageText}>{content}</div>;
|
return (
|
||||||
|
<div className={styles.messageText}>{parseEmojiText(content)}</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user