import React, { forwardRef, useEffect, useMemo, useState } from 'react' import { ContentType, events, MessageEvent, MessageStatus, ThreadContent, ThreadMessage, } from '@janhq/core' import { Tooltip } from '@janhq/joi' import { FolderOpenIcon } from 'lucide-react' import ErrorMessage from '@/containers/ErrorMessage' import { usePath } from '@/hooks/usePath' import { toGibibytes } from '@/utils/converter' import { openFileTitle } from '@/utils/titleUtils' import Icon from '../FileUploadPreview/Icon' import TextMessage from '../TextMessage' import { RelativeImage } from '../TextMessage/RelativeImage' type Ref = HTMLDivElement type Props = { loadModelError?: string isCurrentMessage?: boolean } & ThreadMessage const ChatItem = forwardRef((message, ref) => { const [content, setContent] = useState(message.content) const [status, setStatus] = useState(message.status) const [errorMessage, setErrorMessage] = useState( message.isCurrentMessage && message.status === MessageStatus.Error ? message : undefined ) const messageType = useMemo(() => content[0]?.type ?? '', [content]) const annotation = useMemo( () => content[0]?.text?.annotations[0] ?? '', [content] ) const { onViewFile, onViewFileContainer } = usePath() function onMessageUpdate(data: ThreadMessage) { if (data.id === message.id) { setContent(data.content) if (data.status !== status) setStatus(data.status) if (data.status === MessageStatus.Error && message.isCurrentMessage) setErrorMessage(data) } } useEffect(() => { if (!message.isCurrentMessage && errorMessage) setErrorMessage(undefined) }, [message, errorMessage]) 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 ( <> {status !== MessageStatus.Error && content?.length > 0 && (
{messageType === ContentType.Image && (
onViewFile(annotation)} />
} content={{openFileTitle()}} />
)} {messageType === ContentType.Pdf && (
onViewFile(`${message.id}.${messageType}`)} />
} content={{openFileTitle()}} />
{content[0].text.name?.replaceAll(/[-._]/g, ' ')}

{toGibibytes(Number(content[0].text.size))}

)} {messageType === ContentType.Text && ( )} )} {errorMessage && !message.loadModelError && ( )} ) }) export default ChatItem