mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-22 19:30:15 +01:00
Merge pull request #1 from danny-avila/copyCode
complete copyCode for code blocks
This commit is contained in:
commit
0f9cfd0395
3 changed files with 28 additions and 13 deletions
|
|
@ -42,7 +42,7 @@ Currently, this project is only functional with the `text-davinci-003` model.
|
||||||
- [x] Highlight.js for code blocks
|
- [x] Highlight.js for code blocks
|
||||||
- [x] Markdown handling
|
- [x] Markdown handling
|
||||||
- [x] Language Detection for code blocks
|
- [x] Language Detection for code blocks
|
||||||
- [ ] 'Copy to clipboard' button for code and messages
|
- [x] 'Copy to clipboard' button for code blocks
|
||||||
- [ ] Set user/model label and prompt prefix view option
|
- [ ] Set user/model label and prompt prefix view option
|
||||||
- [ ] AI model change handling (whether to pseudo-persist convos or start new convos within existing convo)
|
- [ ] AI model change handling (whether to pseudo-persist convos or start new convos within existing convo)
|
||||||
- [ ] Server convo pagination (limit fetch and load more with 'show more' button)
|
- [ ] Server convo pagination (limit fetch and load more with 'show more' button)
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,34 @@
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import Clipboard from '../svg/Clipboard';
|
import Clipboard from '../svg/Clipboard';
|
||||||
|
import CheckMark from '../svg/CheckMark';
|
||||||
|
|
||||||
|
export default function Embed({ children, language = '', code, matched }) {
|
||||||
|
const [buttonText, setButtonText] = useState('Copy code');
|
||||||
|
const isClicked = buttonText === 'Copy code';
|
||||||
|
|
||||||
|
const clickHandler = () => {
|
||||||
|
navigator.clipboard.writeText(code.trim());
|
||||||
|
setButtonText('Copied!');
|
||||||
|
setTimeout(() => {
|
||||||
|
setButtonText('Copy code');
|
||||||
|
}, 3000);
|
||||||
|
};
|
||||||
|
|
||||||
export default function Embed({ children, language = '', matched}) {
|
|
||||||
return (
|
return (
|
||||||
<pre>
|
<pre>
|
||||||
<div className="mb-4 rounded-md bg-black">
|
<div className="mb-4 rounded-md bg-black">
|
||||||
<div className="relative flex items-center bg-gray-800 px-4 py-2 font-sans text-xs text-gray-200 rounded-tl-md rounded-tr-md">
|
<div className="relative flex items-center rounded-tl-md rounded-tr-md bg-gray-800 px-4 py-2 font-sans text-xs text-gray-200">
|
||||||
<span className="">{ (language === 'javascript' && !matched ? '' : language) }</span>
|
<span className="">{language === 'javascript' && !matched ? '' : language}</span>
|
||||||
<button className="ml-auto flex gap-2">
|
<button
|
||||||
<Clipboard />
|
className="ml-auto flex gap-2"
|
||||||
Copy code
|
onClick={clickHandler}
|
||||||
|
disabled={!isClicked}
|
||||||
|
>
|
||||||
|
{isClicked ? <Clipboard /> : <CheckMark />}
|
||||||
|
{buttonText}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="overflow-y-auto p-4">
|
<div className="overflow-y-auto p-4">{children}</div>
|
||||||
{ children }
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</pre>
|
</pre>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import Markdown from 'markdown-to-jsx';
|
||||||
import Embed from './Embed';
|
import Embed from './Embed';
|
||||||
import Highlight from './Highlight';
|
import Highlight from './Highlight';
|
||||||
import regexSplit from '~/utils/regexSplit';
|
import regexSplit from '~/utils/regexSplit';
|
||||||
import { languages, wrapperRegex } from '~/utils';
|
import { wrapperRegex } from '~/utils';
|
||||||
const { codeRegex, inLineRegex, markupRegex, languageMatch, newLineMatch } = wrapperRegex;
|
const { codeRegex, inLineRegex, markupRegex, languageMatch, newLineMatch } = wrapperRegex;
|
||||||
const mdOptions = { wrapper: React.Fragment, forceWrapper: true };
|
const mdOptions = { wrapper: React.Fragment, forceWrapper: true };
|
||||||
|
|
||||||
|
|
@ -67,11 +67,12 @@ export default function TextWrapper({ text }) {
|
||||||
<Embed
|
<Embed
|
||||||
key={i}
|
key={i}
|
||||||
language={language}
|
language={language}
|
||||||
|
code={part.slice(3, -3)}
|
||||||
matched={matched}
|
matched={matched}
|
||||||
>
|
>
|
||||||
<Highlight
|
<Highlight
|
||||||
code={part.slice(3, -3)}
|
|
||||||
language={language}
|
language={language}
|
||||||
|
code={part.slice(3, -3)}
|
||||||
/>
|
/>
|
||||||
</Embed>
|
</Embed>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue