diff --git a/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx index 38af2cfc0..d226c7e6f 100644 --- a/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx @@ -1,6 +1,6 @@ -import { memo } from 'react' +import { memo, useEffect, useState } from 'react' -import { MessageStatus } from '@janhq/core' +import { MessageStatus, ThreadMessage } from '@janhq/core' import { useAtomValue } from 'jotai' @@ -17,33 +17,67 @@ import EmptyThread from './EmptyThread' import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom' -const ChatBody = () => { +const ChatConfigurator = memo(() => { const messages = useAtomValue(getCurrentChatMessagesAtom) + const [current, setCurrent] = useState([]) + + const isMessagesIdentificial = ( + arr1: ThreadMessage[], + arr2: ThreadMessage[] + ): boolean => { + if (arr1.length !== arr2.length) return false + return arr1.every((item, index) => item.id === arr2[index].id) + } + + useEffect(() => { + if ( + messages.length !== current.length || + !isMessagesIdentificial(messages, current) + ) { + setCurrent(messages) + } + }, [messages, current]) + const loadModelError = useAtomValue(loadModelErrorAtom) if (!messages.length) return - return ( - - {messages.map((message, index) => ( -
- {message.status !== MessageStatus.Error && - message.content.length > 0 && ( +
+ +
+ ) +}) + +const ChatBody = memo( + ({ + messages, + loadModelError, + }: { + messages: ThreadMessage[] + loadModelError?: string + }) => { + return ( + + {messages.map((message, index) => ( +
+ {message.status !== MessageStatus.Error && ( )} - {!loadModelError && - index === messages.length - 1 && - message.status !== MessageStatus.Pending && - message.status !== MessageStatus.Ready && ( - - )} -
- ))} - {loadModelError && } -
- ) -} + {!loadModelError && + index === messages.length - 1 && + message.status !== MessageStatus.Pending && + message.status !== MessageStatus.Ready && ( + + )} +
+ ))} -export default memo(ChatBody) + {loadModelError && } +
+ ) + } +) + +export default memo(ChatConfigurator) diff --git a/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx index 1b12eff98..913333c6b 100644 --- a/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx @@ -1,15 +1,42 @@ -import React, { forwardRef } from 'react' +import React, { forwardRef, useEffect, useState } from 'react' -import { ThreadMessage } from '@janhq/core' +import { + events, + MessageEvent, + MessageStatus, + ThreadContent, + ThreadMessage, +} from '@janhq/core' import SimpleTextMessage from '../SimpleTextMessage' type Ref = HTMLDivElement -const ChatItem = forwardRef((message, ref) => ( -
- -
-)) +const ChatItem = forwardRef((message, ref) => { + const [content, setContent] = useState(message.content) + const [status, setStatus] = useState(message.status) + + function onMessageUpdate(data: ThreadMessage) { + if (data.id === message.id) { + setContent(data.content) + if (data.status !== status) setStatus(data.status) + } + } + + useEffect(() => { + if (message.status === MessageStatus.Pending) + events.on(MessageEvent.OnMessageUpdate, onMessageUpdate) + return () => { + events.off(MessageEvent.OnMessageUpdate, onMessageUpdate) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + return ( +
+ +
+ ) +}) export default ChatItem