Skip to content

Commit 6d29122

Browse files
authored
Fix: [v2] Update message receipts on real time basis (#117)
* Calculate message status in the message content component, not from outside of the component * Apply onUnreadMemberCountUpdated and onUndeliveredMemberCountUpdated channel handlers into the Conversation component [UIKIT-1620](https://sendbird.atlassian.net/browse/UIKIT-1620)
1 parent 73bddcd commit 6d29122

File tree

5 files changed

+54
-25
lines changed

5 files changed

+54
-25
lines changed

src/smart-components/Conversation/hooks/useHandleChannelEvents.js

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
2020
scrollRef,
2121
setQuoteMessage,
2222
}) {
23-
const channelUrl = currentGroupChannel && currentGroupChannel.url;
23+
const channelUrl = currentGroupChannel && currentGroupChannel?.url;
2424
useEffect(() => {
2525
const messageReceiverId = uuidv4();
2626
if (channelUrl && sdk && sdk.ChannelHandler) {
@@ -29,7 +29,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
2929

3030
ChannelHandler.onMessageReceived = (channel, message) => {
3131
// donot update if hasMoreToBottom
32-
if (compareIds(channel.url, currentGroupChannel.url) && !hasMoreToBottom) {
32+
if (compareIds(channel.url, channelUrl) && !hasMoreToBottom) {
3333
let scrollToEnd = false;
3434
try {
3535
const { current } = scrollRef;
@@ -55,14 +55,38 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
5555
}
5656
}
5757
}
58-
if (compareIds(channel.url, currentGroupChannel.url) && hasMoreToBottom) {
58+
if (compareIds(channel.url, channelUrl) && hasMoreToBottom) {
5959
messagesDispatcher({
6060
type: messageActions.UPDATE_UNREAD_COUNT,
6161
payload: { channel },
6262
});
6363
}
6464
};
6565

66+
/**
67+
* We need to update current channel with the channel,
68+
* when onReadReceiptUpdated or onDeliveryReceiptUpdated are called,
69+
* because cachedReadReceiptStatus and cachedDeliveryReceiptStatus properties were changed
70+
*/
71+
ChannelHandler.onReadReceiptUpdated = (channel) => {
72+
if (compareIds(channel.url, channelUrl)) {
73+
logger.info('Channel | useHandleChannelEvents: onReadReceiptUpdated', channel);
74+
messagesDispatcher({
75+
type: messageActions.SET_CURRENT_CHANNEL,
76+
payload: channel,
77+
});
78+
}
79+
};
80+
ChannelHandler.onDeliveryReceiptUpdated = (channel) => {
81+
if (compareIds(channel.url, channelUrl)) {
82+
logger.info('Channel | useHandleChannelEvents: onDeliveryReceiptUpdated', channel);
83+
messagesDispatcher({
84+
type: messageActions.SET_CURRENT_CHANNEL,
85+
payload: channel,
86+
});
87+
}
88+
};
89+
6690
ChannelHandler.onMessageUpdated = (channel, message) => {
6791
logger.info('Channel | useHandleChannelEvents: onMessageUpdated', message);
6892
messagesDispatcher({
@@ -97,7 +121,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
97121
};
98122

99123
ChannelHandler.onChannelChanged = (groupChannel) => {
100-
if (compareIds(groupChannel.url, currentGroupChannel.url)) {
124+
if (compareIds(groupChannel.url, channelUrl)) {
101125
logger.info('Channel | useHandleChannelEvents: onChannelChanged', groupChannel);
102126
messagesDispatcher({
103127
type: messageActions.SET_CURRENT_CHANNEL,
@@ -107,7 +131,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
107131
};
108132

109133
ChannelHandler.onChannelFrozen = (groupChannel) => {
110-
if (compareIds(groupChannel.url, currentGroupChannel.url)) {
134+
if (compareIds(groupChannel.url, channelUrl)) {
111135
logger.info('Channel | useHandleChannelEvents: onChannelFrozen', groupChannel);
112136
messagesDispatcher({
113137
type: messageActions.SET_CURRENT_CHANNEL,
@@ -117,7 +141,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
117141
};
118142

119143
ChannelHandler.onChannelUnfrozen = (groupChannel) => {
120-
if (compareIds(groupChannel.url, currentGroupChannel.url)) {
144+
if (compareIds(groupChannel.url, channelUrl)) {
121145
logger.info('Channel | useHandleChannelEvents: onChannelUnFrozen', groupChannel);
122146
messagesDispatcher({
123147
type: messageActions.SET_CURRENT_CHANNEL,
@@ -127,7 +151,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
127151
};
128152

129153
ChannelHandler.onUserMuted = (groupChannel) => {
130-
if (compareIds(groupChannel.url, currentGroupChannel.url)) {
154+
if (compareIds(groupChannel.url, channelUrl)) {
131155
logger.info('Channel | useHandleChannelEvents: onUserMuted', groupChannel);
132156
messagesDispatcher({
133157
type: messageActions.SET_CURRENT_CHANNEL,
@@ -137,7 +161,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
137161
};
138162

139163
ChannelHandler.onUserUnmuted = (groupChannel) => {
140-
if (compareIds(groupChannel.url, currentGroupChannel.url)) {
164+
if (compareIds(groupChannel.url, channelUrl)) {
141165
logger.info('Channel | useHandleChannelEvents: onUserUnmuted', groupChannel);
142166
messagesDispatcher({
143167
type: messageActions.SET_CURRENT_CHANNEL,
@@ -147,7 +171,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
147171
};
148172

149173
ChannelHandler.onUserBanned = (groupChannel) => {
150-
if (compareIds(groupChannel.url, currentGroupChannel.url)) {
174+
if (compareIds(groupChannel.url, channelUrl)) {
151175
logger.info('Channel | useHandleChannelEvents: onUserBanned', groupChannel);
152176
messagesDispatcher({
153177
type: messageActions.SET_CURRENT_CHANNEL,
@@ -157,7 +181,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom
157181
};
158182

159183
ChannelHandler.onOperatorUpdated = (groupChannel) => {
160-
if (compareIds(groupChannel.url, currentGroupChannel.url)) {
184+
if (compareIds(groupChannel.url, channelUrl)) {
161185
logger.info('Channel | useHandleChannelEvents: onOperatorUpdated', groupChannel);
162186
messagesDispatcher({
163187
type: messageActions.SET_CURRENT_CHANNEL,

src/ui/MessageContent/index.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import {
3232
isTextMessage,
3333
isOGMessage,
3434
isThumbnailMessage,
35-
getOutgoingMessageState,
3635
getSenderName,
3736
} from '../../utils';
3837
import { UserProfileContext } from '../../lib/UserProfileContext';
@@ -95,7 +94,6 @@ export default function MessageContent({
9594
const supposedHoverClassName = supposedHover ? 'supposed-hover' : '';
9695
const useReplying = !!((replyType === 'QUOTE_REPLY') && message?.parentMessageId && message?.parentMessage);
9796
const useReplyingClassName = useReplying ? 'use-quote' : '';
98-
9997
if (message?.isAdminMessage?.() || message?.messageType === 'admin') {
10098
return (<ClientAdminMessage message={message} />);
10199
}
@@ -205,7 +203,6 @@ export default function MessageContent({
205203
<MessageStatus
206204
message={message}
207205
channel={channel}
208-
status={getOutgoingMessageState(channel, message)}
209206
/>
210207
</div>
211208
</div>

src/ui/MessageStatus/__tests__/MessageStatus.spec.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jest.mock('date-fns/format', () => () => ('mock-date'));
1313
describe('MessageStatus', () => {
1414
it('should contain className', function () {
1515
const text = "example-text";
16-
const component = shallow(<MessageStatus className={text} />);
16+
const component = shallow(<MessageStatus className={text} message={dummyMessage} />);
1717

1818
expect(
1919
component.find(".sendbird-message-status").hasClass(text)
@@ -23,7 +23,7 @@ describe('MessageStatus', () => {
2323
it('should do a snapshot test of the MessageStatus DOM', function () {
2424
const text = "example-text";
2525
const component = renderer.create(
26-
<MessageStatus className={text} status={MessageStatusTypes.SENT} message={dummyMessage} />,
26+
<MessageStatus className={text} message={dummyMessage} />,
2727
);
2828
let tree = component.toJSON();
2929
expect(tree).toMatchSnapshot();
@@ -33,10 +33,11 @@ describe('MessageStatus', () => {
3333
const text = "example-text";
3434
const failedMsg = {
3535
...dummyMessage,
36+
sendingStatus: 'failed',
3637
isResendable: () => { return true; },
3738
};
3839
const component = renderer.create(
39-
<MessageStatus className={text} status={MessageStatusTypes.FAILED} message={failedMsg} />,
40+
<MessageStatus className={text} message={failedMsg} />,
4041
);
4142
let tree = component.toJSON();
4243
expect(tree).toMatchSnapshot();
@@ -46,9 +47,10 @@ describe('MessageStatus', () => {
4647
const text = "example-text";
4748
const failedMsg = {
4849
...dummyMessage,
50+
sendingStatus: 'failed',
4951
};
5052
const component = renderer.create(
51-
<MessageStatus className={text} status={MessageStatusTypes.FAILED} message={failedMsg} />,
53+
<MessageStatus className={text} message={failedMsg} />,
5254
);
5355
let tree = component.toJSON();
5456
expect(tree).toMatchSnapshot();

src/ui/MessageStatus/index.jsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useContext } from 'react';
1+
import React, { useContext, useMemo } from 'react';
22
import PropTypes from 'prop-types';
33

44
import format from 'date-fns/format';
@@ -9,6 +9,7 @@ import Label, { LabelColors, LabelTypography } from '../Label';
99
import Loader from '../Loader';
1010

1111
import {
12+
getOutgoingMessageState,
1213
getOutgoingMessageStates,
1314
isSentStatus,
1415
} from '../../utils';
@@ -19,7 +20,6 @@ export default function MessageStatus({
1920
className,
2021
message,
2122
channel,
22-
status,
2323
}) {
2424
const { dateLocale } = useContext(LocalizationContext);
2525
const showMessageStatusIcon = channel?.isGroupChannel()
@@ -39,6 +39,10 @@ export default function MessageStatus({
3939
[MessageStatusTypes.FAILED]: IconColors.ERROR,
4040
};
4141

42+
const messageStatus = useMemo(() => (
43+
getOutgoingMessageState(channel, message)
44+
), [channel?.getUnreadMemberCount?.(message), channel?.getUndeliveredMemberCount?.(message)]);
45+
4246
return (
4347
<div
4448
className={[
@@ -47,7 +51,7 @@ export default function MessageStatus({
4751
].join(' ')}
4852
>
4953
{(showMessageStatusIcon) && (
50-
(status === MessageStatusTypes.PENDING) ? (
54+
(messageStatus === MessageStatusTypes.PENDING) ? (
5155
<Loader
5256
className="sendbird-message-status__icon"
5357
width="16px"
@@ -63,14 +67,14 @@ export default function MessageStatus({
6367
) : (
6468
<Icon
6569
className="sendbird-message-status__icon"
66-
type={iconType[status] || IconTypes.ERROR}
67-
fillColor={iconColor[status]}
70+
type={iconType[messageStatus] || IconTypes.ERROR}
71+
fillColor={iconColor[messageStatus]}
6872
width="16px"
6973
height="16px"
7074
/>
7175
)
7276
)}
73-
{isSentStatus(status) && (
77+
{isSentStatus(messageStatus) && (
7478
<Label
7579
className="sendbird-message-status__text"
7680
type={LabelTypography.CAPTION_3}
@@ -103,13 +107,13 @@ MessageStatus.propTypes = {
103107
isSuper: PropTypes.bool,
104108
isBroadcast: PropTypes.bool,
105109
isPublic: PropTypes.bool,
110+
getUnreadMemberCount: PropTypes.func,
111+
getUndeliveredMemberCount: PropTypes.func,
106112
}),
107-
status: PropTypes.string,
108113
};
109114

110115
MessageStatus.defaultProps = {
111116
className: '',
112117
message: null,
113118
channel: null,
114-
status: '',
115119
};

src/ui/MessageStatus/messageDummyData.mock.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export function generateNormalMessage(pretreatment) {
2828
reqId: "1579767478746",
2929
translations: {},
3030
requestState: "succeeded",
31+
sendingStatus: "succeeded",
3132
requestedMentionUserIds: [],
3233
errorCode: 0,
3334
getUnreadMemberCount: () => 10,
@@ -70,6 +71,7 @@ export function generateLongMessage(pretreatment) {
7071
reqId: "1579767478746",
7172
translations: {},
7273
requestState: "succeeded",
74+
sendingStatus: "succeeded",
7375
requestedMentionUserIds: [],
7476
errorCode: 0,
7577
requestState: 'DELIVERED',

0 commit comments

Comments
 (0)