mirror of
https://github.com/wassname/chatGPTBox.git
synced 2026-07-01 07:25:29 +08:00
improve render performance (#265)
This commit is contained in:
@@ -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 (
|
||||
<div className="gpt-inner">
|
||||
<div
|
||||
@@ -500,8 +502,9 @@ function ConversationCard(props) {
|
||||
content={data.content}
|
||||
key={idx}
|
||||
type={data.type}
|
||||
session={session}
|
||||
onRetry={idx === conversationItemData.length - 1 ? getRetryFn(session) : null}
|
||||
descName={data.type === 'answer' && session.aiName}
|
||||
modelName={data.type === 'answer' && session.modelName}
|
||||
onRetry={idx === conversationItemData.length - 1 ? retryFn : null}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -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,
|
||||
|
||||
@@ -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 (
|
||||
<p style="white-space: nowrap;">
|
||||
{descName && modelName
|
||||
? `${t(descName)}${
|
||||
isUsingCustomModel({ modelName }) ? ' (' + config.customModelName + ')' : ''
|
||||
}:`
|
||||
: t('Loading...')}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
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 (
|
||||
<div className={type} dir="auto">
|
||||
<div className="gpt-header">
|
||||
<p style="white-space: nowrap;">
|
||||
{session && session.aiName
|
||||
? `${t(session.aiName)}${
|
||||
isUsingCustomModel(session) ? ' (' + config.customModelName + ')' : ''
|
||||
}:`
|
||||
: t('Loading...')}
|
||||
</p>
|
||||
<AnswerTitle descName={descName} modelName={modelName} />
|
||||
<div className="gpt-util-group">
|
||||
{onRetry && (
|
||||
<span title={t('Retry')} className="gpt-util-icon" onClick={onRetry}>
|
||||
<SyncIcon size={14} />
|
||||
</span>
|
||||
)}
|
||||
{session && (
|
||||
{modelName && (
|
||||
<CopyButton contentFn={() => content.replace(/\n<hr\/>$/, '')} size={14} />
|
||||
)}
|
||||
{session && <ReadButton contentFn={() => content} size={14} />}
|
||||
{modelName && <ReadButton contentFn={() => content} size={14} />}
|
||||
{!collapsed ? (
|
||||
<span
|
||||
title={t('Collapse')}
|
||||
@@ -128,8 +140,9 @@ export function ConversationItem({ type, content, session, onRetry }) {
|
||||
ConversationItem.propTypes = {
|
||||
type: PropTypes.oneOf(['question', 'answer', 'error']).isRequired,
|
||||
content: PropTypes.string.isRequired,
|
||||
session: PropTypes.object.isRequired,
|
||||
descName: PropTypes.string,
|
||||
modelName: PropTypes.string,
|
||||
onRetry: PropTypes.func,
|
||||
}
|
||||
|
||||
export default ConversationItem
|
||||
export default memo(ConversationItem)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Browser from 'webextension-polyfill'
|
||||
import { cloneElement, useEffect, useState } from 'react'
|
||||
import { cloneElement, useCallback, useEffect, useState } from 'react'
|
||||
import ConversationCard from '../ConversationCard'
|
||||
import PropTypes from 'prop-types'
|
||||
import { config as toolsConfig } from '../../content-script/selection-tools'
|
||||
@@ -70,10 +70,18 @@ function FloatingToolbar(props) {
|
||||
updatePosition() // avoid jitter
|
||||
}
|
||||
|
||||
const onDock = () => {
|
||||
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}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user