Skip to content

Commit 53b7928

Browse files
authored
Merge pull request #118 from sendbird/feat/quote-reply
feat(UIKIT-3688): quote reply
2 parents 1b0c1dc + 3003549 commit 53b7928

File tree

68 files changed

+1287
-539
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1287
-539
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,6 @@
9696
]
9797
},
9898
"resolutions": {
99-
"@sendbird/chat": "4.9.2"
99+
"@sendbird/chat": "4.9.8"
100100
}
101101
}

packages/uikit-chat-hooks/src/__tests__/channel/useChannelMessagesReducer.test.ts

Lines changed: 136 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ describe('useChannelMessagesReducer', () => {
207207
test('should replace pending messages to succeeded messages', () => {
208208
const me = createMockUser({ userId: 'sender1' }).asSender();
209209
const initMessage = createMockMessage({
210+
reqId: 'req-id-1',
210211
messageId: 3,
211212
message: 'World',
212213
sendingStatus: SendingStatus.SUCCEEDED,
@@ -215,12 +216,14 @@ describe('useChannelMessagesReducer', () => {
215216

216217
const pendingMessages = [
217218
createMockMessage({
219+
reqId: 'req-id-2',
218220
sender: me,
219221
message: 'Hello',
220222
sendingStatus: SendingStatus.PENDING,
221223
messageType: MessageType.USER,
222224
}),
223225
createMockMessage({
226+
reqId: 'req-id-3',
224227
sender: me,
225228
message: 'World',
226229
sendingStatus: SendingStatus.PENDING,
@@ -230,22 +233,16 @@ describe('useChannelMessagesReducer', () => {
230233

231234
const sentMessages = [
232235
createMockMessage({
233-
reqId: pendingMessages[0].asUserMessage().reqId,
234-
sender: pendingMessages[0].asUserMessage().sender,
235-
message: pendingMessages[0].asUserMessage().message,
236+
...pendingMessages[0],
236237
sendingStatus: SendingStatus.SUCCEEDED,
237-
messageType: pendingMessages[0].asUserMessage().messageType,
238238
}),
239239
createMockMessage({
240-
reqId: pendingMessages[1].asUserMessage().reqId,
241-
sender: pendingMessages[1].asUserMessage().sender,
242-
message: pendingMessages[1].asUserMessage().message,
240+
...pendingMessages[1],
243241
sendingStatus: SendingStatus.SUCCEEDED,
244-
messageType: pendingMessages[1].asUserMessage().messageType,
245242
}),
246243
];
247244

248-
const { result } = renderHook(() => useChannelMessagesReducer());
245+
const { result } = renderHook(() => useChannelMessagesReducer((a, b) => a.createdAt - b.createdAt));
249246

250247
act(() => {
251248
result.current.updateMessages([initMessage], true, me.userId);
@@ -264,4 +261,134 @@ describe('useChannelMessagesReducer', () => {
264261
expect(result.current.messages).toHaveLength(3);
265262
expect(result.current.messages).toEqual([initMessage, ...sentMessages]);
266263
});
264+
265+
test('should update succeeded messages with reactions updated', () => {
266+
const me = createMockUser({ userId: 'sender1' }).asSender();
267+
268+
const sentMessages = [
269+
createMockMessage({
270+
sender: me,
271+
message: 'Hello',
272+
sendingStatus: SendingStatus.SUCCEEDED,
273+
messageType: MessageType.USER,
274+
createdAt: 1000,
275+
}),
276+
createMockMessage({
277+
sender: me,
278+
message: 'World',
279+
sendingStatus: SendingStatus.SUCCEEDED,
280+
messageType: MessageType.USER,
281+
createdAt: 1200,
282+
}),
283+
];
284+
285+
const updatedMessages = [
286+
createMockMessage({
287+
...sentMessages[0],
288+
reactions: [{ key: 'string', userIds: [], updatedAt: Date.now(), isEmpty: false, applyEvent: jest.fn() }],
289+
}),
290+
];
291+
292+
const { result } = renderHook(() => useChannelMessagesReducer((a, b) => a.createdAt - b.createdAt));
293+
294+
act(() => {
295+
result.current.updateMessages(sentMessages, true, me.userId);
296+
});
297+
expect(result.current.messages).toHaveLength(2);
298+
expect(result.current.messages).toEqual(sentMessages);
299+
300+
act(() => {
301+
result.current.updateMessages(updatedMessages, false, me.userId);
302+
});
303+
expect(result.current.messages).toHaveLength(2);
304+
expect(result.current.messages).toEqual([updatedMessages[0], sentMessages[1]]);
305+
});
306+
307+
test('should update succeeded messages with message updated', () => {
308+
const me = createMockUser({ userId: 'sender1' }).asSender();
309+
310+
const sentMessages = [
311+
createMockMessage({
312+
sender: me,
313+
message: 'Hello',
314+
sendingStatus: SendingStatus.SUCCEEDED,
315+
messageType: MessageType.USER,
316+
createdAt: 1000,
317+
}),
318+
createMockMessage({
319+
sender: me,
320+
message: 'World',
321+
sendingStatus: SendingStatus.SUCCEEDED,
322+
messageType: MessageType.USER,
323+
createdAt: 1200,
324+
}),
325+
];
326+
327+
const updatedMessages = [
328+
createMockMessage({
329+
...sentMessages[0],
330+
reqId: 'edited-req-id',
331+
message: 'Hello (edited)',
332+
updatedAt: Date.now(),
333+
}),
334+
];
335+
336+
const { result } = renderHook(() => useChannelMessagesReducer((a, b) => a.createdAt - b.createdAt));
337+
338+
act(() => {
339+
result.current.updateMessages(sentMessages, true, me.userId);
340+
});
341+
expect(result.current.messages).toHaveLength(2);
342+
expect(result.current.messages).toEqual(sentMessages);
343+
344+
act(() => {
345+
result.current.updateMessages(updatedMessages, false, me.userId);
346+
});
347+
expect(result.current.messages).toHaveLength(2);
348+
expect(result.current.messages).toEqual([updatedMessages[0], sentMessages[1]]);
349+
});
350+
351+
test('should not update when receiving pending messages that have already been inserted as succeeded', () => {
352+
const me = createMockUser({ userId: 'sender1' }).asSender();
353+
const { result } = renderHook(() => useChannelMessagesReducer((a, b) => a.createdAt - b.createdAt));
354+
355+
const pending = createMockMessage({
356+
reqId: 'req-id-1',
357+
message: 'Hello',
358+
sender: me,
359+
messageType: MessageType.USER,
360+
sendingStatus: SendingStatus.PENDING,
361+
});
362+
const sent = createMockMessage({
363+
reqId: 'req-id-1',
364+
message: 'Hello',
365+
sender: me,
366+
messageType: MessageType.USER,
367+
sendingStatus: SendingStatus.SUCCEEDED,
368+
});
369+
370+
act(() => {
371+
result.current.updateMessages([pending], true, me.userId);
372+
});
373+
expect(result.current.messages).toHaveLength(1);
374+
expect(result.current.messages).toEqual([pending]);
375+
376+
act(() => {
377+
result.current.updateMessages([sent], false, me.userId);
378+
});
379+
expect(result.current.messages).toHaveLength(1);
380+
expect(result.current.messages).toEqual([sent]);
381+
382+
act(() => {
383+
result.current.updateMessages([pending], false, me.userId);
384+
});
385+
expect(result.current.messages).toHaveLength(1);
386+
expect(result.current.messages).toEqual([sent]);
387+
388+
act(() => {
389+
result.current.updateMessages([sent], false, me.userId);
390+
});
391+
expect(result.current.messages).toHaveLength(1);
392+
expect(result.current.messages).toEqual([sent]);
393+
});
267394
});

packages/uikit-chat-hooks/src/__tests__/channel/useGroupChannelList/index.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe('useGroupChannelList', () => {
3131
const sdk = createMockSendbirdChat({ localCacheEnabled: true });
3232
const options = { collectionCreator: jest.fn() };
3333

34-
renderHook(() => useGroupChannelList(sdk, sdk.currentUser.userId, options));
34+
renderHook(() => useGroupChannelList(sdk, sdk.currentUser?.userId, options));
3535

3636
await waitFor(() => {
3737
expect(useGroupChannelListWithCollection).toHaveBeenCalledTimes(1);
@@ -42,7 +42,7 @@ describe('useGroupChannelList', () => {
4242
const sdk = createMockSendbirdChat({ localCacheEnabled: false });
4343
const options = { collectionCreator: jest.fn(), enableCollectionWithoutLocalCache: true };
4444

45-
renderHook(() => useGroupChannelList(sdk, sdk.currentUser.userId, options));
45+
renderHook(() => useGroupChannelList(sdk, sdk.currentUser?.userId, options));
4646

4747
await waitFor(() => {
4848
expect(useGroupChannelListWithCollection).toHaveBeenCalledTimes(1);
@@ -53,23 +53,23 @@ describe('useGroupChannelList', () => {
5353
const sdk = createMockSendbirdChat({ localCacheEnabled: true });
5454
const options = { collectionCreator: jest.fn() };
5555

56-
renderHook(() => useGroupChannelList(sdk, sdk.currentUser.userId, options));
56+
renderHook(() => useGroupChannelList(sdk, sdk.currentUser?.userId, options));
5757

5858
await waitFor(() => {
5959
expect(useGroupChannelListWithCollection).toHaveBeenCalledTimes(1);
60-
expect(useGroupChannelListWithCollection).toHaveBeenCalledWith(sdk, sdk.currentUser.userId, options);
60+
expect(useGroupChannelListWithCollection).toHaveBeenCalledWith(sdk, sdk.currentUser?.userId, options);
6161
});
6262
});
6363

6464
it('should call useGroupChannelListWithQuery with the correct arguments', async () => {
6565
const sdk = createMockSendbirdChat({ localCacheEnabled: false });
6666
const options = { queryCreator: jest.fn() };
6767

68-
renderHook(() => useGroupChannelList(sdk, sdk.currentUser.userId, options));
68+
renderHook(() => useGroupChannelList(sdk, sdk.currentUser?.userId, options));
6969

7070
await waitFor(() => {
7171
expect(useGroupChannelListWithQuery).toHaveBeenCalledTimes(1);
72-
expect(useGroupChannelListWithQuery).toHaveBeenCalledWith(sdk, sdk.currentUser.userId, options);
72+
expect(useGroupChannelListWithQuery).toHaveBeenCalledWith(sdk, sdk.currentUser?.userId, options);
7373
});
7474
});
7575
});

packages/uikit-chat-hooks/src/__tests__/channel/useGroupChannelList/useGroupChannelListWithCollection.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('useGroupChannelListWithCollection', () => {
99
it('should initialize and return default value', async () => {
1010
const sdk = createMockSendbirdChat();
1111

12-
const { result } = renderHook(() => useGroupChannelListWithCollection(sdk, sdk.currentUser.userId));
12+
const { result } = renderHook(() => useGroupChannelListWithCollection(sdk, sdk.currentUser?.userId));
1313

1414
expect(result.current.loading).toBe(true);
1515
expect(result.current.refreshing).toBe(false);
@@ -30,7 +30,7 @@ describe('useGroupChannelListWithCollection', () => {
3030
collectionCreator: jest.fn(() => sdk.groupChannel.createGroupChannelCollection(collectionParams)),
3131
};
3232

33-
renderHook(() => useGroupChannelListWithCollection(sdk, sdk.currentUser.userId, options));
33+
renderHook(() => useGroupChannelListWithCollection(sdk, sdk.currentUser?.userId, options));
3434

3535
await waitFor(() => {
3636
expect(options.collectionCreator).toHaveBeenCalled();
@@ -45,7 +45,7 @@ describe('useGroupChannelListWithCollection', () => {
4545
const collectionCreator = jest.fn(() => collection);
4646

4747
const { result } = renderHook(() =>
48-
useGroupChannelListWithCollection(sdk, sdk.currentUser.userId, { collectionCreator }),
48+
useGroupChannelListWithCollection(sdk, sdk.currentUser?.userId, { collectionCreator }),
4949
);
5050
expect(result.current.refreshing).toBe(false);
5151
expect(collectionCreator).toHaveBeenCalledTimes(1);
@@ -69,7 +69,7 @@ describe('useGroupChannelListWithCollection', () => {
6969
const collectionCreator = jest.fn(() => collection);
7070

7171
const { unmount } = renderHook(() =>
72-
useGroupChannelListWithCollection(sdk, sdk.currentUser.userId, { collectionCreator }),
72+
useGroupChannelListWithCollection(sdk, sdk.currentUser?.userId, { collectionCreator }),
7373
);
7474

7575
unmount();
@@ -85,7 +85,7 @@ describe('useGroupChannelListWithCollection', () => {
8585
const fetchableCollection = createMockGroupChannelCollection({ sdk, limit: 10, hasMore: true });
8686

8787
const { result } = renderHook(() =>
88-
useGroupChannelListWithCollection(sdk, sdk.currentUser.userId, { collectionCreator: () => fetchableCollection }),
88+
useGroupChannelListWithCollection(sdk, sdk.currentUser?.userId, { collectionCreator: () => fetchableCollection }),
8989
);
9090

9191
await waitFor(() => {
@@ -109,7 +109,7 @@ describe('useGroupChannelListWithCollection', () => {
109109
const unFetchableCollection = createMockGroupChannelCollection({ sdk, limit: 10, hasMore: false });
110110

111111
const { result } = renderHook(() =>
112-
useGroupChannelListWithCollection(sdk, sdk.currentUser.userId, {
112+
useGroupChannelListWithCollection(sdk, sdk.currentUser?.userId, {
113113
collectionCreator: () => unFetchableCollection,
114114
}),
115115
);

packages/uikit-chat-hooks/src/__tests__/channel/useGroupChannelList/useGroupChannelListWithQuery.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('useGroupChannelListWithQuery', () => {
99
it('should initialize and return default value', async () => {
1010
const sdk = createMockSendbirdChat();
1111

12-
const { result } = renderHook(() => useGroupChannelListWithQuery(sdk, sdk.currentUser.userId));
12+
const { result } = renderHook(() => useGroupChannelListWithQuery(sdk, sdk.currentUser?.userId));
1313

1414
expect(result.current.loading).toBe(true);
1515
expect(result.current.refreshing).toBe(false);
@@ -30,7 +30,7 @@ describe('useGroupChannelListWithQuery', () => {
3030
queryCreator: jest.fn(() => sdk.groupChannel.createMyGroupChannelListQuery(queryParams)),
3131
};
3232

33-
renderHook(() => useGroupChannelListWithQuery(sdk, sdk.currentUser.userId, options));
33+
renderHook(() => useGroupChannelListWithQuery(sdk, sdk.currentUser?.userId, options));
3434

3535
await waitFor(() => {
3636
expect(options.queryCreator).toHaveBeenCalled();
@@ -49,7 +49,7 @@ describe('useGroupChannelListWithQuery', () => {
4949
}) as unknown as GroupChannelListQuery;
5050
const queryCreator = jest.fn(() => query);
5151

52-
const { result } = renderHook(() => useGroupChannelListWithQuery(sdk, sdk.currentUser.userId, { queryCreator }));
52+
const { result } = renderHook(() => useGroupChannelListWithQuery(sdk, sdk.currentUser?.userId, { queryCreator }));
5353
expect(result.current.refreshing).toBe(false);
5454
expect(queryCreator).toHaveBeenCalledTimes(1);
5555

@@ -74,7 +74,7 @@ describe('useGroupChannelListWithQuery', () => {
7474
}) as unknown as GroupChannelListQuery;
7575

7676
const { result } = renderHook(() =>
77-
useGroupChannelListWithQuery(sdk, sdk.currentUser.userId, { queryCreator: () => fetchableQuery }),
77+
useGroupChannelListWithQuery(sdk, sdk.currentUser?.userId, { queryCreator: () => fetchableQuery }),
7878
);
7979

8080
await waitFor(() => {
@@ -102,7 +102,7 @@ describe('useGroupChannelListWithQuery', () => {
102102
}) as unknown as GroupChannelListQuery;
103103

104104
const { result } = renderHook(() =>
105-
useGroupChannelListWithQuery(sdk, sdk.currentUser.userId, { queryCreator: () => unFetchableQuery }),
105+
useGroupChannelListWithQuery(sdk, sdk.currentUser?.userId, { queryCreator: () => unFetchableQuery }),
106106
);
107107

108108
await waitFor(() => {

packages/uikit-chat-hooks/src/__tests__/channel/useGroupChannelMessages/index.test.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe('useGroupChannelMessages', () => {
3232
const channel = await sdk.groupChannel.getChannel('test-channel');
3333
const options = { collectionCreator: jest.fn() };
3434

35-
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser.userId, options));
35+
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser?.userId, options));
3636

3737
await waitFor(() => {
3838
expect(useGroupChannelMessagesWithCollection).toHaveBeenCalledTimes(1);
@@ -44,7 +44,7 @@ describe('useGroupChannelMessages', () => {
4444
const channel = await sdk.groupChannel.getChannel('test-channel');
4545
const options = { collectionCreator: jest.fn(), enableCollectionWithoutLocalCache: true };
4646

47-
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser.userId, options));
47+
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser?.userId, options));
4848

4949
await waitFor(() => {
5050
expect(useGroupChannelMessagesWithCollection).toHaveBeenCalledTimes(1);
@@ -56,11 +56,16 @@ describe('useGroupChannelMessages', () => {
5656
const channel = await sdk.groupChannel.getChannel('test-channel');
5757
const options = { collectionCreator: jest.fn() };
5858

59-
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser.userId, options));
59+
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser?.userId, options));
6060

6161
await waitFor(() => {
6262
expect(useGroupChannelMessagesWithCollection).toHaveBeenCalledTimes(1);
63-
expect(useGroupChannelMessagesWithCollection).toHaveBeenCalledWith(sdk, channel, sdk.currentUser.userId, options);
63+
expect(useGroupChannelMessagesWithCollection).toHaveBeenCalledWith(
64+
sdk,
65+
channel,
66+
sdk.currentUser?.userId,
67+
options,
68+
);
6469
});
6570
});
6671

@@ -69,11 +74,11 @@ describe('useGroupChannelMessages', () => {
6974
const channel = await sdk.groupChannel.getChannel('test-channel');
7075
const options = { queryCreator: jest.fn() };
7176

72-
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser.userId, options));
77+
renderHook(() => useGroupChannelMessages(sdk, channel, sdk.currentUser?.userId, options));
7378

7479
await waitFor(() => {
7580
expect(useGroupChannelMessagesWithQuery).toHaveBeenCalledTimes(1);
76-
expect(useGroupChannelMessagesWithQuery).toHaveBeenCalledWith(sdk, channel, sdk.currentUser.userId, options);
81+
expect(useGroupChannelMessagesWithQuery).toHaveBeenCalledWith(sdk, channel, sdk.currentUser?.userId, options);
7782
});
7883
});
7984
});

0 commit comments

Comments
 (0)