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); 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 (
        {code}
      
); } return (
{lang}
{highlighted ? (
) : (
            {code}
          
)}
); }