diff --git a/src/components/ArticleV3/ArticleCellExplainCodeButton.css b/src/components/ArticleV3/ArticleCellExplainCodeButton.css
index b8d385c8..68f834dc 100644
--- a/src/components/ArticleV3/ArticleCellExplainCodeButton.css
+++ b/src/components/ArticleV3/ArticleCellExplainCodeButton.css
@@ -1,6 +1,7 @@
.ArticleCellExplainCodeButton {
--bs-btn-disabled-opacity: 0.8;
- --status-error: red;
+ --status-error: tomato;
+ --status-error-alpha: rgba(255, 99, 71, 0.2);
--status-success: green;
color: var(--white);
}
@@ -45,10 +46,16 @@
display: block;
}
-/* .ArticleCellExplainCodeButton.executing .ArticleCellExplainCodeButton__iconWrapper::after {
- border: 2px solid var(--white);
- animation: ArticleCellExplainCodeButton__rotate 2s linear infinite;
-} */
+.ArticleCellExplainCodeButton.error button {
+ color: var(--status-error);
+ border-color: var(--status-error) !important;
+}
+.ArticleCellExplainCodeButton.error button:hover {
+
+ border-color: var(--status-error) !important;
+ background-color: var(--status-error-alpha);
+}
+
.ArticleCellExplainCodeButton.success .ArticleCellExplainCodeButton__iconWrapper::after {
border: 2px solid var(--primary);
}
@@ -57,6 +64,15 @@
color: var(--primary);
}
+.ArticleCellExplainCodeButton.error .ArticleCellExplainCodeButton__iconWrapper {
+ color: var(--status-error);
+}
+
+.ArticleCellExplainCodeButton.error .ArticleCellExplainCodeButton__iconWrapper::after {
+ border: 2px solid var(--status-error);
+}
+
+
@keyframes ArticleCellExplainCodeButton__rotate {
0% {
transform: translate(-50%, -50%) rotate(0deg);
diff --git a/src/components/ArticleV3/ArticleCellExplainCodeButton.js b/src/components/ArticleV3/ArticleCellExplainCodeButton.js
index 860bc2c6..cce6a56d 100644
--- a/src/components/ArticleV3/ArticleCellExplainCodeButton.js
+++ b/src/components/ArticleV3/ArticleCellExplainCodeButton.js
@@ -1,4 +1,4 @@
-import { BrainWarning, ElectronicsChip, MagicWand, PauseSolid } from 'iconoir-react'
+import { BrainWarning, ElectronicsChip, PauseSolid } from 'iconoir-react'
import React from 'react'
import './ArticleCellExplainCodeButton.css'
import CircularLoading from '../CircularLoading'
@@ -17,7 +17,7 @@ export const StatusBeforeExecuting = 'beforeExecuting'
export const AvailableStatuses = [StatusIdle, StatusExecuting, StatusSuccess, StatusError]
const StatusIcons = {
- [StatusIdle]: MagicWand,
+ [StatusIdle]: ElectronicsChip,
[StatusExecuting]: PauseSolid,
[StatusSuccess]: ElectronicsChip,
[StatusError]: BrainWarning,
@@ -42,7 +42,7 @@ const ArticleCellExplainCodeButton = ({
diff --git a/src/components/ArticleV3/ArticleCellExplainer.css b/src/components/ArticleV3/ArticleCellExplainer.css
index cb2908da..e7353bba 100644
--- a/src/components/ArticleV3/ArticleCellExplainer.css
+++ b/src/components/ArticleV3/ArticleCellExplainer.css
@@ -2,3 +2,15 @@
overflow: hidden;
height: 0;
}
+
+.ArticleCellExplainer__messages {
+ margin-top: var(--spacer-2);
+ padding: var(--spacer-1) var(--spacer-2);
+ border-radius: 5px;
+ max-height: 600px;
+}
+.ArticleCellExplainer__messages.error {
+ background: #ff634755;
+ color: tomato;
+ position: relative;
+}
diff --git a/src/components/ArticleV3/ArticleCellExplainer.js b/src/components/ArticleV3/ArticleCellExplainer.js
index 47811f55..6252c215 100644
--- a/src/components/ArticleV3/ArticleCellExplainer.js
+++ b/src/components/ArticleV3/ArticleCellExplainer.js
@@ -11,37 +11,51 @@ import './ArticleCellExplainer.css'
import { useArticleCellExplainerStore } from '../../store'
import { useMutation } from '@tanstack/react-query'
+import { useTranslation } from 'react-i18next'
+
+console.info(
+ '%cEnable Code Explainer',
+ 'font-weight: bold',
+ process.env.REACT_APP_ENABLE_CODE_EXPLAINER === 'true',
+)
const ArticleCellExplainer = ({ source = '', cellIdx = '', className = '' }) => {
+ const { t } = useTranslation()
const messagesRef = useRef(null)
const resultRef = useRef(null)
const [styles, api] = useSpring(() => ({
height: 0,
+ opacity: 0,
}))
const [free, lock] = useArticleCellExplainerStore((state) => [state.free, state.lock])
const currentCellIdx = useArticleCellExplainerStore((state) => state.cellIdx)
- const { status, mutate, data, error } = useMutation({
+ const { status, mutate } = useMutation({
mutationFn: (code) => {
- console.info('[ArticleCellExplainer] mutationFn', code)
- return axios
- .post('/api/explain', {
- code,
- })
- .catch((error) => {
- console.error('[ArticleCellExplainer] mutationFn error', error)
- api.start({
- height: messagesRef.current.scrollHeight,
- })
- free()
- throw error
- })
+ console.info('[ArticleCellExplainer] mutationFn n.chars:', code.length)
+ return axios.post('/api/explain', {
+ code,
+ })
},
onSuccess: (res) => {
console.info('[ArticleCellExplainer] mutation success', res)
- resultRef.current.innerHTML = JSON.stringify(res.data.result, null, 2)
+ const messages = res.data.result.choices.map((choice) => choice.content).join('
')
+ resultRef.current.innerHTML = messages
api.start({
height: messagesRef.current.scrollHeight,
+ opacity: 1,
+ })
+ free()
+ return res
+ },
+ onError: (error) => {
+ console.error('[ArticleCellExplainer] mutation error', error)
+ resultRef.current.innerHTML = t('errors.explainCodeNotAvailable', {
+ error: error.message,
+ })
+ api.start({
+ height: messagesRef.current.scrollHeight,
+ opacity: 1,
})
free()
},
@@ -52,10 +66,12 @@ const ArticleCellExplainer = ({ source = '', cellIdx = '', className = '' }) =>
lock(cellIdx)
let codeToExplain = Array.isArray(source) ? source.join('\n') : source
// reduce the code To Explain Length to max 500 chars
+ codeToExplain = codeToExplain.trim().replace(/\n/g, ' ').replace(/\s+/g, ' ')
if (codeToExplain.length > 1000) {
codeToExplain = codeToExplain.slice(0, 1000)
console.debug('[ArticleCellExplainer] codeToExplain shortened to 1000 chars')
}
+
mutate(codeToExplain)
}
@@ -63,19 +79,20 @@ const ArticleCellExplainer = ({ source = '', cellIdx = '', className = '' }) =>
free()
api.start({
height: 0,
+ opacity: 0,
})
}
// display Status
let displayStatus = StatusIdle
if (status === 'success') {
displayStatus = StatusSuccess
- } else if (status === 'loading') {
+ } else if (status === 'pending') {
displayStatus = StatusExecuting
} else if (status === 'error') {
displayStatus = StatusError
}
const disabled = currentCellIdx !== null
- const cellSource = Array.isArray(source) ? source.join('\n') : source
+ // const cellSource = Array.isArray(source) ? source.join('\n') : source
return (
@@ -92,20 +109,13 @@ const ArticleCellExplainer = ({ source = '', cellIdx = '', className = '' }) =>
(close)
-
-
- axios: {status}
- {JSON.stringify({ data, error })}
- Explainer
- {cellSource.length} characters
- {cellSource}
-
- This code cell is an explainer cell. It is used to provide context and explanation for the
- code cell above it.
-
-
- You can edit the content of this cell by clicking the pencil icon in the top right corner.
-
+
+
)