Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/smart-components/Channel/context/ChannelProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,7 @@ const ChannelProvider: React.FC<ChannelContextProps> = (props: ChannelContextPro
currentGroupChannel,
sdkInit,
currentUserId: userId,
hasMoreNext,
disableMarkAsRead
disableMarkAsRead,
},
{
messagesDispatcher,
Expand Down
57 changes: 57 additions & 0 deletions src/smart-components/Channel/context/__test__/utils.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// test mergeAndSortMessages
// const mergedMessages = [...oldMessages, ...newMessages];
// const getUniqueListByMessageId = (arr) => getUniqueListBy(arr, 'messageId');
// const unique = getUniqueListByMessageId(mergedMessages);
// return unique;

import { mergeAndSortMessages } from "../utils";

const oldMessages = [
{
messageId: 390282401,
createdAt: 390282401,
},
{
messageId: 390282407,
createdAt: 390282407,
},
];

const messagesToAdd_1 = [
{
messageId: 390282408,
createdAt: 390282408
},
{
messageId: 390282409,
createdAt: 390282409,
},
];

const messagesToAdd_2 = [
{
messageId: 390282404,
createdAt: 390282404,
},
{
messageId: 390282405,
createdAt: 390282405,
},
];

describe('mergeAndSortMessages', () => {
it('should append new list of messages to end of list', () => {
const newList = mergeAndSortMessages(oldMessages, messagesToAdd_1);
expect(newList).toEqual([...oldMessages, ...messagesToAdd_1]);
});

it('should sort messages by createdAt', () => {
const newList = mergeAndSortMessages(oldMessages, messagesToAdd_2);
expect(newList).toEqual([
oldMessages[0],
messagesToAdd_2[0],
messagesToAdd_2[1],
oldMessages[1],
]);
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { mockMessage1, generateMockMessage, generateMockChannel } from '../data.mock';
import {
mockMessage1,
generateMockMessage,
generateMockChannel,
} from '../data.mock';
import * as actionTypes from '../actionTypes';
import reducers from '../reducers';
import initialState from '../initialState';
Expand Down
8 changes: 8 additions & 0 deletions src/smart-components/Channel/context/dux/data.mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ export const mockMessage1 = {
"errorCode": 0,
threadInfo: null,
};
export const mockMessage2 = {
"messageId": 390292882,
"channelUrl": "sendbird_group_channel_13883929_3dc3bb3af92eded8ff8e5f71de775fe149a32dd6",
"data": "",
"customType": "",
"createdAt": 1582004961440,
"updatedAt": 0,
};

export const frozenChannel = {
"url": "sendbird_group_channel_204619489_3df4fd3d2feeef8bb0775e57950784a92fa3184c",
Expand Down
26 changes: 4 additions & 22 deletions src/smart-components/Channel/context/dux/reducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import format from 'date-fns/format';
import * as actionTypes from './actionTypes';
import compareIds from '../../../../utils/compareIds';
import { PREV_RESULT_SIZE, NEXT_RESULT_SIZE } from '../const';
import { passUnsuccessfullMessages } from '../utils';
import { passUnsuccessfullMessages, mergeAndSortMessages } from '../utils';
import { filterMessageListParams, getSendingMessageStatus } from '../../../../utils';

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

// Remove duplicated messages
const duplicatedMessageIds = [];
const updatedOldMessages = state.allMessages.map((msg) => {
const duplicatedMessage = messages.find(({ messageId }) => (
compareIds(messageId, msg.messageId)
));
if (!duplicatedMessage) {
return msg;
}
duplicatedMessageIds.push(duplicatedMessage.messageId);
return (duplicatedMessage.updatedAt > msg.updatedAt) ? duplicatedMessage : msg;
});
const filteredNewMessages = (duplicatedMessageIds.length > 0)
? messages.filter((msg) => (
!duplicatedMessageIds.find((messageId) => compareIds(messageId, msg.messageId))
))
: messages;
// sort ~
const sortedMessages = mergeAndSortMessages(state.allMessages, messages);

return {
...state,
hasMoreNext,
latestMessageTimeStamp,
allMessages: [
...updatedOldMessages,
...filteredNewMessages,
],
allMessages: sortedMessages,
};
}
case actionTypes.FETCH_INITIAL_MESSAGES_FAILURE:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import * as messageActions from '../dux/actionTypes';
*/
interface DynamicParams {
sdkInit: boolean;
hasMoreNext: boolean;
currentUserId: string;
disableMarkAsRead: boolean;
currentGroupChannel: GroupChannel;
Expand All @@ -34,7 +33,6 @@ interface StaticParams {

function useHandleChannelEvents({
sdkInit,
hasMoreNext,
currentUserId,
disableMarkAsRead,
currentGroupChannel,
Expand All @@ -51,8 +49,7 @@ function useHandleChannelEvents({
if (channelUrl && sdkInit) {
const channelHandler: GroupChannelHandler = {
onMessageReceived: (channel, message) => {
// Do not update when hasMoreNext
if (compareIds(channel?.url, channelUrl) && !hasMoreNext) {
if (compareIds(channel?.url, channelUrl)) {
let scrollToEnd = false;
try {
const { current } = scrollRef;
Expand Down
21 changes: 21 additions & 0 deletions src/smart-components/Channel/context/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,27 @@ export const getNicknamesMapFromMembers = (members = []) => {
return nicknamesMap;
};

const getUniqueListBy = (arr, key) => [...new Map(arr.map((item) => [item[key], item])).values()];
const getUniqueListByMessageId = (arr) => getUniqueListBy(arr, 'messageId');
const sortByCreatedAt = (messages) => messages.sort((a, b) => a.createdAt - b.createdAt);

export const mergeAndSortMessages = (oldMessages, newMessages) => {
const lastOldMessage = oldMessages[oldMessages.length - 1];
const firstNewMessage = newMessages[0];
// If the last message of oldMessages is older than the first message of newMessages,
// then we can safely append newMessages to oldMessages.
if (lastOldMessage?.createdAt < firstNewMessage?.createdAt) {
return [...oldMessages, ...newMessages];
}

// todo: optimize this
// If the last message of oldMessages is newer than the first message of newMessages,
// then we need to merge the two arrays and sort them by createdAt.
const mergedMessages = [...oldMessages, ...newMessages];
const unique = getUniqueListByMessageId(mergedMessages);
return sortByCreatedAt(unique);
};

export const getMessageCreatedAt = (message) => format(message.createdAt, 'p');

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