diff --git a/frontend/src/components/chat/MessageComposer/Attachment.tsx b/frontend/src/components/chat/MessageComposer/Attachment.tsx index 5bdb336e3d..d5087044e2 100644 --- a/frontend/src/components/chat/MessageComposer/Attachment.tsx +++ b/frontend/src/components/chat/MessageComposer/Attachment.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useMemo } from 'react'; import { DefaultExtensionType, FileIcon, defaultStyles } from 'react-file-icon'; import { Card } from '@/components/ui/card'; @@ -13,9 +13,32 @@ interface AttachmentProps { name: string; mime: string; children?: React.ReactNode; + file?: File; } -const Attachment: React.FC = ({ name, mime, children }) => { +const Attachment: React.FC = ({ + name, + mime, + children, + file +}) => { + const isImage = useMemo(() => mime.startsWith('image/'), [mime]); + const imageUrl = useMemo(() => { + if (isImage && file) { + return URL.createObjectURL(file); + } + return undefined; + }, [isImage, file]); + + // Cleanup Object URL on unmount or when imageUrl changes + useEffect(() => { + return () => { + if (imageUrl) { + URL.revokeObjectURL(imageUrl); + } + }; + }, [imageUrl]); + let extension: DefaultExtensionType; if (name.includes('.')) { extension = name.split('.').pop()!.toLowerCase() as DefaultExtensionType; @@ -25,6 +48,30 @@ const Attachment: React.FC = ({ name, mime, children }) => { : ('txt' as DefaultExtensionType); } + if (isImage && imageUrl) { + return ( + + + +
+ {children} + + {name} + +
+
+ +

{name}

+
+
+
+ ); + } + return ( diff --git a/frontend/src/components/chat/MessageComposer/Attachments.tsx b/frontend/src/components/chat/MessageComposer/Attachments.tsx index ef96d6f1d6..a9418d8005 100644 --- a/frontend/src/components/chat/MessageComposer/Attachments.tsx +++ b/frontend/src/components/chat/MessageComposer/Attachments.tsx @@ -129,6 +129,7 @@ const Attachments = () => { key={attachment.id} name={attachment.name} mime={attachment.type} + file={attachment.file} > {progress} {remove} diff --git a/frontend/src/components/chat/index.tsx b/frontend/src/components/chat/index.tsx index d53575b71c..12a8f6cb7a 100644 --- a/frontend/src/components/chat/index.tsx +++ b/frontend/src/components/chat/index.tsx @@ -137,6 +137,7 @@ const Chat = () => { name: file.name, size: file.size, uploadProgress: 0, + file, cancel: () => { toast.info(`${t('chat.fileUpload.errors.cancelled')} ${file.name}`); xhr.abort(); diff --git a/frontend/src/state/chat.ts b/frontend/src/state/chat.ts index 6acd8cd513..0510db82f9 100644 --- a/frontend/src/state/chat.ts +++ b/frontend/src/state/chat.ts @@ -12,6 +12,7 @@ export interface IAttachment { uploaded?: boolean; cancel?: () => void; remove?: () => void; + file?: File; } export const attachmentsState = atom({