Markdown support in custom messages (#3267)

* add md support to appearance custom messages

* break out dompurify to util

---------

Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
This commit is contained in:
Sean Hatfield 2025-02-19 12:55:56 +08:00 committed by GitHub
parent e53ec1474e
commit 43e29d6f9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 25 additions and 14 deletions

View File

@ -1,6 +1,8 @@
import React from "react"; import React from "react";
import UserIcon from "../UserIcon"; import UserIcon from "../UserIcon";
import { userFromStorage } from "@/utils/request"; import { userFromStorage } from "@/utils/request";
import renderMarkdown from "@/utils/chat/markdown";
import DOMPurify from "@/utils/chat/purify";
export default function ChatBubble({ message, type, popMsg }) { export default function ChatBubble({ message, type, popMsg }) {
const isUser = type === "user"; const isUser = type === "user";
@ -16,11 +18,12 @@ export default function ChatBubble({ message, type, popMsg }) {
role={type} role={type}
/> />
<span <div
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`} className={`markdown whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
> dangerouslySetInnerHTML={{
{message} __html: DOMPurify.sanitize(renderMarkdown(message)),
</span> }}
/>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,8 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { X } from "@phosphor-icons/react"; import { X } from "@phosphor-icons/react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import renderMarkdown from "@/utils/chat/markdown";
import DOMPurify from "@/utils/chat/purify";
export default function EditingChatBubble({ export default function EditingChatBubble({
message, message,
@ -57,9 +59,12 @@ export default function EditingChatBubble({
/> />
) : ( ) : (
tempMessage && ( tempMessage && (
<p className=" font-[500] md:font-semibold text-sm md:text-base break-words light:invert"> <div
{tempMessage} className="markdown font-[500] md:font-semibold text-sm md:text-base break-words light:invert"
</p> dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(renderMarkdown(tempMessage)),
}}
/>
) )
)} )}
</div> </div>

View File

@ -6,7 +6,7 @@ import renderMarkdown from "@/utils/chat/markdown";
import { userFromStorage } from "@/utils/request"; import { userFromStorage } from "@/utils/request";
import Citations from "../Citation"; import Citations from "../Citation";
import { v4 } from "uuid"; import { v4 } from "uuid";
import createDOMPurify from "dompurify"; import DOMPurify from "@/utils/chat/purify";
import { EditMessageForm, useEditMessage } from "./Actions/EditMessage"; import { EditMessageForm, useEditMessage } from "./Actions/EditMessage";
import { useWatchDeleteMessage } from "./Actions/DeleteMessage"; import { useWatchDeleteMessage } from "./Actions/DeleteMessage";
import TTSMessage from "./Actions/TTSButton"; import TTSMessage from "./Actions/TTSButton";
@ -17,11 +17,6 @@ import {
ThoughtChainComponent, ThoughtChainComponent,
} from "../ThoughtContainer"; } from "../ThoughtContainer";
const DOMPurify = createDOMPurify(window);
DOMPurify.setConfig({
ADD_ATTR: ["target", "rel"],
});
const HistoricalMessage = ({ const HistoricalMessage = ({
uuid = v4(), uuid = v4(),
message, message,

View File

@ -0,0 +1,8 @@
import createDOMPurify from "dompurify";
const DOMPurify = createDOMPurify(window);
DOMPurify.setConfig({
ADD_ATTR: ["target", "rel"],
});
export default DOMPurify;