Merge pull request #12 from devchat-ai/feat/prism

Feat/prism
This commit is contained in:
小石头 2024-01-05 16:24:26 +08:00 committed by GitHub
commit 5f88ce17ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 166 additions and 91 deletions

View File

@ -135,6 +135,7 @@
"ncp": "^2.0.0",
"node-fetch": "^3.3.1",
"nonce": "^1.0.4",
"prism-react-renderer": "^2.3.1",
"quote": "^0.4.0",
"react-i18next": "^13.5.0",
"react-markdown": "^8.0.7",

View File

@ -1,107 +1,132 @@
import { Accordion, Box, Button, Collapse, Group,Loader,Text } from "@mantine/core";
import { Accordion, Loader, Text } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import React from "react";
import SyntaxHighlighter from "react-syntax-highlighter";
import LanguageCorner from "./LanguageCorner";
import { Highlight, themes } from "prism-react-renderer";
import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism";
import { IconCheck, IconChevronDown, IconFileDiff, IconLoader } from "@tabler/icons-react";
import { IconCheck } from "@tabler/icons-react";
import { observer } from "mobx-react-lite";
import { useMst } from "@/views/stores/RootStore";
import { keyframes,css } from "@emotion/react";
import { keyframes, css } from "@emotion/react";
interface StepProps {
language: string;
children: string;
status: string;
index: number|undefined;
language: string;
children: string;
status: string;
index: number | undefined;
}
const Step = observer((props:StepProps) => {
const Step = observer((props: StepProps) => {
const { chat } = useMst();
const {language,children,status,index} = props;
const { language, children, status, index } = props;
const [opened, { toggle }] = useDisclosure(false);
// extract first line with # as button label
const lines = children.split('\n');
const title = lines.length>0&&lines[0].indexOf('#')>=0?lines[0].split('#')[1]:'Thinking...';
const contents = lines.slice(1,lines.length-1);
const lines = children.split("\n");
const title =
lines.length > 0 && lines[0].indexOf("#") >= 0
? lines[0].split("#")[1]
: "Thinking...";
const contents = lines.slice(1, lines.length - 1);
const spin = keyframes`
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
`;
return <Accordion
variant="contained"
chevronPosition="right"
sx={{
marginTop: 5,
borderRadius: 5,
backgroundColor: 'var(--vscode-menu-background)',
}}
styles={{
item: {
borderColor: 'var(--vscode-menu-border)',
backgroundColor: 'var(--vscode-menu-background)',
'&[data-active]': {
backgroundColor: 'var(--vscode-menu-background)',
}
},
control: {
height: 30,
borderRadius: 3,
backgroundColor: 'var(--vscode-menu-background)',
'&[aria-expanded="true"]': {
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
},
'&:hover': {
backgroundColor: 'var(--vscode-menu-background)',
},
paddingLeft: '0.5rem',
paddingRight: '0.5rem',
fontFamily: 'var(--vscode-editor-font-familyy)',
fontSize: 'var(--vscode-editor-font-size)',
},
chevron: {
color: 'var(--vscode-menu-foreground)',
},
icon: {
color: 'var(--vscode-menu-foreground)',
},
label: {
color: 'var(--vscode-menu-foreground)',
},
panel: {
color: 'var(--vscode-menu-foreground)',
backgroundColor: 'var(--vscode-menu-background)',
},
content: {
borderRadius: 3,
backgroundColor: 'var(--vscode-menu-background)',
padding:'0.5rem'
}
}}
return (
<Accordion
variant="contained"
chevronPosition="right"
sx={{
marginTop: 5,
borderRadius: 5,
backgroundColor: "var(--vscode-menu-background)",
}}
styles={{
item: {
borderColor: "var(--vscode-menu-border)",
backgroundColor: "var(--vscode-menu-background)",
"&[data-active]": {
backgroundColor: "var(--vscode-menu-background)",
},
},
control: {
height: 30,
borderRadius: 3,
backgroundColor: "var(--vscode-menu-background)",
'&[aria-expanded="true"]': {
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
},
"&:hover": {
backgroundColor: "var(--vscode-menu-background)",
},
paddingLeft: "0.5rem",
paddingRight: "0.5rem",
fontFamily: "var(--vscode-editor-font-familyy)",
fontSize: "var(--vscode-editor-font-size)",
},
chevron: {
color: "var(--vscode-menu-foreground)",
},
icon: {
color: "var(--vscode-menu-foreground)",
},
label: {
color: "var(--vscode-menu-foreground)",
},
panel: {
color: "var(--vscode-menu-foreground)",
backgroundColor: "var(--vscode-menu-background)",
},
content: {
borderRadius: 3,
backgroundColor: "var(--vscode-menu-background)",
padding: "0.5rem",
},
}}
>
<Accordion.Item value={"step" + index} mah="200">
<Accordion.Control
icon={
status === "done" ? (
<IconCheck size="1.125rem" />
) : (
<Loader size="xs" color="#ED6A45" speed={1} />
)
}
>
<Accordion.Item value={'step'+index} mah='200'>
<Accordion.Control icon={
status === "done"
?<IconCheck size="1.125rem"/>
:<Loader size="xs" color="#ED6A45" speed={1} />
}
<Text truncate="end" w={chat.chatPanelWidth - 100}>
{title}
</Text>
</Accordion.Control>
<Accordion.Panel>
<Highlight code={children} theme={themes.okaidia} language="markdown">
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<pre
className={className}
style={{
...style,
borderRadius: "5px",
padding: "10px 15px",
}}
{...props}
>
<Text truncate='end' w={chat.chatPanelWidth-100}>{title}</Text>
</Accordion.Control>
<Accordion.Panel>
<SyntaxHighlighter {...props}
language="markdown"
style={okaidia}
PreTag="div">
{children}
</SyntaxHighlighter>
</Accordion.Panel>
</Accordion.Item>
</Accordion>;
});
{tokens.map((line, i) => (
<div {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span {...getTokenProps({ token, key })} />
))}
</div>
))}
</pre>
)}
</Highlight>
</Accordion.Panel>
</Accordion.Item>
</Accordion>
);
});
export default Step;
export default Step;

