chore(chat): remove image previews, keep drag-to-reorder

This commit is contained in:
Nikunj Kohli
2025-10-27 09:39:38 +05:30
parent af0fe35282
commit a1a0387744
2 changed files with 42 additions and 75 deletions

View File

@@ -95,15 +95,9 @@ export default function MessageInput({
const xhr = new XMLHttpRequest();
const uniqueId = crypto.randomUUID();
// create preview for images
const isImage = file.type.startsWith('image/');
const previewUrl = isImage ? URL.createObjectURL(file) : undefined;
const newAttachment = {
id: uniqueId,
fileName: file.name,
previewUrl,
mimeType: file.type,
progress: 0,
status: 'uploading' as const,
taskId: '',
@@ -145,7 +139,6 @@ export default function MessageInput({
updates: { status: 'failed' },
}),
);
if (previewUrl) URL.revokeObjectURL(previewUrl);
}
};
@@ -156,7 +149,6 @@ export default function MessageInput({
updates: { status: 'failed' },
}),
);
if (previewUrl) URL.revokeObjectURL(previewUrl);
};
xhr.open('POST', `${apiHost}${endpoints.USER.STORE_ATTACHMENT}`);
@@ -277,15 +269,7 @@ export default function MessageInput({
// Drag state for reordering
const [draggingId, setDraggingId] = useState<string | null>(null);
// Revoke object URLs on unmount to avoid memory leaks
useEffect(() => {
return () => {
attachments.forEach((att) => {
if (att.previewUrl) URL.revokeObjectURL(att.previewUrl);
});
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// no preview object URLs to revoke (preview removed per reviewer request)
const findIndexById = (id: string) => attachments.findIndex((a) => a.id === id);
@@ -322,8 +306,6 @@ export default function MessageInput({
<div className="border-dark-gray bg-lotion dark:border-grey relative flex w-full flex-col rounded-[23px] border dark:bg-transparent">
<div className="flex flex-wrap gap-1.5 px-2 py-2 sm:gap-2 sm:px-3">
{attachments.map((attachment) => {
const isImage = attachment.mimeType?.startsWith?.('image/');
const index = attachments.findIndex((a) => a.id === attachment.id);
return (
<div
key={attachment.id}
@@ -336,61 +318,51 @@ export default function MessageInput({
} ${draggingId === attachment.id ? 'opacity-60 ring-2 ring-dashed ring-purple-200' : ''}`}
title={attachment.fileName}
>
<div className="mr-2 flex items-center justify-center">
{isImage && attachment.previewUrl ? (
<div className="bg-purple-30 mr-2 flex h-8 w-8 items-center justify-center rounded-md p-1">
{attachment.status === 'completed' && (
<img
src={attachment.previewUrl}
alt={attachment.fileName}
className="h-8 w-8 rounded-md object-cover"
src={DocumentationDark}
alt="Attachment"
className="h-[15px] w-[15px] object-fill"
/>
) : (
<div className="bg-purple-30 mr-2 flex h-8 w-8 items-center justify-center rounded-md p-1">
{attachment.status === 'completed' && (
<img
src={DocumentationDark}
alt="Attachment"
className="h-[15px] w-[15px] object-fill"
/>
)}
)}
{attachment.status === 'failed' && (
<img
src={AlertIcon}
alt="Failed"
className="h-[15px] w-[15px] object-fill"
/>
)}
{attachment.status === 'failed' && (
<img
src={AlertIcon}
alt="Failed"
className="h-[15px] w-[15px] object-fill"
/>
)}
{(attachment.status === 'uploading' ||
attachment.status === 'processing') && (
<div className="flex h-[15px] w-[15px] items-center justify-center">
<svg className="h-[15px] w-[15px]" viewBox="0 0 24 24">
<circle
className="opacity-0"
cx="12"
cy="12"
r="10"
stroke="transparent"
strokeWidth="4"
fill="none"
/>
<circle
className="text-[#ECECF1]"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
fill="none"
strokeDasharray="62.83"
strokeDashoffset={
62.83 * (1 - attachment.progress / 100)
}
transform="rotate(-90 12 12)"
/>
</svg>
</div>
)}
{(attachment.status === 'uploading' ||
attachment.status === 'processing') && (
<div className="flex h-[15px] w-[15px] items-center justify-center">
<svg className="h-[15px] w-[15px]" viewBox="0 0 24 24">
<circle
className="opacity-0"
cx="12"
cy="12"
r="10"
stroke="transparent"
strokeWidth="4"
fill="none"
/>
<circle
className="text-[#ECECF1]"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
fill="none"
strokeDasharray="62.83"
strokeDashoffset={
62.83 * (1 - attachment.progress / 100)
}
transform="rotate(-90 12 12)"
/>
</svg>
</div>
)}
</div>
@@ -402,7 +374,6 @@ export default function MessageInput({
<button
className="ml-1.5 flex items-center justify-center rounded-full p-1"
onClick={() => {
if (attachment.previewUrl) URL.revokeObjectURL(attachment.previewUrl);
dispatch(removeAttachment(attachment.id));
}}
aria-label={t('conversation.attachments.remove')}

View File

@@ -4,10 +4,6 @@ import { RootState } from '../store';
export interface Attachment {
id: string; // Unique identifier for the attachment (required for state management)
fileName: string;
// Optional preview URL for image thumbnails (object URL)
previewUrl?: string;
// MIME type of the original file
mimeType?: string;
progress: number;
status: 'uploading' | 'processing' | 'completed' | 'failed';
taskId: string; // Server-assigned task ID (used for API calls)