From fc75fb64d255180a5ce83728343ccd4a65f7323e Mon Sep 17 00:00:00 2001 From: Louis Date: Mon, 2 Dec 2024 10:35:51 +0700 Subject: [PATCH] chore: refactor message container and types --- .../ThreadCenterPanel/ChatItem/index.tsx | 78 +------------------ .../TextMessage/DocMessage.tsx | 55 +++++++++++++ .../TextMessage/ImageMessage.tsx | 45 +++++++++++ .../TextMessage/RelativeImage.tsx | 4 +- .../ThreadCenterPanel/TextMessage/index.tsx | 23 +++++- 5 files changed, 124 insertions(+), 81 deletions(-) create mode 100644 web/screens/Thread/ThreadCenterPanel/TextMessage/DocMessage.tsx create mode 100644 web/screens/Thread/ThreadCenterPanel/TextMessage/ImageMessage.tsx diff --git a/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx b/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx index c7c05dca9..10d408211 100644 --- a/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/ChatItem/index.tsx @@ -1,7 +1,6 @@ -import React, { forwardRef, useEffect, useMemo, useState } from 'react' +import React, { forwardRef, useEffect, useState } from 'react' import { - ContentType, events, MessageEvent, MessageStatus, @@ -9,20 +8,9 @@ import { 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' +import MessageContainer from '../TextMessage' type Ref = HTMLDivElement @@ -39,13 +27,6 @@ const ChatItem = forwardRef((message, ref) => { ? 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) { @@ -73,60 +54,7 @@ const ChatItem = forwardRef((message, ref) => { <> {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 && ( diff --git a/web/screens/Thread/ThreadCenterPanel/TextMessage/DocMessage.tsx b/web/screens/Thread/ThreadCenterPanel/TextMessage/DocMessage.tsx new file mode 100644 index 000000000..9c0289734 --- /dev/null +++ b/web/screens/Thread/ThreadCenterPanel/TextMessage/DocMessage.tsx @@ -0,0 +1,55 @@ +import { memo } from 'react' + +import { Tooltip } from '@janhq/joi' + +import { FolderOpenIcon } from 'lucide-react' + +import { usePath } from '@/hooks/usePath' + +import { toGibibytes } from '@/utils/converter' +import { openFileTitle } from '@/utils/titleUtils' + +import Icon from '../FileUploadPreview/Icon' + +const DocMessage = ({ + id, + name, + size, +}: { + id: string + name?: string + size?: number +}) => { + const { onViewFile, onViewFileContainer } = usePath() + + return ( +
+
onViewFile(`${id}.pdf`)} + /> + + +
+ } + content={{openFileTitle()}} + /> + +
+
+ {name?.replaceAll(/[-._]/g, ' ')} +
+

+ {toGibibytes(Number(size))} +

+
+
+ ) +} + +export default memo(DocMessage) diff --git a/web/screens/Thread/ThreadCenterPanel/TextMessage/ImageMessage.tsx b/web/screens/Thread/ThreadCenterPanel/TextMessage/ImageMessage.tsx new file mode 100644 index 000000000..117f259c0 --- /dev/null +++ b/web/screens/Thread/ThreadCenterPanel/TextMessage/ImageMessage.tsx @@ -0,0 +1,45 @@ +import { memo, useMemo } from 'react' + +import { ThreadContent } from '@janhq/core' +import { Tooltip } from '@janhq/joi' + +import { FolderOpenIcon } from 'lucide-react' + +import { usePath } from '@/hooks/usePath' + +import { openFileTitle } from '@/utils/titleUtils' + +import { RelativeImage } from '../TextMessage/RelativeImage' + +const ImageMessage = ({ content }: { content: ThreadContent }) => { + const { onViewFile, onViewFileContainer } = usePath() + + const annotation = useMemo( + () => content?.text?.annotations[0] ?? '', + [content] + ) + + return ( +
+
+ onViewFile(annotation)} + /> +
+ + +
+ } + content={{openFileTitle()}} + /> + + ) +} + +export default memo(ImageMessage) diff --git a/web/screens/Thread/ThreadCenterPanel/TextMessage/RelativeImage.tsx b/web/screens/Thread/ThreadCenterPanel/TextMessage/RelativeImage.tsx index fda4c0755..72d2a9365 100644 --- a/web/screens/Thread/ThreadCenterPanel/TextMessage/RelativeImage.tsx +++ b/web/screens/Thread/ThreadCenterPanel/TextMessage/RelativeImage.tsx @@ -3,11 +3,9 @@ import { useEffect, useState } from 'react' import { getJanDataFolderPath } from '@janhq/core' export const RelativeImage = ({ - id, src, onClick, }: { - id: string src: string onClick: () => void }) => { @@ -22,7 +20,7 @@ export const RelativeImage = ({ diff --git a/web/screens/Thread/ThreadCenterPanel/TextMessage/index.tsx b/web/screens/Thread/ThreadCenterPanel/TextMessage/index.tsx index 905325e2e..7c4950b51 100644 --- a/web/screens/Thread/ThreadCenterPanel/TextMessage/index.tsx +++ b/web/screens/Thread/ThreadCenterPanel/TextMessage/index.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react' -import { ChatCompletionRole, ThreadMessage } from '@janhq/core' +import { ChatCompletionRole, ContentType, ThreadMessage } from '@janhq/core' import { useAtomValue } from 'jotai' import 'katex/dist/katex.min.css' @@ -13,6 +13,8 @@ import { displayDate } from '@/utils/datetime' import EditChatInput from '../EditChatInput' import MessageToolbar from '../MessageToolbar' +import DocMessage from './DocMessage' +import ImageMessage from './ImageMessage' import { MarkdownTextMessage } from './MarkdownTextMessage' import { @@ -22,7 +24,7 @@ import { } from '@/helpers/atoms/ChatMessage.atom' import { activeThreadAtom } from '@/helpers/atoms/Thread.atom' -const TextMessage: React.FC = (props) => { +const MessageContainer: React.FC = (props) => { const isUser = props.role === ChatCompletionRole.User const isSystem = props.role === ChatCompletionRole.System const editMessage = useAtomValue(editMessageAtom) @@ -35,6 +37,10 @@ const TextMessage: React.FC = (props) => { () => props.content[0]?.text?.value ?? '', [props.content] ) + const messageType = useMemo( + () => props.content[0]?.type ?? '', + [props.content] + ) return (
@@ -101,6 +107,17 @@ const TextMessage: React.FC = (props) => { )} > <> + {messageType === ContentType.Image && ( + + )} + {messageType === ContentType.Pdf && ( + + )} + {editMessage === props.id ? (
@@ -121,4 +138,4 @@ const TextMessage: React.FC = (props) => { ) } -export default React.memo(TextMessage) +export default React.memo(MessageContainer)