View File

@ -2,8 +2,7 @@ import { Button, Anchor, Stack, Group, Box, createStyles } from "@mantine/core";
import React, { useEffect, useMemo, useState } from "react";
import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism";
import { Highlight, themes } from "prism-react-renderer";
import CodeButtons from "./CodeButtons";
import Step from "./Step";
import LanguageCorner from "./LanguageCorner";
@ -355,7 +354,7 @@ Generate a professionally written and formatted release note in markdown with th
>
<LanguageCorner language={lanugage} />
<CodeButtons language={lanugage} code={value} />
<SyntaxHighlighter
{/* <SyntaxHighlighter
{...props}
language={lanugage}
customStyle={{ padding: "35px 10px 10px 10px" }}
@ -364,7 +363,39 @@ Generate a professionally written and formatted release note in markdown with th
PreTag="div"
>
{value}
</SyntaxHighlighter>
</SyntaxHighlighter> */}
<Highlight
code={value}
theme={themes.okaidia}
language={lanugage}
>
{({
className,
style,
tokens,
getLineProps,
getTokenProps,
}) => (
<pre
className={className}
style={{
...style,
padding: "35px 10px 10px 10px",
borderRadius: "5px",
...props.style,
}}
{...props}
>
{tokens.map((line, i) => (
<div {...getLineProps({ line, key: i })}>
{line.map((token, key) => (
<span {...getTokenProps({ token, key })} />
))}
</div>
))}
</pre>
)}
</Highlight>
</div>
) : (
<code {...props} className={className}>
@ -392,10 +423,10 @@ Generate a professionally written and formatted release note in markdown with th
color: "#fff",
},
}}
styles = {{
root:{
styles={{
root: {
marginBottom: 10,
}
},
}}
onClick={() => {
value === "get_devchat_key" && platform === "idea"

View File

@ -2218,6 +2218,11 @@
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==
"@types/prismjs@^1.26.0":
version "1.26.3"
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.3.tgz#47fe8e784c2dee24fe636cab82e090d3da9b7dec"
integrity sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==
"@types/prop-types@*", "@types/prop-types@^15.0.0":
version "15.7.11"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
@ -3256,6 +3261,11 @@ clsx@1.1.1:
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
clsx@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@ -6874,6 +6884,14 @@ prism-react-renderer@^1.2.1:
resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz#786bb69aa6f73c32ba1ee813fbe17a0115435085"
integrity sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==
prism-react-renderer@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz#e59e5450052ede17488f6bc85de1553f584ff8d5"
integrity sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==
dependencies:
"@types/prismjs" "^1.26.0"
clsx "^2.0.0"
prismjs@^1.27.0:
version "1.29.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12"