From b7de2633429d9ac221e536593fd5b6384fcedd6d Mon Sep 17 00:00:00 2001 From: HoonBaek Date: Mon, 21 Mar 2022 17:19:54 +0900 Subject: [PATCH 1/4] Apply on read&delivery receipt updated event handler into the Conversation comp (cherry picked from commit 250b23435d250f784f8d3e1a8d8f1e6a2ebad069) --- .../context/hooks/useHandleChannelEvents.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js b/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js index 821a41785..e6d34acdd 100644 --- a/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js +++ b/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js @@ -63,6 +63,26 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom } }; + ChannelHandler.onReadReceiptUpdated = (channel) => { + if (compareIds(currentGroupChannel.url, channel.url)) { + logger.info('Channel | useHandleChannelEvents: onReadReceiptUpdated', channel); + messagesDispatcher({ + type: messageActions.SET_CURRENT_CHANNEL, + payload: channel, + }); + } + }; + + ChannelHandler.onDeliveryReceiptUpdated = (channel) => { + if (compareIds(currentGroupChannel.url, channel.url)) { + logger.info('Channel | useHandleChannelEvents: onDeliveryReceiptUpdated', channel); + messagesDispatcher({ + type: messageActions.SET_CURRENT_CHANNEL, + payload: channel, + }); + } + }; + ChannelHandler.onMessageUpdated = (channel, message) => { logger.info('Channel | useHandleChannelEvents: onMessageUpdated', message); messagesDispatcher({ From 7eed9d80a3457cafd4fb3685646cd87e6def51ca Mon Sep 17 00:00:00 2001 From: HoonBaek Date: Mon, 21 Mar 2022 19:55:54 +0900 Subject: [PATCH 2/4] Calculate message status in the message content comp --- src/ui/MessageContent/index.tsx | 2 - .../__tests__/MessageStatus.spec.js | 8 +-- src/ui/MessageStatus/{index.jsx => index.tsx} | 51 ++++++------------- src/ui/MessageStatus/messageDummyData.mock.js | 2 + 4 files changed, 22 insertions(+), 41 deletions(-) rename src/ui/MessageStatus/{index.jsx => index.tsx} (73%) diff --git a/src/ui/MessageContent/index.tsx b/src/ui/MessageContent/index.tsx index f25e054e2..b07b06077 100644 --- a/src/ui/MessageContent/index.tsx +++ b/src/ui/MessageContent/index.tsx @@ -26,7 +26,6 @@ import { isTextMessage, isOGMessage, isThumbnailMessage, - getOutgoingMessageState, getSenderName, getMessageCreatedAt, CoreMessageType, @@ -203,7 +202,6 @@ export default function MessageContent({ diff --git a/src/ui/MessageStatus/__tests__/MessageStatus.spec.js b/src/ui/MessageStatus/__tests__/MessageStatus.spec.js index a47a22ce2..f4cf8e927 100644 --- a/src/ui/MessageStatus/__tests__/MessageStatus.spec.js +++ b/src/ui/MessageStatus/__tests__/MessageStatus.spec.js @@ -13,7 +13,7 @@ jest.mock('date-fns/format', () => () => ('mock-date')); describe('MessageStatus', () => { it('should contain className', function () { const text = "example-text"; - const component = shallow(); + const component = shallow(); expect( component.find(".sendbird-message-status").hasClass(text) @@ -33,10 +33,11 @@ describe('MessageStatus', () => { const text = "example-text"; const failedMsg = { ...dummyMessage, + sendingStatus: 'failed', isResendable: () => { return true; }, }; const component = renderer.create( - , + , ); let tree = component.toJSON(); expect(tree).toMatchSnapshot(); @@ -46,9 +47,10 @@ describe('MessageStatus', () => { const text = "example-text"; const failedMsg = { ...dummyMessage, + sendingStatus: 'failed', }; const component = renderer.create( - , + , ); let tree = component.toJSON(); expect(tree).toMatchSnapshot(); diff --git a/src/ui/MessageStatus/index.jsx b/src/ui/MessageStatus/index.tsx similarity index 73% rename from src/ui/MessageStatus/index.jsx rename to src/ui/MessageStatus/index.tsx index 65d63566e..abf914a5d 100644 --- a/src/ui/MessageStatus/index.jsx +++ b/src/ui/MessageStatus/index.tsx @@ -1,24 +1,34 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - +import React, { useMemo } from 'react'; import './index.scss'; + import Icon, { IconTypes, IconColors } from '../Icon'; import Label, { LabelColors, LabelTypography } from '../Label'; import Loader from '../Loader'; import { getMessageCreatedAt, + getOutgoingMessageState, getOutgoingMessageStates, isSentStatus, } from '../../utils'; +import { FileMessage, GroupChannel, UserMessage } from 'sendbird'; export const MessageStatusTypes = getOutgoingMessageStates(); + +interface MessageStatusProps { + className?: string; + message: UserMessage | FileMessage; + channel: GroupChannel; +} + export default function MessageStatus({ className, message, channel, - status, -}) { +}: MessageStatusProps): React.ReactElement { + const status = useMemo(() => ( + getOutgoingMessageState(channel, message) + ), [channel?.getUnreadMemberCount?.(message), channel?.getUndeliveredMemberCount?.(message)]); const showMessageStatusIcon = channel?.isGroupChannel() && !channel?.isSuper && !channel?.isPublic @@ -77,34 +87,3 @@ export default function MessageStatus({ ); } - -MessageStatus.propTypes = { - className: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.arrayOf(PropTypes.string), - ]), - message: PropTypes.shape({ - createdAt: PropTypes.number, - sender: PropTypes.shape({ - friendName: PropTypes.string, - nickname: PropTypes.string, - userId: PropTypes.string, - profileUrl: PropTypes.string, - }), - sendingStatus: PropTypes.string, - }), - channel: PropTypes.shape({ - isGroupChannel: PropTypes.func, - isSuper: PropTypes.bool, - isBroadcast: PropTypes.bool, - isPublic: PropTypes.bool, - }), - status: PropTypes.string, -}; - -MessageStatus.defaultProps = { - className: '', - message: null, - channel: null, - status: '', -}; diff --git a/src/ui/MessageStatus/messageDummyData.mock.js b/src/ui/MessageStatus/messageDummyData.mock.js index cd429ed5b..48305cd80 100644 --- a/src/ui/MessageStatus/messageDummyData.mock.js +++ b/src/ui/MessageStatus/messageDummyData.mock.js @@ -28,6 +28,7 @@ export function generateNormalMessage(pretreatment) { reqId: "1579767478746", translations: {}, requestState: "succeeded", + sendingStatus: "succeeded", requestedMentionUserIds: [], errorCode: 0, getUnreadMemberCount: () => 10, @@ -70,6 +71,7 @@ export function generateLongMessage(pretreatment) { reqId: "1579767478746", translations: {}, requestState: "succeeded", + sendingStatus: "succeeded", requestedMentionUserIds: [], errorCode: 0, requestState: 'DELIVERED', From efe5b412c2ba7d1eb6da423bf03459fcb4454c91 Mon Sep 17 00:00:00 2001 From: HoonBaek Date: Mon, 21 Mar 2022 19:59:45 +0900 Subject: [PATCH 3/4] Modify the path to reduce file extention --- src/ui/MessageStatus/stories/MessageStatus.stories.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/MessageStatus/stories/MessageStatus.stories.js b/src/ui/MessageStatus/stories/MessageStatus.stories.js index 40ff03f3d..bf02ffa52 100644 --- a/src/ui/MessageStatus/stories/MessageStatus.stories.js +++ b/src/ui/MessageStatus/stories/MessageStatus.stories.js @@ -1,5 +1,5 @@ import React from 'react'; -import MessageStatus, { MessageStatusTypes } from '../index.jsx'; +import MessageStatus, { MessageStatusTypes } from '../index'; import { generateNormalMessage } from '../messageDummyData.mock'; export default { title: 'UI Components/MessageStatus' }; From b8096236c6dc6d190c74e2ce9b7aca5167070003 Mon Sep 17 00:00:00 2001 From: HoonBaek Date: Tue, 22 Mar 2022 11:22:09 +0900 Subject: [PATCH 4/4] Apply optional chaining to the channelUrl and leave comments for receipts handling --- .../context/hooks/useHandleChannelEvents.js | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js b/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js index e6d34acdd..ea547c503 100644 --- a/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js +++ b/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js @@ -20,7 +20,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom scrollRef, setQuoteMessage, }) { - const channelUrl = currentGroupChannel && currentGroupChannel.url; + const channelUrl = currentGroupChannel && currentGroupChannel?.url; useEffect(() => { const messageReceiverId = uuidv4(); if (channelUrl && sdk && sdk.ChannelHandler) { @@ -29,7 +29,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom ChannelHandler.onMessageReceived = (channel, message) => { // donot update if hasMoreToBottom - if (compareIds(channel.url, currentGroupChannel.url) && !hasMoreToBottom) { + if (compareIds(channel.url, channelUrl) && !hasMoreToBottom) { let scrollToEnd = false; try { const { current } = scrollRef; @@ -55,7 +55,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom } } } - if (compareIds(channel.url, currentGroupChannel.url) && hasMoreToBottom) { + if (compareIds(channel.url, channelUrl) && hasMoreToBottom) { messagesDispatcher({ type: messageActions.UPDATE_UNREAD_COUNT, payload: { channel }, @@ -63,8 +63,13 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom } }; + /** + * We need to update current channel with the channel, + * when onReadReceiptUpdated or onDeliveryReceiptUpdated are called, + * because cachedReadReceiptStatus and cachedDeliveryReceiptStatus properties were changed + */ ChannelHandler.onReadReceiptUpdated = (channel) => { - if (compareIds(currentGroupChannel.url, channel.url)) { + if (compareIds(channel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onReadReceiptUpdated', channel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -72,9 +77,8 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }); } }; - ChannelHandler.onDeliveryReceiptUpdated = (channel) => { - if (compareIds(currentGroupChannel.url, channel.url)) { + if (compareIds(channel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onDeliveryReceiptUpdated', channel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -117,7 +121,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }; ChannelHandler.onChannelChanged = (groupChannel) => { - if (compareIds(groupChannel.url, currentGroupChannel.url)) { + if (compareIds(groupChannel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onChannelChanged', groupChannel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -127,7 +131,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }; ChannelHandler.onChannelFrozen = (groupChannel) => { - if (compareIds(groupChannel.url, currentGroupChannel.url)) { + if (compareIds(groupChannel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onChannelFrozen', groupChannel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -137,7 +141,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }; ChannelHandler.onChannelUnfrozen = (groupChannel) => { - if (compareIds(groupChannel.url, currentGroupChannel.url)) { + if (compareIds(groupChannel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onChannelUnFrozen', groupChannel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -147,7 +151,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }; ChannelHandler.onUserMuted = (groupChannel) => { - if (compareIds(groupChannel.url, currentGroupChannel.url)) { + if (compareIds(groupChannel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onUserMuted', groupChannel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -157,7 +161,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }; ChannelHandler.onUserUnmuted = (groupChannel) => { - if (compareIds(groupChannel.url, currentGroupChannel.url)) { + if (compareIds(groupChannel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onUserUnmuted', groupChannel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -167,7 +171,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }; ChannelHandler.onUserBanned = (groupChannel) => { - if (compareIds(groupChannel.url, currentGroupChannel.url)) { + if (compareIds(groupChannel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onUserBanned', groupChannel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL, @@ -177,7 +181,7 @@ function useHandleChannelEvents({ currentGroupChannel, sdkInit, hasMoreToBottom }; ChannelHandler.onOperatorUpdated = (groupChannel) => { - if (compareIds(groupChannel.url, currentGroupChannel.url)) { + if (compareIds(groupChannel.url, channelUrl)) { logger.info('Channel | useHandleChannelEvents: onOperatorUpdated', groupChannel); messagesDispatcher({ type: messageActions.SET_CURRENT_CHANNEL,