Skip to content

Commit 27b21ee

Browse files
author
Sravan S
authored
fix: fix not showing newly recived messages (#410)
We decided not to filter at event handler, instead we filter, clean at reducer fixes: [UIKIT-2877](https://sendbird.atlassian.net/browse/UIKIT-2877)
1 parent a46bf78 commit 27b21ee

File tree

7 files changed

+97
-29
lines changed

7 files changed

+97
-29
lines changed

src/smart-components/Channel/context/ChannelProvider.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,7 @@ const ChannelProvider: React.FC<ChannelContextProps> = (props: ChannelContextPro
321321
currentGroupChannel,
322322
sdkInit,
323323
currentUserId: userId,
324-
hasMoreNext,
325-
disableMarkAsRead
324+
disableMarkAsRead,
326325
},
327326
{
328327
messagesDispatcher,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// test mergeAndSortMessages
2+
// const mergedMessages = [...oldMessages, ...newMessages];
3+
// const getUniqueListByMessageId = (arr) => getUniqueListBy(arr, 'messageId');
4+
// const unique = getUniqueListByMessageId(mergedMessages);
5+
// return unique;
6+
7+
import { mergeAndSortMessages } from "../utils";
8+
9+
const oldMessages = [
10+
{
11+
messageId: 390282401,
12+
createdAt: 390282401,
13+
},
14+
{
15+
messageId: 390282407,
16+
createdAt: 390282407,
17+
},
18+
];
19+
20+
const messagesToAdd_1 = [
21+
{
22+
messageId: 390282408,
23+
createdAt: 390282408
24+
},
25+
{
26+
messageId: 390282409,
27+
createdAt: 390282409,
28+
},
29+
];
30+
31+
const messagesToAdd_2 = [
32+
{
33+
messageId: 390282404,
34+
createdAt: 390282404,
35+
},
36+
{
37+
messageId: 390282405,
38+
createdAt: 390282405,
39+
},
40+
];
41+
42+
describe('mergeAndSortMessages', () => {
43+
it('should append new list of messages to end of list', () => {
44+
const newList = mergeAndSortMessages(oldMessages, messagesToAdd_1);
45+
expect(newList).toEqual([...oldMessages, ...messagesToAdd_1]);
46+
});
47+
48+
it('should sort messages by createdAt', () => {
49+
const newList = mergeAndSortMessages(oldMessages, messagesToAdd_2);
50+
expect(newList).toEqual([
51+
oldMessages[0],
52+
messagesToAdd_2[0],
53+
messagesToAdd_2[1],
54+
oldMessages[1],
55+
]);
56+
});
57+
});

src/smart-components/Channel/context/dux/__tests__/reducers.spec.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { mockMessage1, generateMockMessage, generateMockChannel } from '../data.mock';
1+
import {
2+
mockMessage1,
3+
generateMockMessage,
4+
generateMockChannel,
5+
} from '../data.mock';
26
import * as actionTypes from '../actionTypes';
37
import reducers from '../reducers';
48
import initialState from '../initialState';

src/smart-components/Channel/context/dux/data.mock.js

+8
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ export const mockMessage1 = {
175175
"errorCode": 0,
176176
threadInfo: null,
177177
};
178+
export const mockMessage2 = {
179+
"messageId": 390292882,
180+
"channelUrl": "sendbird_group_channel_13883929_3dc3bb3af92eded8ff8e5f71de775fe149a32dd6",
181+
"data": "",
182+
"customType": "",
183+
"createdAt": 1582004961440,
184+
"updatedAt": 0,
185+
};
178186

179187
export const frozenChannel = {
180188
"url": "sendbird_group_channel_204619489_3df4fd3d2feeef8bb0775e57950784a92fa3184c",

src/smart-components/Channel/context/dux/reducers.js

+4-22
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import format from 'date-fns/format';
33
import * as actionTypes from './actionTypes';
44
import compareIds from '../../../../utils/compareIds';
55
import { PREV_RESULT_SIZE, NEXT_RESULT_SIZE } from '../const';
6-
import { passUnsuccessfullMessages } from '../utils';
6+
import { passUnsuccessfullMessages, mergeAndSortMessages } from '../utils';
77
import { filterMessageListParams, getSendingMessageStatus } from '../../../../utils';
88

99
const {
@@ -111,32 +111,14 @@ export default function reducer(state, action) {
111111
const hasMoreNext = messages && messages.length === NEXT_RESULT_SIZE + 1;
112112
const latestMessageTimeStamp = getLatestMessageTimeStamp(messages);
113113

114-
// Remove duplicated messages
115-
const duplicatedMessageIds = [];
116-
const updatedOldMessages = state.allMessages.map((msg) => {
117-
const duplicatedMessage = messages.find(({ messageId }) => (
118-
compareIds(messageId, msg.messageId)
119-
));
120-
if (!duplicatedMessage) {
121-
return msg;
122-
}
123-
duplicatedMessageIds.push(duplicatedMessage.messageId);
124-
return (duplicatedMessage.updatedAt > msg.updatedAt) ? duplicatedMessage : msg;
125-
});
126-
const filteredNewMessages = (duplicatedMessageIds.length > 0)
127-
? messages.filter((msg) => (
128-
!duplicatedMessageIds.find((messageId) => compareIds(messageId, msg.messageId))
129-
))
130-
: messages;
114+
// sort ~
115+
const sortedMessages = mergeAndSortMessages(state.allMessages, messages);
131116

132117
return {
133118
...state,
134119
hasMoreNext,
135120
latestMessageTimeStamp,
136-
allMessages: [
137-
...updatedOldMessages,
138-
...filteredNewMessages,
139-
],
121+
allMessages: sortedMessages,
140122
};
141123
}
142124
case actionTypes.FETCH_INITIAL_MESSAGES_FAILURE:

src/smart-components/Channel/context/hooks/useHandleChannelEvents.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import * as messageActions from '../dux/actionTypes';
1919
*/
2020
interface DynamicParams {
2121
sdkInit: boolean;
22-
hasMoreNext: boolean;
2322
currentUserId: string;
2423
disableMarkAsRead: boolean;
2524
currentGroupChannel: GroupChannel;
@@ -34,7 +33,6 @@ interface StaticParams {
3433

3534
function useHandleChannelEvents({
3635
sdkInit,
37-
hasMoreNext,
3836
currentUserId,
3937
disableMarkAsRead,
4038
currentGroupChannel,
@@ -51,8 +49,7 @@ function useHandleChannelEvents({
5149
if (channelUrl && sdkInit) {
5250
const channelHandler: GroupChannelHandler = {
5351
onMessageReceived: (channel, message) => {
54-
// Do not update when hasMoreNext
55-
if (compareIds(channel?.url, channelUrl) && !hasMoreNext) {
52+
if (compareIds(channel?.url, channelUrl)) {
5653
let scrollToEnd = false;
5754
try {
5855
const { current } = scrollRef;

src/smart-components/Channel/context/utils.js

+21
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,27 @@ export const getNicknamesMapFromMembers = (members = []) => {
186186
return nicknamesMap;
187187
};
188188

189+
const getUniqueListBy = (arr, key) => [...new Map(arr.map((item) => [item[key], item])).values()];
190+
const getUniqueListByMessageId = (arr) => getUniqueListBy(arr, 'messageId');
191+
const sortByCreatedAt = (messages) => messages.sort((a, b) => a.createdAt - b.createdAt);
192+
193+
export const mergeAndSortMessages = (oldMessages, newMessages) => {
194+
const lastOldMessage = oldMessages[oldMessages.length - 1];
195+
const firstNewMessage = newMessages[0];
196+
// If the last message of oldMessages is older than the first message of newMessages,
197+
// then we can safely append newMessages to oldMessages.
198+
if (lastOldMessage?.createdAt < firstNewMessage?.createdAt) {
199+
return [...oldMessages, ...newMessages];
200+
}
201+
202+
// todo: optimize this
203+
// If the last message of oldMessages is newer than the first message of newMessages,
204+
// then we need to merge the two arrays and sort them by createdAt.
205+
const mergedMessages = [...oldMessages, ...newMessages];
206+
const unique = getUniqueListByMessageId(mergedMessages);
207+
return sortByCreatedAt(unique);
208+
};
209+
189210
export const getMessageCreatedAt = (message) => format(message.createdAt, 'p');
190211

191212
export const isSameGroup = (message, comparingMessage, currentChannel) => {

0 commit comments

Comments
 (0)