diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index f8f25a3..ea0c1ed 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -1,4 +1,4 @@ -import { memo, useEffect, useRef, useState } from 'react' +import { memo, useEffect, useMemo, useRef, useState } from 'react' import PropTypes from 'prop-types' import Browser from 'webextension-polyfill' import InputBox from '../InputBox' @@ -292,6 +292,8 @@ function ConversationCard(props) { } } + const retryFn = useMemo(() => getRetryFn(session), [session]) + return (
))}
@@ -533,7 +536,7 @@ function ConversationCard(props) { ConversationCard.propTypes = { session: PropTypes.object.isRequired, - question: PropTypes.string.isRequired, + question: PropTypes.string, onUpdate: PropTypes.func, draggable: PropTypes.bool, closeable: PropTypes.bool, diff --git a/src/components/ConversationItem/index.jsx b/src/components/ConversationItem/index.jsx index 1709d72..9ef7734 100644 --- a/src/components/ConversationItem/index.jsx +++ b/src/components/ConversationItem/index.jsx @@ -1,4 +1,4 @@ -import { useState } from 'react' +import { memo, useState } from 'react' import { ChevronDownIcon, XCircleIcon, SyncIcon } from '@primer/octicons-react' import CopyButton from '../CopyButton' import ReadButton from '../ReadButton' @@ -8,11 +8,29 @@ import { useTranslation } from 'react-i18next' import { isUsingCustomModel } from '../../config/index.mjs' import { useConfig } from '../../hooks/use-config.mjs' -// eslint-disable-next-line -export function ConversationItem({ type, content, session, onRetry }) { +function AnswerTitle({ descName, modelName }) { + const { t } = useTranslation() + const config = useConfig() + + return ( +

+ {descName && modelName + ? `${t(descName)}${ + isUsingCustomModel({ modelName }) ? ' (' + config.customModelName + ')' : '' + }:` + : t('Loading...')} +

+ ) +} + +AnswerTitle.propTypes = { + descName: PropTypes.string, + modelName: PropTypes.string, +} + +export function ConversationItem({ type, content, descName, modelName, onRetry }) { const { t } = useTranslation() const [collapsed, setCollapsed] = useState(false) - const config = useConfig() switch (type) { case 'question': @@ -49,23 +67,17 @@ export function ConversationItem({ type, content, session, onRetry }) { return (
-

- {session && session.aiName - ? `${t(session.aiName)}${ - isUsingCustomModel(session) ? ' (' + config.customModelName + ')' : '' - }:` - : t('Loading...')} -

+
{onRetry && ( )} - {session && ( + {modelName && ( content.replace(/\n$/, '')} size={14} /> )} - {session && content} size={14} />} + {modelName && content} size={14} />} {!collapsed ? ( { + const onClose = useCallback(() => { + props.container.remove() + }, []) + + const onDock = useCallback(() => { props.container.className = 'chatgptbox-toolbar-container-not-queryable' setCloseable(true) - } + }, []) + + const onUpdate = useCallback(() => { + updatePosition() + }, [position]) if (config.alwaysPinWindow) onDock() @@ -95,14 +103,10 @@ function FloatingToolbar(props) { question={prompt} draggable={true} closeable={closeable} - onClose={() => { - props.container.remove() - }} + onClose={onClose} dockable={props.dockable} onDock={onDock} - onUpdate={() => { - updatePosition() - }} + onUpdate={onUpdate} />
diff --git a/src/components/MarkdownRender/markdown.jsx b/src/components/MarkdownRender/markdown.jsx index 5bf2e3c..bc1552f 100644 --- a/src/components/MarkdownRender/markdown.jsx +++ b/src/components/MarkdownRender/markdown.jsx @@ -8,6 +8,7 @@ import remarkGfm from 'remark-gfm' import remarkBreaks from 'remark-breaks' import { Pre } from './Pre' import { Hyperlink } from './Hyperlink' +import { memo } from 'react' export function MarkdownRender(props) { return ( @@ -41,4 +42,4 @@ MarkdownRender.propTypes = { ...ReactMarkdown.propTypes, } -export default MarkdownRender +export default memo(MarkdownRender)