From 25627c0830d196b701bda5aa80d0d27277cd5fbf Mon Sep 17 00:00:00 2001 From: Bhupesh-MS Date: Thu, 25 Jul 2024 19:26:09 +0530 Subject: [PATCH 1/6] msg indicators added --- packages/lib/messaging/src/Message.ts | 54 +++++++++ packages/lib/messaging/src/index.ts | 2 + .../src/profileExtension/ProfileExtension.ts | 2 + .../src/components/Chat/Chat.tsx | 3 + .../src/components/Contacts/Contacts.tsx | 15 ++- .../src/components/Message/Message.css | 5 + .../src/components/Message/MessageDetail.tsx | 58 +++++++--- .../renderer/messageTypes/renderReadOpened.ts | 25 ++++ .../messageTypes/renderReadReceived.ts | 27 +++++ .../hooks/messages/renderer/renderMessage.ts | 6 +- .../handleMessagesFromDeliveryService.ts | 70 ++++++++++++ .../sources/handleMessagesFromWebSocket.ts | 41 ++++++- .../src/hooks/messages/useMessage.tsx | 107 +++++++++++++----- .../messenger-widget/src/interfaces/props.ts | 2 + 14 files changed, 368 insertions(+), 49 deletions(-) create mode 100644 packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadOpened.ts create mode 100644 packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadReceived.ts diff --git a/packages/lib/messaging/src/Message.ts b/packages/lib/messaging/src/Message.ts index fc3146a4a..9cfe3081e 100644 --- a/packages/lib/messaging/src/Message.ts +++ b/packages/lib/messaging/src/Message.ts @@ -44,6 +44,8 @@ export type MessageType = | 'EDIT' | 'REPLY' | 'REACTION' + | 'READ_OPENED' + | 'READ_RECEIVED' | 'READ_RECEIPT' | 'RESEND_REQUEST'; @@ -253,6 +255,58 @@ export async function createReactionMessage( ); } +/** + * creats a read opened message and signs it + * @param to sender ENS name + * @param from receiver ENS name + * @param message the message content + * @param privateKey sender signing key + * @param referenceMessageHash reference to previous message + */ +export async function createReadOpenMessage( + to: string, + from: string, + message: string, + privateKey: string, + referenceMessageHash: string, +): Promise { + return internalCreateMessage( + to, + from, + message, + privateKey, + 'READ_OPENED', + [], + referenceMessageHash, + ); +} + +/** + * creates a read received message and signs it + * @param to sender ENS name + * @param from receiver ENS name + * @param message the message content + * @param privateKey sender signing key + * @param referenceMessageHash reference to previous message + */ +export async function createReadReceiveMessage( + to: string, + from: string, + message: string, + privateKey: string, + referenceMessageHash: string, +): Promise { + return internalCreateMessage( + to, + from, + message, + privateKey, + 'READ_RECEIVED', + [], + referenceMessageHash, + ); +} + export async function checkMessageSignature( message: Message, publicSigningKey: string, diff --git a/packages/lib/messaging/src/index.ts b/packages/lib/messaging/src/index.ts index 2d8bbeeaa..c3de845b8 100644 --- a/packages/lib/messaging/src/index.ts +++ b/packages/lib/messaging/src/index.ts @@ -11,6 +11,8 @@ export { createEditMessage, createReactionMessage, createReplyMessage, + createReadOpenMessage, + createReadReceiveMessage, createJsonRpcCallSubmitMessage, handleMessageOnDeliveryService, decryptEnvelop, diff --git a/packages/lib/profile/src/profileExtension/ProfileExtension.ts b/packages/lib/profile/src/profileExtension/ProfileExtension.ts index ce5857a39..e0136bbc3 100644 --- a/packages/lib/profile/src/profileExtension/ProfileExtension.ts +++ b/packages/lib/profile/src/profileExtension/ProfileExtension.ts @@ -5,6 +5,8 @@ export type MessageType = | 'EDIT' | 'REPLY' | 'REACTION' + | 'READ_OPEN' + | 'READ_RECEIVE' | 'READ_RECEIPT' | 'RESEND_REQUEST'; diff --git a/packages/messenger-widget/src/components/Chat/Chat.tsx b/packages/messenger-widget/src/components/Chat/Chat.tsx index 4f7a9d643..a4ffd09bc 100644 --- a/packages/messenger-widget/src/components/Chat/Chat.tsx +++ b/packages/messenger-widget/src/components/Chat/Chat.tsx @@ -225,6 +225,9 @@ export function Chat() { replyToMessageEnvelop={ storageEnvelopContainer.replyToMessageEnvelop } + indicator={ + storageEnvelopContainer.indicator + } /> ), diff --git a/packages/messenger-widget/src/components/Contacts/Contacts.tsx b/packages/messenger-widget/src/components/Contacts/Contacts.tsx index 004843c06..d8542137f 100644 --- a/packages/messenger-widget/src/components/Contacts/Contacts.tsx +++ b/packages/messenger-widget/src/components/Contacts/Contacts.tsx @@ -103,14 +103,25 @@ export function Contacts() { const _contact = normalizeEnsName(contactEnsName); const messages = getMessages(_contact); + // don't include the preview of acknowledgment msgs if (messages?.length > 0) { - return messages[0].envelop.message.message ?? ''; + return messages[0].envelop.message.metadata.type !== + 'READ_OPENED' && + messages[0].envelop.message.metadata.type !== 'READ_RECEIVED' && + messages[0].envelop.message.message + ? messages[0].envelop.message.message + : ''; } const contact = contacts.find( (c) => c.contactDetails.account.ensName === _contact, ); const previewMessage = contact?.message; - return previewMessage ?? ''; + return previewMessage + ? previewMessage !== 'READ_OPENED' && + previewMessage !== 'READ_RECEIVED' + ? previewMessage + : '' + : ''; }; const isContactSelected = (id: string) => { diff --git a/packages/messenger-widget/src/components/Message/Message.css b/packages/messenger-widget/src/components/Message/Message.css index 217957f99..40ac6f31b 100644 --- a/packages/messenger-widget/src/components/Message/Message.css +++ b/packages/messenger-widget/src/components/Message/Message.css @@ -36,6 +36,11 @@ margin-left: -5px; } +.indicator-tick-icon { + height: 15px; + width: 10px; +} + .msg-action-container { height: fit-content; width: fit-content; diff --git a/packages/messenger-widget/src/components/Message/MessageDetail.tsx b/packages/messenger-widget/src/components/Message/MessageDetail.tsx index 0dd608d20..9b6d75252 100644 --- a/packages/messenger-widget/src/components/Message/MessageDetail.tsx +++ b/packages/messenger-widget/src/components/Message/MessageDetail.tsx @@ -1,10 +1,45 @@ import './Message.css'; import { getMessageChangeText } from './bl'; -import tickIcon from '../../assets/images/tick.svg'; +import blueTickIcon from '../../assets/images/tick.svg'; +import whiteTickIcon from '../../assets/images/white-tick.svg'; import { MessageProps } from '../../interfaces/props'; -import { MessageState } from '@dm3-org/dm3-lib-messaging'; +import { MessageIndicator } from '../../hooks/messages/useMessage'; export function MessageDetail(props: MessageProps) { + const getMessageIndicatorView = ( + indicator: MessageIndicator | undefined, + ) => { + if (!indicator || indicator === MessageIndicator.SENT) { + return ( + read + ); + } + + const indicatorIcon = + indicator === MessageIndicator.RECEIVED + ? whiteTickIcon + : blueTickIcon; + + return ( + <> + read + read + + ); + }; + return (
{getMessageChangeText(props)} @@ -13,20 +48,13 @@ export function MessageDetail(props: MessageProps) { {/* readed message tick indicator */} {props.ownMessage ? ( - props.messageState === MessageState.Read ? ( - <> - read - read - - ) : ( - read - ) + getMessageIndicatorView(props.indicator) ) : ( - read + read )}
diff --git a/packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadOpened.ts b/packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadOpened.ts new file mode 100644 index 000000000..7409a2cc0 --- /dev/null +++ b/packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadOpened.ts @@ -0,0 +1,25 @@ +import { MessageIndicator, MessageModel } from '../../useMessage'; + +export const renderReadOpened = (messages: MessageModel[]) => { + //We filter out all messages that are of type READ_OPENED + const readOpenedMsgs = messages.filter( + (message) => message.envelop.message.metadata.type === 'READ_OPENED', + ); + + const msgsWithoutReadType = messages.filter( + (data) => data.envelop.message.metadata.type !== 'READ_OPENED', + ); + + //update indicator to the messages + return msgsWithoutReadType.map((message) => { + const openedMsg = readOpenedMsgs.find( + (m) => + m.envelop.message.metadata.referenceMessageHash === + message.envelop.metadata?.encryptedMessageHash, + ); + return { + ...message, + indicator: openedMsg ? MessageIndicator.READED : message.indicator, + }; + }); +}; diff --git a/packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadReceived.ts b/packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadReceived.ts new file mode 100644 index 000000000..1a0b4c79c --- /dev/null +++ b/packages/messenger-widget/src/hooks/messages/renderer/messageTypes/renderReadReceived.ts @@ -0,0 +1,27 @@ +import { MessageIndicator, MessageModel } from '../../useMessage'; + +export const renderReadReceived = (messages: MessageModel[]) => { + //We filter out all messages that are of type READ_RECEIVED + const readReceivedMsgs = messages.filter( + (message) => message.envelop.message.metadata.type === 'READ_RECEIVED', + ); + + const msgsWithoutReadType = messages.filter( + (data) => data.envelop.message.metadata.type !== 'READ_RECEIVED', + ); + + //update indicator to the messages + return msgsWithoutReadType.map((message) => { + const receivedMsg = readReceivedMsgs.find( + (m) => + m.envelop.message.metadata.referenceMessageHash === + message.envelop.metadata?.encryptedMessageHash, + ); + return { + ...message, + indicator: receivedMsg + ? MessageIndicator.RECEIVED + : MessageIndicator.SENT, + }; + }); +}; diff --git a/packages/messenger-widget/src/hooks/messages/renderer/renderMessage.ts b/packages/messenger-widget/src/hooks/messages/renderer/renderMessage.ts index eb571bb14..47bc1c9bf 100644 --- a/packages/messenger-widget/src/hooks/messages/renderer/renderMessage.ts +++ b/packages/messenger-widget/src/hooks/messages/renderer/renderMessage.ts @@ -3,6 +3,8 @@ import { renderDelete } from './messageTypes/renderDelete'; import { renderDuplicates } from './messageTypes/renderDuplicates'; import { renderEdit } from './messageTypes/renderEdit'; import { renderReactions } from './messageTypes/renderReactions'; +import { renderReadOpened } from './messageTypes/renderReadOpened'; +import { renderReadReceived } from './messageTypes/renderReadReceived'; import { renderReply } from './messageTypes/renderReply'; /** @@ -12,7 +14,9 @@ import { renderReply } from './messageTypes/renderReply'; * Putting them to the right place in the conversation. */ export const renderMessage = (messages: MessageModel[]) => { - const withDeletes = renderDelete(messages); + const withReadReceived = renderReadReceived(messages); + const withReadOpened = renderReadOpened(withReadReceived); + const withDeletes = renderDelete(withReadOpened); const withReactions = renderReactions(withDeletes); const withReply = renderReply(withReactions); diff --git a/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromDeliveryService.ts b/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromDeliveryService.ts index 2b8bf7477..131c1d0c2 100644 --- a/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromDeliveryService.ts +++ b/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromDeliveryService.ts @@ -1,5 +1,7 @@ import { decryptAsymmetric } from '@dm3-org/dm3-lib-crypto'; import { + createReadOpenMessage, + createReadReceiveMessage, EncryptionEnvelop, Envelop, MessageState, @@ -8,8 +10,10 @@ import { MessageModel, MessageSource } from '../useMessage'; import { Account, ProfileKeys } from '@dm3-org/dm3-lib-profile'; import { AddConversation, StoreMessageBatch } from '../../storage/useStorage'; import { Acknowledgment } from '@dm3-org/dm3-lib-delivery'; +import { ContactPreview } from '../../../interfaces/utils'; export const handleMessagesFromDeliveryService = async ( + selectedContact: ContactPreview | undefined, account: Account, profileKeys: ProfileKeys, addConversation: AddConversation, @@ -21,6 +25,7 @@ export const handleMessagesFromDeliveryService = async ( acknoledgments: Acknowledgment[], ) => void, updateConversationList: (conversation: string, updatedAt: number) => void, + addMessage: Function, ) => { //Fetch the messages from the delivery service const encryptedIncommingMessages = await fetchNewMessages( @@ -84,5 +89,70 @@ export const handleMessagesFromDeliveryService = async ( })); await syncAcknowledgment(account.ensName, acks); + + const ackToSend = messagesSortedASC.filter( + (data) => + data.envelop.message.metadata.type !== 'READ_RECEIVED' && + data.envelop.message.metadata.type !== 'READ_OPENED', + ); + + // if contact is selected send READ_OPENED acknowledgment to sender for all new messages received + if ( + ackToSend.length && + selectedContact && + selectedContact.contactDetails.account.ensName === + ackToSend[0].envelop.message.metadata.from + ) { + // send READ_OPENED acknowledgment to sender's for all messages + const openedMsgs = await Promise.all( + ackToSend.map(async (message: MessageModel) => { + return await createReadOpenMessage( + message.envelop.message.metadata.from, + account!.ensName, + 'READ_OPENED', + profileKeys?.signingKeyPair.privateKey!, + message.envelop.metadata?.encryptedMessageHash as string, + ); + }), + ); + + // add message + await Promise.all( + openedMsgs.map(async (msg, index) => { + await addMessage( + ackToSend[index].envelop.message.metadata.from, + msg, + ); + }), + ); + + return messagesSortedASC; + } + + if (ackToSend.length) { + // send READ_RECEIVED acknowledgment to sender's for all new messages received + const readedMsgs = await Promise.all( + ackToSend.map(async (message: MessageModel) => { + return await createReadReceiveMessage( + message.envelop.message.metadata.from, + account!.ensName, + 'READ_RECEIVED', + profileKeys?.signingKeyPair.privateKey!, + message.envelop.metadata?.encryptedMessageHash as string, + ); + }), + ); + + // add message + await Promise.all( + readedMsgs.map(async (msg, index) => { + await addMessage( + ackToSend[index].envelop.message.metadata.from, + msg, + ); + }), + ); + } + return messagesSortedASC; }; diff --git a/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromWebSocket.ts b/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromWebSocket.ts index 94b5779ce..3e043d62d 100644 --- a/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromWebSocket.ts +++ b/packages/messenger-widget/src/hooks/messages/sources/handleMessagesFromWebSocket.ts @@ -1,15 +1,22 @@ import { decryptAsymmetric } from '@dm3-org/dm3-lib-crypto'; import { + createReadOpenMessage, + createReadReceiveMessage, EncryptionEnvelop, Envelop, MessageState, } from '@dm3-org/dm3-lib-messaging'; -import { ProfileKeys, normalizeEnsName } from '@dm3-org/dm3-lib-profile'; +import { + Account, + ProfileKeys, + normalizeEnsName, +} from '@dm3-org/dm3-lib-profile'; import { ContactPreview } from '../../../interfaces/utils'; import { AddConversation, StoreMessageAsync } from '../../storage/useStorage'; import { MessageModel, MessageSource, MessageStorage } from '../useMessage'; export const handleMessagesFromWebSocket = async ( + account: Account, addConversation: AddConversation, setMessages: Function, storeMessage: StoreMessageAsync, @@ -18,6 +25,7 @@ export const handleMessagesFromWebSocket = async ( encryptedEnvelop: EncryptionEnvelop, resolveTLDtoAlias: Function, updateConversationList: (conversation: string, updatedAt: number) => void, + addMessage: Function, ) => { const decryptedEnvelop: Envelop = { message: JSON.parse( @@ -71,6 +79,37 @@ export const handleMessagesFromWebSocket = async ( }; }); + // if contact is selected then send READ_OPENED acknowledgment to sender for new message received + if ( + selectedContact && + selectedContact.contactDetails.account.ensName === + messageModel.envelop.message.metadata.from + ) { + const readedMsg = await createReadOpenMessage( + messageModel.envelop.message.metadata.from, + account!.ensName, + 'READ_OPENED', + profileKeys?.signingKeyPair.privateKey!, + messageModel.envelop.metadata?.encryptedMessageHash as string, + ); + + await addMessage(messageModel.envelop.message.metadata.from, readedMsg); + } else if ( + messageModel.envelop.message.metadata.type !== 'READ_RECEIVED' && + messageModel.envelop.message.metadata.type !== 'READ_OPENED' + ) { + // send READ_RECEIVED acknowledgment to sender for new message received + const readedMsg = await createReadReceiveMessage( + messageModel.envelop.message.metadata.from, + account!.ensName, + 'READ_RECEIVED', + profileKeys?.signingKeyPair.privateKey!, + messageModel.envelop.metadata?.encryptedMessageHash as string, + ); + + await addMessage(messageModel.envelop.message.metadata.from, readedMsg); + } + // Update the conversation with the latest message timestamp updateConversationList( contact, diff --git a/packages/messenger-widget/src/hooks/messages/useMessage.tsx b/packages/messenger-widget/src/hooks/messages/useMessage.tsx index 90d5c26ab..d8dc8a494 100644 --- a/packages/messenger-widget/src/hooks/messages/useMessage.tsx +++ b/packages/messenger-widget/src/hooks/messages/useMessage.tsx @@ -5,8 +5,9 @@ import { Message, MessageState, buildEnvelop, + createReadOpenMessage, } from '@dm3-org/dm3-lib-messaging'; -import { normalizeEnsName } from '@dm3-org/dm3-lib-profile'; +import { Account, normalizeEnsName } from '@dm3-org/dm3-lib-profile'; import { sha256, stringify } from '@dm3-org/dm3-lib-shared'; import { StorageEnvelopContainer as StorageEnvelopContainerNew } from '@dm3-org/dm3-lib-storage'; import { useCallback, useContext, useEffect, useState } from 'react'; @@ -25,6 +26,12 @@ import { handleMessagesFromWebSocket } from './sources/handleMessagesFromWebSock const DEFAULT_MESSAGE_PAGESIZE = 100; +export enum MessageIndicator { + SENT = 'SENT', + RECEIVED = 'RECEIVED', + READED = 'READED', +} + //Message source to identify where a message comes from. This is important to handle pagination of storage messages properly export enum MessageSource { //Messages added by the client via addMessage @@ -41,6 +48,7 @@ export type MessageModel = StorageEnvelopContainerNew & { reactions: Envelop[]; replyToMessageEnvelop?: Envelop; source: MessageSource; + indicator?: MessageIndicator; }; export type MessageStorage = { @@ -102,6 +110,7 @@ export const useMessage = () => { useEffect(() => { onNewMessage((encryptedEnvelop: EncryptionEnvelop) => { handleMessagesFromWebSocket( + account as Account, addConversation, setMessages, storeMessage, @@ -110,6 +119,7 @@ export const useMessage = () => { encryptedEnvelop, resolveTLDtoAlias, updateConversationList, + addMessage, ); }); @@ -120,39 +130,72 @@ export const useMessage = () => { //Mark messages as read when the selected contact changes useEffect(() => { - const _contact = selectedContact?.contactDetails.account.ensName; - if (!_contact) { - return; - } + const markMsgsAsRead = async () => { + const _contact = selectedContact?.contactDetails.account.ensName; + if (!_contact) { + return; + } - const contact = normalizeEnsName(_contact); + const contact = normalizeEnsName(_contact); - const unreadMessages = (messages[contact] ?? []).filter( - (message) => - message.messageState !== MessageState.Read && - message.envelop.message.metadata.from !== account?.ensName, - ); + const unreadMessages = (messages[contact] ?? []).filter( + (message) => + message.messageState !== MessageState.Read && + message.envelop.message.metadata.from !== account?.ensName, + ); - setMessages((prev) => { - //Check no new messages are added here - return { - ...prev, - [contact]: [ - ...(prev[contact] ?? []).map((message) => ({ - ...message, - messageState: MessageState.Read, - })), - ], - }; - }); + setMessages((prev) => { + //Check no new messages are added here + return { + ...prev, + [contact]: [ + ...(prev[contact] ?? []).map((message) => ({ + ...message, + messageState: MessageState.Read, + })), + ], + }; + }); - editMessageBatchAsync( - contact, - unreadMessages.map((message) => ({ - ...message, - messageState: MessageState.Read, - })), - ); + const ackToSend = unreadMessages.filter( + (data) => + data.envelop.message.metadata.type !== 'READ_RECEIVED' && + data.envelop.message.metadata.type !== 'READ_OPENED', + ); + + // send READ_OPENED acknowledgment to sender for all new messages received + const readedMsgs = await Promise.all( + ackToSend.map(async (message: MessageModel) => { + return await createReadOpenMessage( + message.envelop.message.metadata.from, + account!.ensName, + 'READ_OPENED', + profileKeys?.signingKeyPair.privateKey!, + message.envelop.metadata + ?.encryptedMessageHash as string, + ); + }), + ); + + // add messages + await Promise.all( + readedMsgs.map(async (msgs, index) => { + await addMessage( + ackToSend[index].envelop.message.metadata.from, + msgs, + ); + }), + ); + + editMessageBatchAsync( + contact, + unreadMessages.map((message) => ({ + ...message, + messageState: MessageState.Read, + })), + ); + }; + markMsgsAsRead(); }, [selectedContact]); //View function that returns wether a contact is loading @@ -184,6 +227,8 @@ export const useMessage = () => { return messages[contactName].filter( (message) => message.messageState !== MessageState.Read && + message.envelop.message.metadata.type !== 'READ_OPENED' && + message.envelop.message.metadata.type !== 'READ_RECEIVED' && message.envelop.message.metadata.from !== account?.ensName, ).length; }, @@ -350,6 +395,7 @@ export const useMessage = () => { 0, ), handleMessagesFromDeliveryService( + selectedContact, account!, profileKeys!, addConversation, @@ -358,6 +404,7 @@ export const useMessage = () => { fetchNewMessages, syncAcknowledgment, updateConversationList, + addMessage, ), ]); const flatten = initialMessages.reduce( diff --git a/packages/messenger-widget/src/interfaces/props.ts b/packages/messenger-widget/src/interfaces/props.ts index f27095c21..e8425748a 100644 --- a/packages/messenger-widget/src/interfaces/props.ts +++ b/packages/messenger-widget/src/interfaces/props.ts @@ -1,6 +1,7 @@ import { Envelop, MessageState } from '@dm3-org/dm3-lib-messaging'; import { MessageActionType } from '../utils/enum-type-utils'; import { IAttachmentPreview, ContactPreview } from './utils'; +import { MessageIndicator } from '../hooks/messages/useMessage'; export interface IEnsDetails { propertyKey: string; @@ -23,6 +24,7 @@ export interface MessageProps { reactions: Envelop[]; isLastMessage?: boolean; hideFunction?: string; + indicator?: MessageIndicator; } export interface MessageAction { From 65eea40889038189d781baff5b1a3f5f5bb8ba63 Mon Sep 17 00:00:00 2001 From: Bhupesh-MS Date: Fri, 26 Jul 2024 16:13:11 +0530 Subject: [PATCH 2/6] fixed broken tests --- .../src/hooks/messages/useMessage.test.tsx | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/messenger-widget/src/hooks/messages/useMessage.test.tsx b/packages/messenger-widget/src/hooks/messages/useMessage.test.tsx index 49bd9b2c1..233b454c5 100644 --- a/packages/messenger-widget/src/hooks/messages/useMessage.test.tsx +++ b/packages/messenger-widget/src/hooks/messages/useMessage.test.tsx @@ -678,8 +678,14 @@ describe('useMessage hook test cases', () => { result.current.messages['alice.eth'].length > 0, ); + // Filter out the acknowledgment messages + const sentMsgs = result.current.messages['alice.eth'].filter( + (data) => + data.envelop.message.metadata.type !== 'READ_RECEIVED', + ); + expect(result.current.contactIsLoading('alice.eth')).toBe(false); - expect(result.current.messages['alice.eth'].length).toBe(3); + expect(sentMsgs.length).toBe(3); }); }); describe('message pagination', () => { @@ -885,9 +891,16 @@ describe('useMessage hook test cases', () => { result.current.messages['alice.eth'].length > 0, ); + // Filter out the acknowledgment messages + const sentMsgs = result.current.messages['alice.eth'].filter( + (data) => + data.envelop.message.metadata.type !== 'READ_RECEIVED', + ); + expect(result.current.contactIsLoading('alice.eth')).toBe(false); + //Initial message number would be storage(100) = Ds (13) == 113 - expect(result.current.messages['alice.eth'].length).toBe(113); + expect(sentMsgs.length).toBe(113); await act(async () => result.current.loadMoreMessages('alice.eth')); @@ -898,11 +911,17 @@ describe('useMessage hook test cases', () => { result.current.messages['alice.eth'].length > 133, ); + // Filter out the acknowledgment messages + const moreSentMsgs = result.current.messages['alice.eth'].filter( + (data) => + data.envelop.message.metadata.type !== 'READ_RECEIVED', + ); + expect(result.current.contactIsLoading('alice.eth')).toBe(false); - expect(result.current.messages['alice.eth'].length).toBe(213); + expect(moreSentMsgs.length).toBe(213); //991 = 99 message 100(since pageSize starts from 0) = 1 offset expect( - result.current.messages['alice.eth'][212].envelop.message + result.current.messages['alice.eth'][225].envelop.message .message, ).toBe('hello dm3 991'); }); From 5b8992f9e031f99ae33dad8d18ba26e482f90ec4 Mon Sep 17 00:00:00 2001 From: AlexNi245 Date: Wed, 31 Jul 2024 10:01:44 +0200 Subject: [PATCH 3/6] dont show indicators on received messages --- .../src/components/Message/MessageDetail.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/messenger-widget/src/components/Message/MessageDetail.tsx b/packages/messenger-widget/src/components/Message/MessageDetail.tsx index 9b6d75252..7a36598e7 100644 --- a/packages/messenger-widget/src/components/Message/MessageDetail.tsx +++ b/packages/messenger-widget/src/components/Message/MessageDetail.tsx @@ -50,11 +50,7 @@ export function MessageDetail(props: MessageProps) { {props.ownMessage ? ( getMessageIndicatorView(props.indicator) ) : ( - read + <> )} From 63660b578dd02c97f3b2098b9f0bf6b590156067 Mon Sep 17 00:00:00 2001 From: AlexNi245 Date: Wed, 31 Jul 2024 10:02:13 +0200 Subject: [PATCH 4/6] remove unused READ_RECEIVED MessageType --- packages/lib/messaging/src/Message.ts | 1 - .../lib/profile/src/profileExtension/ProfileExtension.ts | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/lib/messaging/src/Message.ts b/packages/lib/messaging/src/Message.ts index 9cfe3081e..a8fe7d212 100644 --- a/packages/lib/messaging/src/Message.ts +++ b/packages/lib/messaging/src/Message.ts @@ -46,7 +46,6 @@ export type MessageType = | 'REACTION' | 'READ_OPENED' | 'READ_RECEIVED' - | 'READ_RECEIPT' | 'RESEND_REQUEST'; export interface Postmark { diff --git a/packages/lib/profile/src/profileExtension/ProfileExtension.ts b/packages/lib/profile/src/profileExtension/ProfileExtension.ts index e0136bbc3..6a21b3853 100644 --- a/packages/lib/profile/src/profileExtension/ProfileExtension.ts +++ b/packages/lib/profile/src/profileExtension/ProfileExtension.ts @@ -5,9 +5,8 @@ export type MessageType = | 'EDIT' | 'REPLY' | 'REACTION' - | 'READ_OPEN' - | 'READ_RECEIVE' - | 'READ_RECEIPT' + | 'READ_OPENED' + | 'READ_RECEIVED' | 'RESEND_REQUEST'; export interface ProfileExtension { From c495b38467a30bc935dc9ab79ebc00563652738a Mon Sep 17 00:00:00 2001 From: AlexNi245 Date: Wed, 31 Jul 2024 10:42:32 +0200 Subject: [PATCH 5/6] rename storageEnvelopContainer to messageModel --- .../src/components/Chat/Chat.tsx | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/packages/messenger-widget/src/components/Chat/Chat.tsx b/packages/messenger-widget/src/components/Chat/Chat.tsx index a4ffd09bc..a9552fc7d 100644 --- a/packages/messenger-widget/src/components/Chat/Chat.tsx +++ b/packages/messenger-widget/src/components/Chat/Chat.tsx @@ -192,41 +192,34 @@ export function Chat() { > {messages.length > 0 && messages.map( - ( - storageEnvelopContainer: MessageModel, - index, - ) => ( + (messageModel: MessageModel, index) => (
From 4826be627b063ed5498c5e3690aa5f395a479dac Mon Sep 17 00:00:00 2001 From: AlexNi245 Date: Wed, 31 Jul 2024 10:52:10 +0200 Subject: [PATCH 6/6] bring back preview message check --- .../messenger-widget/src/components/Contacts/Contacts.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/messenger-widget/src/components/Contacts/Contacts.tsx b/packages/messenger-widget/src/components/Contacts/Contacts.tsx index d8542137f..936d5be9e 100644 --- a/packages/messenger-widget/src/components/Contacts/Contacts.tsx +++ b/packages/messenger-widget/src/components/Contacts/Contacts.tsx @@ -105,9 +105,7 @@ export function Contacts() { // don't include the preview of acknowledgment msgs if (messages?.length > 0) { - return messages[0].envelop.message.metadata.type !== - 'READ_OPENED' && - messages[0].envelop.message.metadata.type !== 'READ_RECEIVED' && + return messages[0].envelop.message.metadata.type === 'NEW' && messages[0].envelop.message.message ? messages[0].envelop.message.message : '';