Skip to content

Commit

Permalink
feat: performance optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
YanceyOfficial committed Dec 13, 2024
1 parent 151cd20 commit 3461e32
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 83 deletions.
39 changes: 31 additions & 8 deletions src/components/ChatBox/ChatBubble.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import classNames from 'classnames'
import { FC, memo, ReactNode } from 'react'
import { ChatCompletionContentPartText } from 'openai/resources'
import { FC, memo } from 'react'
import ChatGPTLogoImg from 'src/assets/chatbot.png'
import { useSettings } from 'src/hooks'
import { Message, Roles } from 'src/types/conversation'
import Avatar from '../Avatar'
import Markdown from './Markdown'
import ToolsBox from './ToolsBox'

interface Props {
message: Message
children: ReactNode
}

const ChatBubble: FC<Props> = ({ message, children }) => {
const ChatBubble: FC<Props> = ({ message }) => {
const { settings } = useSettings()

const getBotLogo = (role: Roles) =>
role === Roles.Assistant
? settings?.assistantAvatarFilename
Expand Down Expand Up @@ -49,15 +51,36 @@ const ChatBubble: FC<Props> = ({ message, children }) => {
message.role === Roles.User
})}
>
{children}
{message.role === Roles.Assistant && (
<Markdown
src={(message.content as ChatCompletionContentPartText[])[0].text}
/>
)}

{message.role === Roles.User && (
<div>
{message.content.map((item, key) => {
if (item.type === 'image_url') {
return (
<img
src={item.image_url.url}
key={key}
className="mb-2 max-w-80"
/>
)
}

if (item.type === 'text') {
return <p key={key}>{item.text}</p>
}
})}
</div>
)}
</section>
<ToolsBox message={message} />
</section>
</section>
)
}

export default memo(
ChatBubble,
(prevProps, nextProps) => prevProps.children === nextProps.children
)
export default memo(ChatBubble)
72 changes: 7 additions & 65 deletions src/components/ChatBox/ChatMessages.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import classNames from 'classnames'
import { ChatCompletionContentPartText } from 'openai/resources'
import { FC, memo, useMemo, useRef } from 'react'
import { FC, memo, useEffect, useMemo, useRef } from 'react'
import { useRecoilValue } from 'recoil'
import NoDataIllustration from 'src/assets/illustrations/no-data.svg'
import { isSupportAudio } from 'src/shared/utils'
import { currConversationState, loadingState } from 'src/stores/conversation'
import { currConversationState } from 'src/stores/conversation'
import { currProductState } from 'src/stores/global'
import { Message, Roles } from 'src/types/conversation'
import { Products } from 'src/types/global'
import Waveform from '../Waveform'
import { Message } from 'src/types/conversation'
import ChatBubble from './ChatBubble'
import Markdown from './Markdown'
import MessageSpinner from './MessageSpinner'

const ChatMessages: FC = () => {
const chatBoxRef = useRef<HTMLDivElement>(null)
const loading = useRecoilValue(loadingState)
const currProduct = useRecoilValue(currProductState)
const currConversation = useRecoilValue(currConversationState)
const hasMessages = useMemo(
Expand Down Expand Up @@ -43,9 +37,9 @@ const ChatMessages: FC = () => {
return ''
}

// useEffect(() => {
// scrollToBottom()
// }, [currConversation])
useEffect(() => {
scrollToBottom()
}, [currConversation])

return (
<section
Expand All @@ -58,60 +52,8 @@ const ChatMessages: FC = () => {
{hasMessages ? (
<>
{currConversation?.messages.map((message) => (
<ChatBubble key={message.messageId} message={message}>
{getAudioFilename(message) ? (
<>
<Waveform filename={getAudioFilename(message)} />
{message.content}
</>
) : (
<>
{loading && !message.content ? (
<MessageSpinner />
) : message.role === Roles.Assistant ? (
<Markdown
raw={
(message.content as ChatCompletionContentPartText[])[0]
.text
}
/>
) : (
<div>
{message.content.map((item, key) => {
if (item.type === 'image_url') {
return (
<img
src={item.image_url.url}
key={key}
className="mb-2 max-w-80"
/>
)
}

if (item.type === 'text') {
return <p key={key}>{item.text}</p>
}
})}
</div>
)}
</>
)}
</ChatBubble>
<ChatBubble key={message.messageId} message={message}></ChatBubble>
))}

{loading && currProduct !== Products.ChatCompletion && (
<ChatBubble
message={{
messageId: '$$placeholder',
role: Roles.Assistant,
content: [],
tokensCount: 0,
createdAt: +new Date()
}}
>
<MessageSpinner />
</ChatBubble>
)}
</>
) : (
<img
Expand Down
17 changes: 7 additions & 10 deletions src/components/ChatBox/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { marked, Tokens } from 'marked'
import { FC, memo, useCallback } from 'react'

interface Props {
raw: string
src: string
}

const Markdown: FC<Props> = ({ raw }) => {
const Markdown: FC<Props> = memo(({ src }) => {
const parseMarkdown = useCallback(() => {
const renderer = new marked.Renderer()

Expand All @@ -29,24 +29,21 @@ const Markdown: FC<Props> = ({ raw }) => {
return `<img src="${href}" alt="${text}" class="mb-3" loading="lazy" />`
}

renderer.link = ({ href, title, text }: Tokens.Link) => {
renderer.link = ({ href, text }: Tokens.Link) => {
return `<a href="${href}" target="_blank" rel="noopener noreferrer" class="font-bold underline">${text}</a>`
}

return marked(raw, {
return marked(src, {
renderer
})
}, [raw])
}, [src])

return (
<section
className="markdown"
dangerouslySetInnerHTML={{ __html: parseMarkdown() }}
/>
)
}
})

export default memo(
Markdown,
(prevProps, nextProps) => prevProps.raw === nextProps.raw
)
export default Markdown

0 comments on commit 3461e32

Please sign in to comment.