diff --git a/components/contacts/__tests__/contact-form.test.tsx b/components/contacts/__tests__/contact-form.test.tsx
index 530c086a..75f4375b 100644
--- a/components/contacts/__tests__/contact-form.test.tsx
+++ b/components/contacts/__tests__/contact-form.test.tsx
@@ -62,6 +62,27 @@ describe('ContactForm', () => {
expect(phoneAfter.length).toBe(phoneBefore.length + 1);
});
+ it('sends media: null when an existing photo is removed', async () => {
+ const onSave = vi.fn().mockResolvedValue(undefined);
+ const contactWithPhoto: ContactCard = {
+ ...existingContact,
+ media: {
+ photo: { kind: 'photo', uri: 'data:image/png;base64,AAAA', mediaType: 'image/png' },
+ },
+ };
+ render();
+
+ fireEvent.click(screen.getByText('remove_photo'));
+ fireEvent.submit(screen.getByText('save').closest('form')!);
+
+ await waitFor(() => {
+ expect(onSave).toHaveBeenCalledOnce();
+ });
+
+ const savedData = onSave.mock.calls[0][0];
+ expect(savedData.media).toBeNull();
+ });
+
it('submits form data correctly', async () => {
const onSave = vi.fn().mockResolvedValue(undefined);
render();
diff --git a/components/contacts/contact-form.tsx b/components/contacts/contact-form.tsx
index ebf6fe1c..697e9cc0 100644
--- a/components/contacts/contact-form.tsx
+++ b/components/contacts/contact-form.tsx
@@ -525,6 +525,11 @@ export function ContactForm({ contact, addressBooks, allKeywords, defaultAddress
mediaMap[photoKey] = { kind: "photo", uri: photoUri, mediaType: photoMediaType };
}
+ // Set mediaVluae to null if we are removing media, so the server removes it
+ const hadMedia = !!contact?.media && Object.keys(contact.media).length > 0;
+ const mediaValue: Record | null | undefined =
+ Object.keys(mediaMap).length > 0 ? mediaMap : (hadMedia ? null : undefined);
+
const data: Partial = {
name: { components: nameComponents, isOrdered: true },
nicknames: nickname.trim() ? { n0: { name: nickname.trim() } } : undefined,
@@ -551,7 +556,7 @@ export function ContactForm({ contact, addressBooks, allKeywords, defaultAddress
calendarUri: calendarUri.trim() || undefined,
schedulingUri: schedulingUri.trim() || undefined,
freeBusyUri: freeBusyUri.trim() || undefined,
- media: Object.keys(mediaMap).length > 0 ? mediaMap : undefined,
+ media: mediaValue as Record | undefined,
...(selectedBookId ? { addressBookIds: { [selectedBookId]: true } } : {}),
};