mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-21 04:41:16 -05:00
Replace react markdown with react remark for better performance when streaming
This commit is contained in:
129
webview-ui/src/components/common/MarkdownBlock.tsx
Normal file
129
webview-ui/src/components/common/MarkdownBlock.tsx
Normal file
@@ -0,0 +1,129 @@
|
||||
import { memo, useEffect } from "react"
|
||||
import { useRemark } from "react-remark"
|
||||
import rehypeHighlight, { Options } from "rehype-highlight"
|
||||
import styled from "styled-components"
|
||||
import { visit } from "unist-util-visit"
|
||||
import { useExtensionState } from "../../context/ExtensionStateContext"
|
||||
import { CODE_BLOCK_BG_COLOR } from "./CodeBlock"
|
||||
|
||||
interface MarkdownBlockProps {
|
||||
markdown?: string
|
||||
}
|
||||
|
||||
const StyledMarkdown = styled.div`
|
||||
pre {
|
||||
background-color: ${CODE_BLOCK_BG_COLOR};
|
||||
border-radius: 3px;
|
||||
margin: 13x 0;
|
||||
padding: 10px 10px;
|
||||
max-width: calc(100vw - 20px);
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
.hljs-deletion {
|
||||
background-color: var(--vscode-diffEditor-removedTextBackground);
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
.hljs-addition {
|
||||
background-color: var(--vscode-diffEditor-insertedTextBackground);
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
span.line:empty {
|
||||
display: none;
|
||||
}
|
||||
word-wrap: break-word;
|
||||
border-radius: 3px;
|
||||
background-color: ${CODE_BLOCK_BG_COLOR};
|
||||
font-size: var(--vscode-editor-font-size, var(--vscode-font-size, 12px));
|
||||
font-family: var(--vscode-editor-font-family);
|
||||
}
|
||||
|
||||
code:not(pre > code) {
|
||||
font-family: var(--vscode-editor-font-family, monospace);
|
||||
color: var(--vscode-textPreformat-foreground, #f78383);
|
||||
background-color: var(--vscode-textCodeBlock-background, #1e1e1e);
|
||||
padding: 0px 2px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid var(--vscode-textSeparator-foreground, #424242);
|
||||
white-space: pre-line;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
font-family: var(--vscode-font-family), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
|
||||
font-size: var(--vscode-font-size, 13px);
|
||||
|
||||
p,
|
||||
li,
|
||||
ol,
|
||||
ul {
|
||||
line-height: 1.25;
|
||||
}
|
||||
`
|
||||
|
||||
const StyledPre = styled.pre<{ theme: any }>`
|
||||
& .hljs {
|
||||
color: var(--vscode-editor-foreground, #fff);
|
||||
}
|
||||
|
||||
${(props) =>
|
||||
Object.keys(props.theme)
|
||||
.map((key, index) => {
|
||||
return `
|
||||
& ${key} {
|
||||
color: ${props.theme[key]};
|
||||
}
|
||||
`
|
||||
})
|
||||
.join("")}
|
||||
`
|
||||
|
||||
const MarkdownBlock = memo(({ markdown }: MarkdownBlockProps) => {
|
||||
const { theme } = useExtensionState()
|
||||
const [reactContent, setMarkdown] = useRemark({
|
||||
remarkPlugins: [
|
||||
() => {
|
||||
return (tree) => {
|
||||
visit(tree, "code", (node: any) => {
|
||||
if (!node.lang) {
|
||||
node.lang = "javascript"
|
||||
} else if (node.lang.includes(".")) {
|
||||
node.lang = node.lang.split(".").slice(-1)[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
],
|
||||
rehypePlugins: [
|
||||
rehypeHighlight as any,
|
||||
{
|
||||
// languages: {},
|
||||
} as Options,
|
||||
],
|
||||
rehypeReactOptions: {
|
||||
components: {
|
||||
pre: ({ node, ...preProps }: any) => <StyledPre {...preProps} theme={theme} />,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
setMarkdown(markdown || "")
|
||||
}, [markdown, setMarkdown, theme])
|
||||
|
||||
return (
|
||||
<div style={{}}>
|
||||
<StyledMarkdown>{reactContent}</StyledMarkdown>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export default MarkdownBlock
|
||||
Reference in New Issue
Block a user