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)