Skip to content

Commit a2160b9

Browse files
committed
improve attachment logic
1 parent a01bb75 commit a2160b9

File tree

1 file changed

+51
-48
lines changed
  • client/packages/lowcoder/src/comps/comps/chatComp/components/ui

1 file changed

+51
-48
lines changed

client/packages/lowcoder/src/comps/comps/chatComp/components/ui/attachment.tsx

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -144,73 +144,76 @@ const ScreenReaderOnly = styled.span`
144144
overflow: hidden;
145145
`;
146146

147-
// ============================================================================
148-
// UTILITY HOOKS
149-
// ============================================================================
150-
151-
152-
const useFileSrc = (file: File | undefined) => {
153-
const [src, setSrc] = useState<string | undefined>();
154-
const lastFileRef = useRef<File>();
155-
156-
useEffect(() => {
157-
if (!file || file === lastFileRef.current) return;
158-
159-
const objectUrl = URL.createObjectURL(file);
160-
setSrc(objectUrl);
161-
lastFileRef.current = file;
162-
163-
return () => {
164-
URL.revokeObjectURL(objectUrl);
165-
};
166-
}, [file]);
167-
168-
return src;
169-
};
170-
171-
172147

173148
const useAttachmentSrc = () => {
149+
// Listen only to image-type attachments
174150
const attachment = useAttachment(
175-
useCallback((a: any) => {
176-
if (a.type !== "image") return undefined;
177-
return a;
178-
}, [])
151+
useCallback((a: any) => (a.type === "image" ? a : undefined), [])
179152
);
180153

181154
const [src, setSrc] = useState<string | undefined>();
182-
const lastAttachmentRef = useRef<any>();
183155

184-
useEffect(() => {
185-
if (!attachment || attachment === lastAttachmentRef.current) return;
156+
// Keep track of the last generated object URL so that we can revoke it
157+
const objectUrlRef = useRef<string | undefined>();
158+
const lastAttachmentIdRef = useRef<string | undefined>();
186159

187-
// Handle new/pending attachments with File objects
188-
if (attachment.file && attachment.file instanceof File) {
189-
const objectUrl = URL.createObjectURL(attachment.file);
190-
setSrc(objectUrl);
191-
lastAttachmentRef.current = attachment;
160+
useEffect(() => {
161+
// If the same attachment is rendered again, do nothing
162+
if (!attachment || attachment.id === lastAttachmentIdRef.current) return;
163+
164+
// Clean up any previous object URL
165+
if (objectUrlRef.current) {
166+
try {
167+
URL.revokeObjectURL(objectUrlRef.current);
168+
} catch {
169+
/* ignore */
170+
}
171+
objectUrlRef.current = undefined;
172+
}
192173

193-
return () => {
194-
URL.revokeObjectURL(objectUrl);
195-
};
174+
// ------------------------------------------------------------------
175+
// 1. New (local) File object – generate a temporary ObjectURL
176+
// ------------------------------------------------------------------
177+
if (attachment.file instanceof File) {
178+
const url = URL.createObjectURL(attachment.file);
179+
objectUrlRef.current = url;
180+
setSrc(url);
181+
lastAttachmentIdRef.current = attachment.id;
182+
return;
196183
}
197184

198-
// Handle saved attachments with base64 data
199-
const imageContent = attachment.content?.find((c: any) => c.type === "image");
200-
if (imageContent?.image) {
201-
setSrc(imageContent.image);
202-
lastAttachmentRef.current = attachment;
185+
// ------------------------------------------------------------------
186+
// 2. Restored attachment coming from storage – use stored base64 image
187+
// ------------------------------------------------------------------
188+
const imgPart = attachment.content?.find((p: any) => p.type === "image");
189+
if (imgPart?.image) {
190+
setSrc(imgPart.image as string);
191+
lastAttachmentIdRef.current = attachment.id;
203192
return;
204193
}
205194

206-
// If no valid source found, clear the src
195+
// ------------------------------------------------------------------
196+
// 3. No usable preview – clear src
197+
// ------------------------------------------------------------------
207198
setSrc(undefined);
208-
lastAttachmentRef.current = attachment;
199+
lastAttachmentIdRef.current = attachment.id;
209200
}, [attachment]);
210201

202+
/* Cleanup when the component using this hook unmounts */
203+
useEffect(() => {
204+
return () => {
205+
if (objectUrlRef.current) {
206+
try {
207+
URL.revokeObjectURL(objectUrlRef.current);
208+
} catch {
209+
/* ignore */
210+
}
211+
}
212+
};
213+
}, []);
214+
211215
return src;
212216
};
213-
214217
// ============================================================================
215218
// ATTACHMENT COMPONENTS
216219
// ============================================================================

0 commit comments

Comments
 (0)