feat: 聊天室对话渲染增强 - 思考内容Markdown渲染 + 工具调用参数卡片化
This commit is contained in:
71
src/web/features/chat/parts/HighlightBlock.tsx
Normal file
71
src/web/features/chat/parts/HighlightBlock.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { CopyOutlined } from "@ant-design/icons";
|
||||
import { App, Button } from "antd";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { codeToHtml } from "shiki";
|
||||
|
||||
import { useIsDark } from "../../../shared/hooks/use-is-dark";
|
||||
|
||||
interface HighlightBlockProps {
|
||||
code: string;
|
||||
isStreaming: boolean;
|
||||
lang: string;
|
||||
}
|
||||
|
||||
export function HighlightBlock({ code, isStreaming, lang }: HighlightBlockProps) {
|
||||
const { message } = App.useApp();
|
||||
const isDark = useIsDark();
|
||||
const [highlighted, setHighlighted] = useState<null | string>(null);
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
navigator.clipboard.writeText(code).then(
|
||||
() => message.success("已复制"),
|
||||
() => message.error("复制失败"),
|
||||
);
|
||||
}, [code, message]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isStreaming || !code) return;
|
||||
|
||||
let cancelled = false;
|
||||
codeToHtml(code, {
|
||||
lang,
|
||||
theme: isDark ? "github-dark" : "github-light",
|
||||
})
|
||||
.then((html) => {
|
||||
if (!cancelled) setHighlighted(html);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!cancelled) setHighlighted(null);
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [code, lang, isDark, isStreaming]);
|
||||
|
||||
if (isStreaming) {
|
||||
return (
|
||||
<pre className="code-block">
|
||||
<code>{code}</code>
|
||||
</pre>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="code-block">
|
||||
<div className="code-block-header">
|
||||
<span className="code-block-lang">{lang}</span>
|
||||
<Button className="btn-dimmed" icon={<CopyOutlined />} onClick={handleCopy} size="small" type="text" />
|
||||
</div>
|
||||
{highlighted ? (
|
||||
<div className="code-block-body" dangerouslySetInnerHTML={{ __html: highlighted }} />
|
||||
) : (
|
||||
<div className="code-block-body">
|
||||
<pre>
|
||||
<code>{code}</code>
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user