diff --git a/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js b/src/smart-components/Channel/context/hooks/useHandleChannelEvents.js index 821a41785..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,6 +63,30 @@ 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(channel.url, channelUrl)) { + logger.info('Channel | useHandleChannelEvents: onReadReceiptUpdated', channel); + messagesDispatcher({ + type: messageActions.SET_CURRENT_CHANNEL, + payload: channel, + }); + } + }; + ChannelHandler.onDeliveryReceiptUpdated = (channel) => { + if (compareIds(channel.url, channelUrl)) { + 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({ @@ -97,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, @@ -107,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, @@ -117,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, @@ -127,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, @@ -137,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, @@ -147,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, @@ -157,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, 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', 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' };