From e95e22de15c76596f0058fc06ba3d44596378561 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Thu, 23 Feb 2023 16:32:08 -0500 Subject: [PATCH] code highlighting in progress --- .vscode/settings.json | 2 +- package-lock.json | 46 ++++++++++++++++++ package.json | 2 + server/routes/ask.js | 2 +- src/atom-one-dark.css | 1 + src/components/Messages/CodeWrapper.jsx | 63 ++++++++++++++++++++----- src/components/Messages/Embed.jsx | 62 ++++++++++++++++++++++++ src/components/Nav/index.jsx | 2 +- src/components/main/TextChat.jsx | 2 +- src/utils/handleSubmit.js | 5 +- 10 files changed, 169 insertions(+), 18 deletions(-) create mode 100644 src/atom-one-dark.css create mode 100644 src/components/Messages/Embed.jsx diff --git a/.vscode/settings.json b/.vscode/settings.json index 1c0b593392..bb0a651f67 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "editor.lightbulb.enabled": false, "editor.parameterHints.enabled": false, "editor.renderWhitespace": "all", - "editor.snippetSuggestions": "none", + // "editor.snippetSuggestions": "none", "editor.tabSize": 2, "editor.wordWrap": "on", "emmet.showExpandedAbbreviation": "never", diff --git a/package-lock.json b/package-lock.json index 28c8e6ece2..667b3488ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "cors": "^2.8.5", "crypto-browserify": "^3.12.0", "dotenv": "^16.0.3", + "highlight.js": "^11.7.0", "keyv": "^4.5.2", "keyv-file": "^0.2.0", "lucide-react": "^0.113.0", @@ -27,6 +28,7 @@ "openai": "^3.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-highlight": "^0.15.0", "react-redux": "^8.0.5", "react-textarea-autosize": "^8.4.0", "react-transition-group": "^4.4.5", @@ -8722,6 +8724,14 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz", + "integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -12211,6 +12221,22 @@ "react": "^18.2.0" } }, + "node_modules/react-highlight": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/react-highlight/-/react-highlight-0.15.0.tgz", + "integrity": "sha512-5uV/b/N4Z421GSVVe05fz+OfTsJtFzx/fJBdafZyw4LS70XjIZwgEx3Lrkfc01W/RzZ2Dtfb0DApoaJFAIKBtA==", + "dependencies": { + "highlight.js": "^10.5.0" + } + }, + "node_modules/react-highlight/node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "engines": { + "node": "*" + } + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -21488,6 +21514,11 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "highlight.js": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz", + "integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==" + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -23885,6 +23916,21 @@ "scheduler": "^0.23.0" } }, + "react-highlight": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/react-highlight/-/react-highlight-0.15.0.tgz", + "integrity": "sha512-5uV/b/N4Z421GSVVe05fz+OfTsJtFzx/fJBdafZyw4LS70XjIZwgEx3Lrkfc01W/RzZ2Dtfb0DApoaJFAIKBtA==", + "requires": { + "highlight.js": "^10.5.0" + }, + "dependencies": { + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + } + } + }, "react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", diff --git a/package.json b/package.json index 0436b67dbc..c204baa719 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "cors": "^2.8.5", "crypto-browserify": "^3.12.0", "dotenv": "^16.0.3", + "highlight.js": "^11.7.0", "keyv": "^4.5.2", "keyv-file": "^0.2.0", "lucide-react": "^0.113.0", @@ -39,6 +40,7 @@ "openai": "^3.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-highlight": "^0.15.0", "react-redux": "^8.0.5", "react-textarea-autosize": "^8.4.0", "react-transition-group": "^4.4.5", diff --git a/server/routes/ask.js b/server/routes/ask.js index b19e632640..6b379f9df1 100644 --- a/server/routes/ask.js +++ b/server/routes/ask.js @@ -154,7 +154,7 @@ router.post('/', async (req, res) => { } if (!parentMessageId) { - gptResponse.title = await titleConvo(text, gptResponse.text, model); + gptResponse.title = await titleConvo(text, JSON.stringify(gptResponse.text), model); } gptResponse.sender = model; gptResponse.final = true; diff --git a/src/atom-one-dark.css b/src/atom-one-dark.css new file mode 100644 index 0000000000..5344ee3819 --- /dev/null +++ b/src/atom-one-dark.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/src/components/Messages/CodeWrapper.jsx b/src/components/Messages/CodeWrapper.jsx index 3dc1217f20..ef28bf40af 100644 --- a/src/components/Messages/CodeWrapper.jsx +++ b/src/components/Messages/CodeWrapper.jsx @@ -1,18 +1,55 @@ import React from 'react'; +import Embed from './Embed'; +import hljs from 'highlight.js'; +import Highlight from 'react-highlight'; export default function CodeWrapper({ text }) { - const matchRegex = /(`[^`]+?`)/g; - const parts = text.split(matchRegex); - // console.log('parts', parts); + if (text.includes('```')) { + const codeRegex = /(```[^`]+?```)/g; + const inLineRegex = /(`[^`]+?`)/g; + const parts = text.split(codeRegex); + // console.log(parts); + const codeParts = parts.map((part, i) => { + if (part.match(codeRegex)) { + return ( + + {hljs.highlightAuto(part.slice(1, -1)).value} + {/* {part.slice(1, -1)} */} - // map over the parts and wrap any text between tildes with tags - const codeParts = parts.map((part, index) => { - if (part.match(matchRegex)) { - return {part.slice(1, -1)}; - } else { - return part; - } - }); + + ); + } else if (part.match(inLineRegex)) { + const innerParts = part.split(inLineRegex); + return innerParts.map((part, i) => { + if (part.match(inLineRegex)) { + return {part.slice(1, -1)}; + } else { + return part; + } + }); + } else { + return part; + } + }); - return <>{codeParts}; // return the wrapped text -} \ No newline at end of file + return <>{codeParts}; // return the wrapped text + } else { + const matchRegex = /(`[^`]+?`)/g; + const parts = text.split(matchRegex); + // console.log('parts', parts); + + // map over the parts and wrap any text between tildes with tags + const codeParts = parts.map((part, i) => { + if (part.match(matchRegex)) { + return {part.slice(1, -1)}; + } else { + return part; + } + }); + + return <>{codeParts}; // return the wrapped text + } +} diff --git a/src/components/Messages/Embed.jsx b/src/components/Messages/Embed.jsx new file mode 100644 index 0000000000..004d4a1e16 --- /dev/null +++ b/src/components/Messages/Embed.jsx @@ -0,0 +1,62 @@ +import React from 'react'; +// import '~/atom-one-dark.css'; + +export default function Embed({ children, language = ''}) { + return ( +
+      
+
+ { language } + +
+
+ { children } + {/* export default function CodeWrapper({ text }) { + const matchRegex = /(`[^`]+?`)/g; // regex to match backticks and text between them + const parts = text.split(matchRegex); + console.log('parts', parts); + + // map over the parts and wrap any backticked text with <code> tags + const codeParts = parts.map((part, index) => { + if (part.match(matchRegex)) { + <> + return <code key={index}>{part}</code>; + + } else { + <> + return part.trim(); // remove leading/trailing whitespace from non-backticked text + + } + }); + + return <>{codeParts}</>; // return the wrapped text +} */} +
+
+
+ ); +} diff --git a/src/components/Nav/index.jsx b/src/components/Nav/index.jsx index b517de335a..35e9dcd1f6 100644 --- a/src/components/Nav/index.jsx +++ b/src/components/Nav/index.jsx @@ -28,7 +28,7 @@ export default function Nav() { onMouseLeave={() => setIsHovering(false)} >
- {!!isLoading ? : } + {isLoading ? : }
diff --git a/src/components/main/TextChat.jsx b/src/components/main/TextChat.jsx index 58b37e6d2e..0d6bf3d9b5 100644 --- a/src/components/main/TextChat.jsx +++ b/src/components/main/TextChat.jsx @@ -38,7 +38,7 @@ export default function TextChat({ messages }) { }; const convoHandler = (data) => { console.log('in convo handler'); - if (model !== 'bingai' && convo.conversationId && convo.parentMessageId === null) { + if (model !== 'bingai' && convo.conversationId === null && convo.parentMessageId === null) { const { title, conversationId, id } = data; console.log('parentMessageId is null'); console.log('title, convoId, id', title, conversationId, id); diff --git a/src/utils/handleSubmit.js b/src/utils/handleSubmit.js index d5e9d110da..c2467e4a6c 100644 --- a/src/utils/handleSubmit.js +++ b/src/utils/handleSubmit.js @@ -1,5 +1,6 @@ import { SSE } from '../../app/sse'; const endpoint = 'http://localhost:3050/ask'; +// const newLineRegex = /^\n+/; export default function handleSubmit({ model, @@ -40,8 +41,10 @@ export default function handleSubmit({ events.onmessage = function (e) { const data = JSON.parse(e.data); - const text = data.text || data.response; + let text = data.text || data.response; if (data.message) { + // text = text.match(newLineRegex) ? text.replace(newLineRegex, '') : text; + // console.log(data); messageHandler(text); } else if (data.final) { console.log(data);