Skip to content

Commit

Permalink
Merge pull request #1125 from dm3-org/msg-lib-indicators
Browse files Browse the repository at this point in the history
Msg indicators
  • Loading branch information
AlexNi245 authored Jul 31, 2024
2 parents 6585bba + 4826be6 commit 947fc9a
Show file tree
Hide file tree
Showing 15 changed files with 393 additions and 70 deletions.
55 changes: 54 additions & 1 deletion packages/lib/messaging/src/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export type MessageType =
| 'EDIT'
| 'REPLY'
| 'REACTION'
| 'READ_RECEIPT'
| 'READ_OPENED'
| 'READ_RECEIVED'
| 'RESEND_REQUEST';

export interface Postmark {
Expand Down Expand Up @@ -253,6 +254,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<Message> {
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<Message> {
return internalCreateMessage(
to,
from,
message,
privateKey,
'READ_RECEIVED',
[],
referenceMessageHash,
);
}

export async function checkMessageSignature(
message: Message,
publicSigningKey: string,
Expand Down
2 changes: 2 additions & 0 deletions packages/lib/messaging/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export {
createEditMessage,
createReactionMessage,
createReplyMessage,
createReadOpenMessage,
createReadReceiveMessage,
createJsonRpcCallSubmitMessage,
handleMessageOnDeliveryService,
decryptEnvelop,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export type MessageType =
| 'EDIT'
| 'REPLY'
| 'REACTION'
| 'READ_RECEIPT'
| 'READ_OPENED'
| 'READ_RECEIVED'
| 'RESEND_REQUEST';

export interface ProfileExtension {
Expand Down
26 changes: 11 additions & 15 deletions packages/messenger-widget/src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,38 +192,34 @@ export function Chat() {
>
{messages.length > 0 &&
messages.map(
(
storageEnvelopContainer: MessageModel,
index,
) => (
(messageModel: MessageModel, index) => (
<div key={index} className="mt-2">
<Message
message={
storageEnvelopContainer
.envelop.message
messageModel.envelop.message
.message ?? ''
}
time={
storageEnvelopContainer.envelop.message.metadata?.timestamp.toString() ??
messageModel.envelop.message.metadata?.timestamp.toString() ??
'0'
}
messageState={
storageEnvelopContainer.messageState
messageModel.messageState
}
ownMessage={
storageEnvelopContainer
.envelop.message
messageModel.envelop.message
.metadata?.from ===
account!.ensName
}
envelop={
storageEnvelopContainer.envelop
}
envelop={messageModel.envelop}
reactions={
storageEnvelopContainer.reactions
messageModel.reactions
}
replyToMessageEnvelop={
storageEnvelopContainer.replyToMessageEnvelop
messageModel.replyToMessageEnvelop
}
indicator={
messageModel.indicator
}
/>
</div>
Expand Down
13 changes: 11 additions & 2 deletions packages/messenger-widget/src/components/Contacts/Contacts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,23 @@ 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 === 'NEW' &&
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) => {
Expand Down
5 changes: 5 additions & 0 deletions packages/messenger-widget/src/components/Message/Message.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
margin-left: -5px;
}

.indicator-tick-icon {
height: 15px;
width: 10px;
}

.msg-action-container {
height: fit-content;
width: fit-content;
Expand Down
54 changes: 39 additions & 15 deletions packages/messenger-widget/src/components/Message/MessageDetail.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<img
className="indicator-tick-icon"
src={whiteTickIcon}
alt="read"
/>
);
}

const indicatorIcon =
indicator === MessageIndicator.RECEIVED
? whiteTickIcon
: blueTickIcon;

return (
<>
<img
className="indicator-tick-icon"
src={indicatorIcon}
alt="read"
/>
<img
src={indicatorIcon}
alt="read"
className="second-tick indicator-tick-icon"
/>
</>
);
};

return (
<div className="d-flex justify-content-end pt-1 ps-1 pe-1">
{getMessageChangeText(props)}
Expand All @@ -13,20 +48,9 @@ export function MessageDetail(props: MessageProps) {
{/* readed message tick indicator */}
<span className="tick-icon readed-tick-icon">
{props.ownMessage ? (
props.messageState === MessageState.Read ? (
<>
<img src={tickIcon} alt="read" />
<img
src={tickIcon}
alt="read"
className="second-tick"
/>
</>
) : (
<img src={tickIcon} alt="read" />
)
getMessageIndicatorView(props.indicator)
) : (
<img src={tickIcon} alt="read" />
<></>
)}
</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
};
});
};
Original file line number Diff line number Diff line change
@@ -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,
};
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -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);

Expand Down
Loading

0 comments on commit 947fc9a

Please sign in to comment.