diff --git a/frontend/src/components/Chat/ConversationEditor.test.tsx b/frontend/src/components/Chat/ConversationEditor.test.tsx index 7a557434c2..5d586f58b7 100644 --- a/frontend/src/components/Chat/ConversationEditor.test.tsx +++ b/frontend/src/components/Chat/ConversationEditor.test.tsx @@ -289,3 +289,18 @@ describe('ConversationEditor', () => { expect(onSaved).not.toHaveBeenCalled() }) }) + +it('revokes the blob URL when an attachment is removed from the editor', async () => { + const user = userEvent.setup() + const mockObjectUrl = 'blob:http://localhost/attach-1' + global.URL.createObjectURL = jest.fn().mockReturnValue(mockObjectUrl) + global.URL.revokeObjectURL = jest.fn() + setupEditor() + + const first = screen.getByRole('region', { name: 'Message 1' }) + await user.upload(within(first).getAllByTestId('file-input')[0], new File(['x'], 'photo.png', { type: 'image/png' })) + + await user.click(await screen.findByRole('button', { name: 'Remove photo.png' })) + + expect(global.URL.revokeObjectURL).toHaveBeenCalledWith(mockObjectUrl) +}) diff --git a/frontend/src/components/Chat/ConversationEditor.tsx b/frontend/src/components/Chat/ConversationEditor.tsx index 33c01c212e..c52b004046 100644 --- a/frontend/src/components/Chat/ConversationEditor.tsx +++ b/frontend/src/components/Chat/ConversationEditor.tsx @@ -101,8 +101,13 @@ function DraftPieceEditor({ piece, disabled, onChange, onAttachments, onConverte }) }, [media, onChange, piece.draftId]) const changeAttachments = useCallback((attachments: MessageAttachment[]): void => { + if (media) { + const nextUrls = new Set(attachments.map((attachment: MessageAttachment) => attachment.url)) + const current = draftAttachment(piece) + if (!nextUrls.has(current.url) && current.url.startsWith('blob:')) URL.revokeObjectURL(current.url) + } onAttachments(piece.draftId, attachments) - }, [onAttachments, piece.draftId]) + }, [media, piece, onAttachments]) const clearConversion = (): void => onChange(piece.draftId, (current: ConversationDraftPiece) => ({ ...current, converted_value: undefined, converted_value_data_type: undefined, applied_converter_ids: [], }))