From d622cf7c88c7aade17786cde329ce79acc390d23 Mon Sep 17 00:00:00 2001 From: martincupela Date: Wed, 8 Oct 2025 21:52:04 +0200 Subject: [PATCH 1/2] feat: add optional Delete for me message action --- src/components/Channel/Channel.tsx | 15 +++-- .../Channel/__tests__/Channel.test.js | 18 ++++-- .../hooks/useCreateChannelStateContext.ts | 5 +- .../Message/__tests__/utils.test.js | 57 +++++++++++-------- .../hooks/__tests__/useDeleteHandler.test.js | 17 +++++- .../Message/hooks/useDeleteHandler.ts | 12 +++- src/components/Message/utils.tsx | 10 +++- .../MessageActions/MessageActionsBox.tsx | 13 ++++- .../__tests__/MessageActionsBox.test.js | 14 +++++ src/context/ChannelActionContext.tsx | 6 +- src/context/MessageContext.tsx | 8 ++- src/i18n/de.json | 1 + src/i18n/en.json | 1 + src/i18n/es.json | 1 + src/i18n/fr.json | 1 + src/i18n/hi.json | 1 + src/i18n/it.json | 1 + src/i18n/ja.json | 1 + src/i18n/ko.json | 1 + src/i18n/nl.json | 1 + src/i18n/pt.json | 1 + src/i18n/ru.json | 1 + src/i18n/tr.json | 1 + 23 files changed, 141 insertions(+), 46 deletions(-) diff --git a/src/components/Channel/Channel.tsx b/src/components/Channel/Channel.tsx index 296976705a..c2bc6fb4d2 100644 --- a/src/components/Channel/Channel.tsx +++ b/src/components/Channel/Channel.tsx @@ -18,6 +18,7 @@ import type { ChannelMemberResponse, ChannelQueryOptions, ChannelState, + DeleteMessageOptions, ErrorFromResponse, Event, EventAPIResponse, @@ -176,7 +177,10 @@ export type ChannelProps = ChannelPropsForwardedToComponentContext & { */ channelQueryOptions?: ChannelQueryOptions; /** Custom action handler to override the default `client.deleteMessage(message.id)` function */ - doDeleteMessageRequest?: (message: LocalMessage) => Promise; + doDeleteMessageRequest?: ( + message: LocalMessage, + options?: DeleteMessageOptions, + ) => Promise; /** Custom action handler to override the default `channel.markRead` request function (advanced usage only) */ doMarkReadRequest?: ( channel: StreamChannel, @@ -910,15 +914,18 @@ const ChannelInner = ( ); const deleteMessage = useCallback( - async (message: LocalMessage): Promise => { + async ( + message: LocalMessage, + options?: DeleteMessageOptions, + ): Promise => { if (!message?.id) { throw new Error('Cannot delete a message - missing message ID.'); } let deletedMessage; if (doDeleteMessageRequest) { - deletedMessage = await doDeleteMessageRequest(message); + deletedMessage = await doDeleteMessageRequest(message, options); } else { - const result = await client.deleteMessage(message.id); + const result = await client.deleteMessage(message.id, options); deletedMessage = result.message; } diff --git a/src/components/Channel/__tests__/Channel.test.js b/src/components/Channel/__tests__/Channel.test.js index 2d9139bc48..0ec95580a7 100644 --- a/src/components/Channel/__tests__/Channel.test.js +++ b/src/components/Channel/__tests__/Channel.test.js @@ -1603,15 +1603,18 @@ describe('Channel', () => { it('should call the default client.deleteMessage() function', async () => { const message = generateMessage(); - + const deleteMessageOptions = { deleteForMe: true, hard: false }; const clientDeleteMessageSpy = jest .spyOn(chatClient, 'deleteMessage') .mockImplementationOnce(() => Promise.resolve({ message })); await renderComponent({ channel, chatClient }, ({ deleteMessage }) => { - deleteMessage(message); + deleteMessage(message, deleteMessageOptions); }); await waitFor(() => - expect(clientDeleteMessageSpy).toHaveBeenCalledWith(message.id), + expect(clientDeleteMessageSpy).toHaveBeenCalledWith( + message.id, + deleteMessageOptions, + ), ); }); @@ -1640,7 +1643,7 @@ describe('Channel', () => { it('should call the custom doDeleteMessageRequest instead of client.deleteMessage()', async () => { const message = generateMessage(); - + const deleteMessageOptions = { deleteForMe: true, hard: false }; const doDeleteMessageRequest = jest.fn(); const clientDeleteMessageSpy = jest .spyOn(chatClient, 'deleteMessage') @@ -1649,13 +1652,16 @@ describe('Channel', () => { await renderComponent( { channel, chatClient, doDeleteMessageRequest }, ({ deleteMessage }) => { - deleteMessage(message); + deleteMessage(message, deleteMessageOptions); }, ); await waitFor(() => { expect(clientDeleteMessageSpy).not.toHaveBeenCalled(); - expect(doDeleteMessageRequest).toHaveBeenCalledWith(message); + expect(doDeleteMessageRequest).toHaveBeenCalledWith( + message, + deleteMessageOptions, + ); }); }); }); diff --git a/src/components/Channel/hooks/useCreateChannelStateContext.ts b/src/components/Channel/hooks/useCreateChannelStateContext.ts index 9a4aafdc8b..d53c17221e 100644 --- a/src/components/Channel/hooks/useCreateChannelStateContext.ts +++ b/src/components/Channel/hooks/useCreateChannelStateContext.ts @@ -59,6 +59,8 @@ export const useCreateChannelStateContext = ( channelCapabilities[capability] = true; }); + // FIXME: this is crazy - I could not find out why the messages were not getting updated when only message properties that are not part + // of this serialization has been changed. A great example of memoization gone wrong. const memoizedMessageData = skipMessageDataMemoization ? messages : messages @@ -69,10 +71,11 @@ export const useCreateChannelStateContext = ( pinned, reply_count, status, + type, updated_at, user, }) => - `${deleted_at}${ + `${type}${deleted_at}${ latest_reactions ? latest_reactions.map(({ type }) => type).join() : '' }${pinned}${reply_count}${status}${ updated_at && (isDayOrMoment(updated_at) || isDate(updated_at)) diff --git a/src/components/Message/__tests__/utils.test.js b/src/components/Message/__tests__/utils.test.js index 08d468d815..e42898475b 100644 --- a/src/components/Message/__tests__/utils.test.js +++ b/src/components/Message/__tests__/utils.test.js @@ -17,6 +17,7 @@ import { MESSAGE_ACTIONS, messageHasAttachments, messageHasReactions, + OPTIONAL_MESSAGE_ACTIONS, validateAndGetMessage, } from '../utils'; @@ -90,6 +91,7 @@ describe('Message utils', () => { canReply: true, }; const actions = Object.values(MESSAGE_ACTIONS); + const optionalActions = Object.values(OPTIONAL_MESSAGE_ACTIONS); it.each([ ['empty', []], @@ -131,31 +133,36 @@ describe('Message utils', () => { }); it.each([ - ['allow', 'edit', 'canEdit', true], - ['not allow', 'edit', 'canEdit', false], - ['allow', 'delete', 'canDelete', true], - ['not allow', 'delete', 'canDelete', false], - ['allow', 'flag', 'canFlag', true], - ['not allow', 'flag', 'canFlag', false], - ['allow', 'markUnread', 'canMarkUnread', true], - ['not allow', 'markUnread', 'canMarkUnread', false], - ['allow', 'mute', 'canMute', true], - ['not allow', 'mute', 'canMute', false], - ['allow', 'pin', 'canPin', true], - ['not allow', 'pin', 'canPin', false], - ['allow', 'quote', 'canQuote', true], - ['not allow', 'quote', 'canQuote', false], - ])('it should %s %s when %s is %s', (_, action, capabilityKey, capabilityValue) => { - const capabilities = { - [capabilityKey]: capabilityValue, - }; - const result = getMessageActions(actions, capabilities); - if (capabilityValue) { - expect(result).toStrictEqual([action]); - } else { - expect(result).not.toStrictEqual([action]); - } - }); + ['allow', 'edit', 'canEdit', true, actions], + ['not allow', 'edit', 'canEdit', false, actions], + ['allow', 'delete', 'canDelete', true, actions], + ['not allow', 'delete', 'canDelete', false, actions], + ['allow', 'deleteForMe', 'canDelete', true, optionalActions], + ['not allow', 'deleteForMe', 'canDelete', false, optionalActions], + ['allow', 'flag', 'canFlag', true, actions], + ['not allow', 'flag', 'canFlag', false, actions], + ['allow', 'markUnread', 'canMarkUnread', true, actions], + ['not allow', 'markUnread', 'canMarkUnread', false, actions], + ['allow', 'mute', 'canMute', true, actions], + ['not allow', 'mute', 'canMute', false, actions], + ['allow', 'pin', 'canPin', true, actions], + ['not allow', 'pin', 'canPin', false, actions], + ['allow', 'quote', 'canQuote', true, actions], + ['not allow', 'quote', 'canQuote', false, actions], + ])( + 'it should %s %s when %s is %s', + (_, action, capabilityKey, capabilityValue, actionsToUse) => { + const capabilities = { + [capabilityKey]: capabilityValue, + }; + const result = getMessageActions(actionsToUse, capabilities); + if (capabilityValue) { + expect(result).toStrictEqual([action]); + } else { + expect(result).not.toStrictEqual([action]); + } + }, + ); }); describe('shouldMessageComponentUpdate', () => { diff --git a/src/components/Message/hooks/__tests__/useDeleteHandler.test.js b/src/components/Message/hooks/__tests__/useDeleteHandler.test.js index 3ddd469c74..999f88926c 100644 --- a/src/components/Message/hooks/__tests__/useDeleteHandler.test.js +++ b/src/components/Message/hooks/__tests__/useDeleteHandler.test.js @@ -75,9 +75,22 @@ describe('useDeleteHandler custom hook', () => { it('should delete a message by its id', async () => { const message = generateMessage(); + const deleteMessageOptions = { deleteForMe: true, hard: false }; const handleDelete = await renderUseDeleteHandler(message); - await handleDelete(mouseEventMock); - expect(deleteMessage).toHaveBeenCalledWith(message); + await handleDelete(mouseEventMock, deleteMessageOptions); + expect(deleteMessage).toHaveBeenCalledWith(message, deleteMessageOptions); + }); + + it('should enrich the message in the delete response with deleted_for_me and type="deleted"', async () => { + jest.spyOn(client, 'deleteMessage').mockResolvedValueOnce({ message: testMessage }); + const deleteMessageOptions = { deleteForMe: true, hard: false }; + const handleDelete = await renderUseDeleteHandler(testMessage); + await handleDelete(mouseEventMock, deleteMessageOptions); + expect(updateMessage).toHaveBeenCalledWith({ + ...testMessage, + deleted_for_me: true, + type: 'deleted', + }); }); it('should update the message with the result of deletion', async () => { diff --git a/src/components/Message/hooks/useDeleteHandler.ts b/src/components/Message/hooks/useDeleteHandler.ts index f51dc8bb89..5ed588b9df 100644 --- a/src/components/Message/hooks/useDeleteHandler.ts +++ b/src/components/Message/hooks/useDeleteHandler.ts @@ -4,7 +4,7 @@ import { useChannelActionContext } from '../../../context/ChannelActionContext'; import { useChatContext } from '../../../context/ChatContext'; import { useTranslationContext } from '../../../context/TranslationContext'; -import type { LocalMessage } from 'stream-chat'; +import type { DeleteMessageOptions, LocalMessage } from 'stream-chat'; import type { ReactEventHandler } from '../types'; export type DeleteMessageNotifications = { @@ -22,14 +22,20 @@ export const useDeleteHandler = ( const { client } = useChatContext('useDeleteHandler'); const { t } = useTranslationContext('useDeleteHandler'); - return async (event) => { + return async (event, options?: DeleteMessageOptions) => { event.preventDefault(); if (!message?.id || !client || !updateMessage) { return; } try { - const deletedMessage = await deleteMessage(message); + const deletedMessage = await deleteMessage(message, options); + // necessary to populate the below values as the server does not return the message in the response as deleted + if (options?.deleteForMe) { + // deleted_at is not available for messages that are deleted_for_me + deletedMessage.deleted_for_me = true; + deletedMessage.type = 'deleted'; + } updateMessage(deletedMessage); } catch (e) { const errorMessage = diff --git a/src/components/Message/utils.tsx b/src/components/Message/utils.tsx index 7c7d7720e3..ae04a5c904 100644 --- a/src/components/Message/utils.tsx +++ b/src/components/Message/utils.tsx @@ -52,6 +52,10 @@ export const isUserMuted = (message: LocalMessage, mutes?: Mute[]) => { return !!userMuted.length; }; +export const OPTIONAL_MESSAGE_ACTIONS = { + deleteForMe: 'deleteForMe', +}; + export const MESSAGE_ACTIONS = { delete: 'delete', edit: 'edit', @@ -67,7 +71,7 @@ export const MESSAGE_ACTIONS = { }; export type MessageActionsArray = Array< - keyof typeof MESSAGE_ACTIONS | T + keyof typeof MESSAGE_ACTIONS | keyof typeof OPTIONAL_MESSAGE_ACTIONS | T >; // @deprecated in favor of `channelCapabilities` - TODO: remove in next major release @@ -172,6 +176,10 @@ export const getMessageActions = ( messageActionsAfterPermission.push(MESSAGE_ACTIONS.delete); } + if (canDelete && messageActions.indexOf(OPTIONAL_MESSAGE_ACTIONS.deleteForMe) > -1) { + messageActionsAfterPermission.push(OPTIONAL_MESSAGE_ACTIONS.deleteForMe); + } + if (canEdit && messageActions.indexOf(MESSAGE_ACTIONS.edit) > -1) { messageActionsAfterPermission.push(MESSAGE_ACTIONS.edit); } diff --git a/src/components/MessageActions/MessageActionsBox.tsx b/src/components/MessageActions/MessageActionsBox.tsx index 17c57a109a..0a6c4392b6 100644 --- a/src/components/MessageActions/MessageActionsBox.tsx +++ b/src/components/MessageActions/MessageActionsBox.tsx @@ -3,7 +3,7 @@ import type { ComponentProps } from 'react'; import React from 'react'; import { CustomMessageActionsList as DefaultCustomMessageActionsList } from './CustomMessageActionsList'; import { RemindMeActionButton } from './RemindMeSubmenu'; -import { useMessageReminder } from '../Message'; +import { OPTIONAL_MESSAGE_ACTIONS, useMessageReminder } from '../Message'; import { useMessageComposer } from '../MessageInput'; import { useChatContext, @@ -162,6 +162,17 @@ const UnMemoizedMessageActionsBox = (props: MessageActionsBoxProps) => { {t('Delete')} )} + {messageActions.indexOf(OPTIONAL_MESSAGE_ACTIONS.deleteForMe) > -1 && + !message.deleted_for_me && ( + + )} {messageActions.indexOf(MESSAGE_ACTIONS.remindMe) > -1 && ( )} diff --git a/src/components/MessageActions/__tests__/MessageActionsBox.test.js b/src/components/MessageActions/__tests__/MessageActionsBox.test.js index 14a62bad58..427cb297ff 100644 --- a/src/components/MessageActions/__tests__/MessageActionsBox.test.js +++ b/src/components/MessageActions/__tests__/MessageActionsBox.test.js @@ -179,6 +179,20 @@ describe('MessageActionsBox', () => { expect(results).toHaveNoViolations(); }); + it('should call the handleDelete prop if the deleteForMe button is clicked', async () => { + getMessageActionsMock.mockImplementationOnce(() => ['deleteForMe']); + const handleDelete = jest.fn(); + const { + result: { container, getByText }, + } = await renderComponent({ handleDelete, message: generateMessage() }); + await act(async () => { + await fireEvent.click(getByText('Delete for me')); + }); + expect(handleDelete).toHaveBeenCalledTimes(1); + const results = await axe(container); + expect(results).toHaveNoViolations(); + }); + it('should call the handlePin prop if the pin button is clicked', async () => { getMessageActionsMock.mockImplementationOnce(() => ['pin']); const handlePin = jest.fn(); diff --git a/src/context/ChannelActionContext.tsx b/src/context/ChannelActionContext.tsx index e7ed002e99..036f2135b2 100644 --- a/src/context/ChannelActionContext.tsx +++ b/src/context/ChannelActionContext.tsx @@ -2,6 +2,7 @@ import type { PropsWithChildren } from 'react'; import React, { useContext } from 'react'; import type { + DeleteMessageOptions, LocalMessage, Message, MessageResponse, @@ -29,7 +30,10 @@ export type RetrySendMessage = (message: LocalMessage) => Promise; export type ChannelActionContextValue = { addNotification: (text: string, type: 'success' | 'error') => void; closeThread: (event?: React.BaseSyntheticEvent) => void; - deleteMessage: (message: LocalMessage) => Promise; + deleteMessage: ( + message: LocalMessage, + options?: DeleteMessageOptions, + ) => Promise; dispatch: React.Dispatch; editMessage: ( message: LocalMessage | MessageResponse, diff --git a/src/context/MessageContext.tsx b/src/context/MessageContext.tsx index cb7f30c463..7455d4697b 100644 --- a/src/context/MessageContext.tsx +++ b/src/context/MessageContext.tsx @@ -1,7 +1,8 @@ -import type { PropsWithChildren, ReactNode } from 'react'; +import type { BaseSyntheticEvent, PropsWithChildren, ReactNode } from 'react'; import React, { useContext } from 'react'; import type { + DeleteMessageOptions, LocalMessage, Mute, ReactionResponse, @@ -48,7 +49,10 @@ export type MessageContextValue = { /** Function to send an action in a Channel */ handleAction: ActionHandlerReturnType; /** Function to delete a message in a Channel */ - handleDelete: ReactEventHandler; + handleDelete: ( + event: BaseSyntheticEvent, + options?: DeleteMessageOptions, + ) => Promise | void; /** Function to edit a message in a Channel */ handleEdit: ReactEventHandler; /** Function to fetch the message reactions */ diff --git a/src/i18n/de.json b/src/i18n/de.json index b7872ed9ad..8e560c32d6 100644 --- a/src/i18n/de.json +++ b/src/i18n/de.json @@ -29,6 +29,7 @@ "Create poll": "Umfrage erstellen", "Current location": "Aktueller Standort", "Delete": "Löschen", + "Delete for me": "Für mich löschen", "Delivered": "Zugestellt", "Download attachment {{ name }}": "Anhang {{ name }} herunterladen", "Drag your files here": "Ziehen Sie Ihre Dateien hierher", diff --git a/src/i18n/en.json b/src/i18n/en.json index a2bf551dd8..0c17e6dfa5 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -29,6 +29,7 @@ "Create poll": "Create poll", "Current location": "Current location", "Delete": "Delete", + "Delete for me": "Delete for me", "Delivered": "Delivered", "Download attachment {{ name }}": "Download attachment {{ name }}", "Drag your files here": "Drag your files here", diff --git a/src/i18n/es.json b/src/i18n/es.json index 81241a7ad8..7c10bd0dff 100644 --- a/src/i18n/es.json +++ b/src/i18n/es.json @@ -29,6 +29,7 @@ "Create poll": "Crear encuesta", "Current location": "Ubicación actual", "Delete": "Borrar", + "Delete for me": "Eliminar para mí", "Delivered": "Entregado", "Download attachment {{ name }}": "Descargar adjunto {{ name }}", "Drag your files here": "Arrastra tus archivos aquí", diff --git a/src/i18n/fr.json b/src/i18n/fr.json index 3ea9af2c0d..4ecc8f6f10 100644 --- a/src/i18n/fr.json +++ b/src/i18n/fr.json @@ -29,6 +29,7 @@ "Create poll": "Créer un sondage", "Current location": "Emplacement actuel", "Delete": "Supprimer", + "Delete for me": "Supprimer pour moi", "Delivered": "Publié", "Download attachment {{ name }}": "Télécharger la pièce jointe {{ name }}", "Drag your files here": "Glissez vos fichiers ici", diff --git a/src/i18n/hi.json b/src/i18n/hi.json index 7c24f40ab3..a3bf26e80d 100644 --- a/src/i18n/hi.json +++ b/src/i18n/hi.json @@ -29,6 +29,7 @@ "Create poll": "मतदान बनाएँ", "Current location": "वर्तमान स्थान", "Delete": "डिलीट", + "Delete for me": "मेरे लिए डिलीट करें", "Delivered": "पहुंच गया", "Download attachment {{ name }}": "अनुलग्नक {{ name }} डाउनलोड करें", "Drag your files here": "अपनी फ़ाइलें यहाँ खींचें", diff --git a/src/i18n/it.json b/src/i18n/it.json index 3feee54e0c..a143fb63b5 100644 --- a/src/i18n/it.json +++ b/src/i18n/it.json @@ -29,6 +29,7 @@ "Create poll": "Crea sondaggio", "Current location": "Posizione attuale", "Delete": "Elimina", + "Delete for me": "Elimina per me", "Delivered": "Consegnato", "Download attachment {{ name }}": "Scarica l'allegato {{ name }}", "Drag your files here": "Trascina i tuoi file qui", diff --git a/src/i18n/ja.json b/src/i18n/ja.json index d036711dc3..eab97ed935 100644 --- a/src/i18n/ja.json +++ b/src/i18n/ja.json @@ -29,6 +29,7 @@ "Create poll": "投票を作成", "Current location": "現在の位置", "Delete": "消去", + "Delete for me": "自分用に削除", "Delivered": "配信しました", "Download attachment {{ name }}": "添付ファイル {{ name }} をダウンロード", "Drag your files here": "ここにファイルをドラッグ", diff --git a/src/i18n/ko.json b/src/i18n/ko.json index eabd666b44..45e1ae3394 100644 --- a/src/i18n/ko.json +++ b/src/i18n/ko.json @@ -29,6 +29,7 @@ "Create poll": "투표 생성", "Current location": "현재 위치", "Delete": "삭제", + "Delete for me": "나만 삭제", "Delivered": "배달됨", "Download attachment {{ name }}": "첨부 파일 {{ name }} 다운로드", "Drag your files here": "여기로 파일을 끌어다 놓으세요", diff --git a/src/i18n/nl.json b/src/i18n/nl.json index 5710546871..d981106a00 100644 --- a/src/i18n/nl.json +++ b/src/i18n/nl.json @@ -29,6 +29,7 @@ "Create poll": "Maak peiling", "Current location": "Huidige locatie", "Delete": "Verwijder", + "Delete for me": "Voor mij verwijderen", "Delivered": "Afgeleverd", "Download attachment {{ name }}": "Bijlage {{ name }} downloaden", "Drag your files here": "Sleep je bestanden hier naartoe", diff --git a/src/i18n/pt.json b/src/i18n/pt.json index 86683ed73a..a2713a4943 100644 --- a/src/i18n/pt.json +++ b/src/i18n/pt.json @@ -29,6 +29,7 @@ "Create poll": "Criar enquete", "Current location": "Localização atual", "Delete": "Excluir", + "Delete for me": "Excluir para mim", "Delivered": "Entregue", "Download attachment {{ name }}": "Baixar anexo {{ name }}", "Drag your files here": "Arraste seus arquivos aqui", diff --git a/src/i18n/ru.json b/src/i18n/ru.json index 9607a8710b..7e51cb53aa 100644 --- a/src/i18n/ru.json +++ b/src/i18n/ru.json @@ -29,6 +29,7 @@ "Create poll": "Создать опрос", "Current location": "Текущее местоположение", "Delete": "Удалить", + "Delete for me": "Удалить для меня", "Delivered": "Отправлено", "Download attachment {{ name }}": "Скачать вложение {{ name }}", "Drag your files here": "Перетащите ваши файлы сюда", diff --git a/src/i18n/tr.json b/src/i18n/tr.json index a57be10fff..e6328e2e4e 100644 --- a/src/i18n/tr.json +++ b/src/i18n/tr.json @@ -29,6 +29,7 @@ "Create poll": "Anket oluştur", "Current location": "Mevcut konum", "Delete": "Sil", + "Delete for me": "Benim için sil", "Delivered": "İletildi", "Download attachment {{ name }}": "Ek {{ name }}'i indir", "Drag your files here": "Dosyalarınızı buraya sürükleyin", From 6cd64d0b983bae6befb270558a0585085e6b6e18 Mon Sep 17 00:00:00 2001 From: martincupela Date: Thu, 9 Oct 2025 10:12:03 +0200 Subject: [PATCH 2/2] refactor: rely on delete message response enrichment of deleted-for-me message in LLC --- .../Message/hooks/__tests__/useDeleteHandler.test.js | 12 ------------ src/components/Message/hooks/useDeleteHandler.ts | 6 ------ 2 files changed, 18 deletions(-) diff --git a/src/components/Message/hooks/__tests__/useDeleteHandler.test.js b/src/components/Message/hooks/__tests__/useDeleteHandler.test.js index 999f88926c..c7bf98a6bf 100644 --- a/src/components/Message/hooks/__tests__/useDeleteHandler.test.js +++ b/src/components/Message/hooks/__tests__/useDeleteHandler.test.js @@ -81,18 +81,6 @@ describe('useDeleteHandler custom hook', () => { expect(deleteMessage).toHaveBeenCalledWith(message, deleteMessageOptions); }); - it('should enrich the message in the delete response with deleted_for_me and type="deleted"', async () => { - jest.spyOn(client, 'deleteMessage').mockResolvedValueOnce({ message: testMessage }); - const deleteMessageOptions = { deleteForMe: true, hard: false }; - const handleDelete = await renderUseDeleteHandler(testMessage); - await handleDelete(mouseEventMock, deleteMessageOptions); - expect(updateMessage).toHaveBeenCalledWith({ - ...testMessage, - deleted_for_me: true, - type: 'deleted', - }); - }); - it('should update the message with the result of deletion', async () => { const deleteMessageResponse = generateMessage(); deleteMessage.mockImplementationOnce(() => Promise.resolve(deleteMessageResponse)); diff --git a/src/components/Message/hooks/useDeleteHandler.ts b/src/components/Message/hooks/useDeleteHandler.ts index 5ed588b9df..6adcac545b 100644 --- a/src/components/Message/hooks/useDeleteHandler.ts +++ b/src/components/Message/hooks/useDeleteHandler.ts @@ -30,12 +30,6 @@ export const useDeleteHandler = ( try { const deletedMessage = await deleteMessage(message, options); - // necessary to populate the below values as the server does not return the message in the response as deleted - if (options?.deleteForMe) { - // deleted_at is not available for messages that are deleted_for_me - deletedMessage.deleted_for_me = true; - deletedMessage.type = 'deleted'; - } updateMessage(deletedMessage); } catch (e) { const errorMessage =