stream-chat-react-native-core 6.0.2 → 6.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/components/Channel/Channel.js +371 -279
  3. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  4. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js +8 -0
  5. package/lib/commonjs/components/Channel/hooks/useChannelDataState.js.map +1 -1
  6. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js +10 -1
  7. package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  8. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  9. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  10. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +161 -69
  11. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  12. package/lib/commonjs/components/Channel/hooks/useTargetedMessage.js +10 -0
  13. package/lib/commonjs/components/Channel/hooks/useTargetedMessage.js.map +1 -1
  14. package/lib/commonjs/components/Chat/hooks/handleEventToSyncDB.js +81 -54
  15. package/lib/commonjs/components/Chat/hooks/handleEventToSyncDB.js.map +1 -1
  16. package/lib/commonjs/components/Message/Message.js +6 -0
  17. package/lib/commonjs/components/Message/Message.js.map +1 -1
  18. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js +117 -79
  19. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  20. package/lib/commonjs/components/Message/hooks/useMessageActions.js +32 -14
  21. package/lib/commonjs/components/Message/hooks/useMessageActions.js.map +1 -1
  22. package/lib/commonjs/components/Message/utils/messageActions.js +4 -0
  23. package/lib/commonjs/components/Message/utils/messageActions.js.map +1 -1
  24. package/lib/commonjs/components/MessageList/InlineUnreadIndicator.js +19 -55
  25. package/lib/commonjs/components/MessageList/InlineUnreadIndicator.js.map +1 -1
  26. package/lib/commonjs/components/MessageList/MessageList.js +249 -211
  27. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  28. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js +148 -0
  29. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js.map +1 -0
  30. package/lib/commonjs/components/MessageMenu/MessageActionListItem.js.map +1 -1
  31. package/lib/commonjs/contexts/channelContext/ChannelContext.js.map +1 -1
  32. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  33. package/lib/commonjs/contexts/themeContext/utils/theme.js +7 -1
  34. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  35. package/lib/commonjs/i18n/en.json +2 -0
  36. package/lib/commonjs/i18n/es.json +2 -0
  37. package/lib/commonjs/i18n/fr.json +2 -0
  38. package/lib/commonjs/i18n/he.json +2 -0
  39. package/lib/commonjs/i18n/hi.json +2 -0
  40. package/lib/commonjs/i18n/it.json +2 -0
  41. package/lib/commonjs/i18n/ja.json +2 -0
  42. package/lib/commonjs/i18n/ko.json +2 -0
  43. package/lib/commonjs/i18n/nl.json +2 -0
  44. package/lib/commonjs/i18n/pt-br.json +2 -0
  45. package/lib/commonjs/i18n/ru.json +2 -0
  46. package/lib/commonjs/i18n/tr.json +2 -0
  47. package/lib/commonjs/icons/UnreadIndicator.js +30 -0
  48. package/lib/commonjs/icons/UnreadIndicator.js.map +1 -0
  49. package/lib/commonjs/icons/index.js +11 -0
  50. package/lib/commonjs/icons/index.js.map +1 -1
  51. package/lib/commonjs/store/SqliteClient.js +1 -1
  52. package/lib/commonjs/store/schema.js +1 -0
  53. package/lib/commonjs/store/schema.js.map +1 -1
  54. package/lib/commonjs/types/types.js.map +1 -1
  55. package/lib/commonjs/utils/utils.js +35 -1
  56. package/lib/commonjs/utils/utils.js.map +1 -1
  57. package/lib/commonjs/version.json +1 -1
  58. package/lib/module/components/Channel/Channel.js +371 -279
  59. package/lib/module/components/Channel/Channel.js.map +1 -1
  60. package/lib/module/components/Channel/hooks/useChannelDataState.js +8 -0
  61. package/lib/module/components/Channel/hooks/useChannelDataState.js.map +1 -1
  62. package/lib/module/components/Channel/hooks/useCreateChannelContext.js +10 -1
  63. package/lib/module/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
  64. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  65. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  66. package/lib/module/components/Channel/hooks/useMessageListPagination.js +161 -69
  67. package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  68. package/lib/module/components/Channel/hooks/useTargetedMessage.js +10 -0
  69. package/lib/module/components/Channel/hooks/useTargetedMessage.js.map +1 -1
  70. package/lib/module/components/Chat/hooks/handleEventToSyncDB.js +81 -54
  71. package/lib/module/components/Chat/hooks/handleEventToSyncDB.js.map +1 -1
  72. package/lib/module/components/Message/Message.js +6 -0
  73. package/lib/module/components/Message/Message.js.map +1 -1
  74. package/lib/module/components/Message/hooks/useMessageActionHandlers.js +117 -79
  75. package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  76. package/lib/module/components/Message/hooks/useMessageActions.js +32 -14
  77. package/lib/module/components/Message/hooks/useMessageActions.js.map +1 -1
  78. package/lib/module/components/Message/utils/messageActions.js +4 -0
  79. package/lib/module/components/Message/utils/messageActions.js.map +1 -1
  80. package/lib/module/components/MessageList/InlineUnreadIndicator.js +19 -55
  81. package/lib/module/components/MessageList/InlineUnreadIndicator.js.map +1 -1
  82. package/lib/module/components/MessageList/MessageList.js +249 -211
  83. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  84. package/lib/module/components/MessageList/UnreadMessagesNotification.js +148 -0
  85. package/lib/module/components/MessageList/UnreadMessagesNotification.js.map +1 -0
  86. package/lib/module/components/MessageMenu/MessageActionListItem.js.map +1 -1
  87. package/lib/module/contexts/channelContext/ChannelContext.js.map +1 -1
  88. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  89. package/lib/module/contexts/themeContext/utils/theme.js +7 -1
  90. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  91. package/lib/module/i18n/en.json +2 -0
  92. package/lib/module/i18n/es.json +2 -0
  93. package/lib/module/i18n/fr.json +2 -0
  94. package/lib/module/i18n/he.json +2 -0
  95. package/lib/module/i18n/hi.json +2 -0
  96. package/lib/module/i18n/it.json +2 -0
  97. package/lib/module/i18n/ja.json +2 -0
  98. package/lib/module/i18n/ko.json +2 -0
  99. package/lib/module/i18n/nl.json +2 -0
  100. package/lib/module/i18n/pt-br.json +2 -0
  101. package/lib/module/i18n/ru.json +2 -0
  102. package/lib/module/i18n/tr.json +2 -0
  103. package/lib/module/icons/UnreadIndicator.js +30 -0
  104. package/lib/module/icons/UnreadIndicator.js.map +1 -0
  105. package/lib/module/icons/index.js +11 -0
  106. package/lib/module/icons/index.js.map +1 -1
  107. package/lib/module/store/SqliteClient.js +1 -1
  108. package/lib/module/store/schema.js +1 -0
  109. package/lib/module/store/schema.js.map +1 -1
  110. package/lib/module/types/types.js.map +1 -1
  111. package/lib/module/utils/utils.js +35 -1
  112. package/lib/module/utils/utils.js.map +1 -1
  113. package/lib/module/version.json +1 -1
  114. package/lib/typescript/components/Channel/Channel.d.ts +15 -3
  115. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  116. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts +1 -0
  117. package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts.map +1 -1
  118. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts +1 -1
  119. package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts.map +1 -1
  120. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +4 -2
  121. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
  122. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +4 -1
  123. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -1
  124. package/lib/typescript/components/Channel/hooks/useTargetedMessage.d.ts +2 -1
  125. package/lib/typescript/components/Channel/hooks/useTargetedMessage.d.ts.map +1 -1
  126. package/lib/typescript/components/Chat/hooks/handleEventToSyncDB.d.ts.map +1 -1
  127. package/lib/typescript/components/Message/Message.d.ts +2 -1
  128. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  129. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts +2 -1
  130. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
  131. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts +3 -2
  132. package/lib/typescript/components/Message/hooks/useMessageActions.d.ts.map +1 -1
  133. package/lib/typescript/components/Message/hooks/useMessageData.d.ts +1 -1
  134. package/lib/typescript/components/Message/utils/messageActions.d.ts +2 -1
  135. package/lib/typescript/components/Message/utils/messageActions.d.ts.map +1 -1
  136. package/lib/typescript/components/MessageList/InlineUnreadIndicator.d.ts.map +1 -1
  137. package/lib/typescript/components/MessageList/MessageList.d.ts +1 -1
  138. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  139. package/lib/typescript/components/MessageList/UnreadMessagesNotification.d.ts +13 -0
  140. package/lib/typescript/components/MessageList/UnreadMessagesNotification.d.ts.map +1 -0
  141. package/lib/typescript/components/MessageMenu/MessageActionListItem.d.ts +2 -2
  142. package/lib/typescript/components/MessageMenu/MessageActionListItem.d.ts.map +1 -1
  143. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts +25 -8
  144. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts.map +1 -1
  145. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +5 -0
  146. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  147. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +6 -0
  148. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  149. package/lib/typescript/i18n/en.json +2 -0
  150. package/lib/typescript/i18n/es.json +2 -0
  151. package/lib/typescript/i18n/fr.json +2 -0
  152. package/lib/typescript/i18n/he.json +2 -0
  153. package/lib/typescript/i18n/hi.json +2 -0
  154. package/lib/typescript/i18n/it.json +2 -0
  155. package/lib/typescript/i18n/ja.json +2 -0
  156. package/lib/typescript/i18n/ko.json +2 -0
  157. package/lib/typescript/i18n/nl.json +2 -0
  158. package/lib/typescript/i18n/pt-br.json +2 -0
  159. package/lib/typescript/i18n/ru.json +2 -0
  160. package/lib/typescript/i18n/tr.json +2 -0
  161. package/lib/typescript/icons/UnreadIndicator.d.ts +8 -0
  162. package/lib/typescript/icons/UnreadIndicator.d.ts.map +1 -0
  163. package/lib/typescript/icons/index.d.ts +1 -0
  164. package/lib/typescript/icons/index.d.ts.map +1 -1
  165. package/lib/typescript/store/mappers/mapStorableToChannel.d.ts +1 -1
  166. package/lib/typescript/store/schema.d.ts +1 -0
  167. package/lib/typescript/store/schema.d.ts.map +1 -1
  168. package/lib/typescript/types/types.d.ts +2 -1
  169. package/lib/typescript/types/types.d.ts.map +1 -1
  170. package/lib/typescript/utils/i18n/Streami18n.d.ts +2 -0
  171. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  172. package/lib/typescript/utils/utils.d.ts +21 -1
  173. package/lib/typescript/utils/utils.d.ts.map +1 -1
  174. package/package.json +1 -1
  175. package/src/components/Channel/Channel.tsx +101 -24
  176. package/src/components/Channel/__tests__/Channel.test.js +109 -58
  177. package/src/components/Channel/__tests__/ownCapabilities.test.js +26 -0
  178. package/src/components/Channel/__tests__/useMessageListPagination.test.js +234 -37
  179. package/src/components/Channel/hooks/useChannelDataState.ts +8 -0
  180. package/src/components/Channel/hooks/useCreateChannelContext.ts +11 -0
  181. package/src/components/Channel/hooks/useCreateMessagesContext.ts +4 -0
  182. package/src/components/Channel/hooks/useMessageListPagination.tsx +134 -64
  183. package/src/components/Channel/hooks/useTargetedMessage.ts +9 -2
  184. package/src/components/Chat/hooks/handleEventToSyncDB.ts +23 -1
  185. package/src/components/Message/Message.tsx +8 -0
  186. package/src/components/Message/hooks/useMessageActionHandlers.ts +54 -40
  187. package/src/components/Message/hooks/useMessageActions.tsx +31 -14
  188. package/src/components/Message/utils/messageActions.ts +6 -0
  189. package/src/components/MessageList/InlineUnreadIndicator.tsx +17 -26
  190. package/src/components/MessageList/MessageList.tsx +197 -231
  191. package/src/components/MessageList/UnreadMessagesNotification.tsx +107 -0
  192. package/src/components/MessageList/__tests__/MessageList.test.js +213 -0
  193. package/src/components/MessageMenu/MessageActionListItem.tsx +2 -1
  194. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +669 -679
  195. package/src/contexts/channelContext/ChannelContext.tsx +35 -9
  196. package/src/contexts/messagesContext/MessagesContext.tsx +7 -2
  197. package/src/contexts/themeContext/utils/theme.ts +12 -0
  198. package/src/i18n/en.json +2 -0
  199. package/src/i18n/es.json +2 -0
  200. package/src/i18n/fr.json +2 -0
  201. package/src/i18n/he.json +2 -0
  202. package/src/i18n/hi.json +2 -0
  203. package/src/i18n/it.json +2 -0
  204. package/src/i18n/ja.json +2 -0
  205. package/src/i18n/ko.json +2 -0
  206. package/src/i18n/nl.json +2 -0
  207. package/src/i18n/pt-br.json +2 -0
  208. package/src/i18n/ru.json +2 -0
  209. package/src/i18n/tr.json +2 -0
  210. package/src/icons/UnreadIndicator.tsx +18 -0
  211. package/src/icons/index.ts +1 -0
  212. package/src/store/SqliteClient.ts +1 -1
  213. package/src/store/schema.ts +2 -0
  214. package/src/types/types.ts +5 -2
  215. package/src/utils/utils.ts +61 -1
  216. package/src/version.json +1 -1
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import { Pressable, StyleSheet, Text } from 'react-native';
3
+
4
+ import { useChannelContext } from '../../contexts/channelContext/ChannelContext';
5
+ import { useTheme } from '../../contexts/themeContext/ThemeContext';
6
+ import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
7
+ import { Close } from '../../icons';
8
+
9
+ export type UnreadMessagesNotificationProps = {
10
+ /**
11
+ * Callback to handle the close event
12
+ */
13
+ onCloseHandler?: () => void;
14
+ /**
15
+ * Callback to handle the press event
16
+ */
17
+ onPressHandler?: () => Promise<void>;
18
+ };
19
+
20
+ export const UnreadMessagesNotification = (props: UnreadMessagesNotificationProps) => {
21
+ const { onCloseHandler, onPressHandler } = props;
22
+ const { t } = useTranslationContext();
23
+ const {
24
+ channelUnreadState,
25
+ loadChannelAtFirstUnreadMessage,
26
+ markRead,
27
+ setChannelUnreadState,
28
+ setTargetedMessage,
29
+ } = useChannelContext();
30
+
31
+ const handleOnPress = async () => {
32
+ if (onPressHandler) {
33
+ await onPressHandler();
34
+ } else {
35
+ await loadChannelAtFirstUnreadMessage({
36
+ channelUnreadState,
37
+ setChannelUnreadState,
38
+ setTargetedMessage,
39
+ });
40
+ }
41
+ };
42
+
43
+ const handleClose = async () => {
44
+ if (onCloseHandler) {
45
+ await onCloseHandler();
46
+ } else {
47
+ await markRead();
48
+ }
49
+ };
50
+
51
+ const {
52
+ theme: {
53
+ colors: { text_low_emphasis, white_snow },
54
+ messageList: {
55
+ unreadMessagesNotification: { closeButtonContainer, closeIcon, container, text },
56
+ },
57
+ },
58
+ } = useTheme();
59
+
60
+ return (
61
+ <Pressable
62
+ onPress={handleOnPress}
63
+ style={({ pressed }) => [
64
+ styles.container,
65
+ { backgroundColor: text_low_emphasis, opacity: pressed ? 0.8 : 1 },
66
+ container,
67
+ ]}
68
+ >
69
+ <Text style={[styles.text, { color: white_snow }, text]}>{t<string>('Unread Messages')}</Text>
70
+ <Pressable
71
+ onPress={handleClose}
72
+ style={({ pressed }) => [
73
+ {
74
+ opacity: pressed ? 0.8 : 1,
75
+ },
76
+ closeButtonContainer,
77
+ ]}
78
+ >
79
+ <Close pathFill={white_snow} {...closeIcon} />
80
+ </Pressable>
81
+ </Pressable>
82
+ );
83
+ };
84
+
85
+ const styles = StyleSheet.create({
86
+ container: {
87
+ alignItems: 'center',
88
+ borderRadius: 20,
89
+ elevation: 4,
90
+ flexDirection: 'row',
91
+ paddingHorizontal: 16,
92
+ paddingVertical: 8,
93
+ position: 'absolute',
94
+ shadowColor: '#000',
95
+ shadowOffset: {
96
+ height: 2,
97
+ width: 0,
98
+ },
99
+ shadowOpacity: 0.23,
100
+ shadowRadius: 2.62,
101
+ top: 8,
102
+ },
103
+ text: {
104
+ fontWeight: '500',
105
+ marginRight: 8,
106
+ },
107
+ });
@@ -1,5 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
+ import { FlatList } from 'react-native';
4
+
3
5
  import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react-native';
4
6
 
5
7
  import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvider';
@@ -17,6 +19,7 @@ import { Channel } from '../../Channel/Channel';
17
19
  import { channelInitialState } from '../../Channel/hooks/useChannelDataState';
18
20
  import * as MessageListPaginationHook from '../../Channel/hooks/useMessageListPagination';
19
21
  import { Chat } from '../../Chat/Chat';
22
+
20
23
  import { MessageList } from '../MessageList';
21
24
 
22
25
  describe('MessageList', () => {
@@ -382,6 +385,216 @@ describe('MessageList', () => {
382
385
  expect(() => screen.getByText(latestMessageText)).toThrow();
383
386
  });
384
387
  });
388
+
389
+ it("should render the UnreadMessagesIndicator when there's unread messages", async () => {
390
+ const user1 = generateUser();
391
+ const user2 = generateUser();
392
+ const messages = Array.from({ length: 10 }, (_, i) =>
393
+ generateMessage({ id: `${i}`, text: `message-${i}` }),
394
+ );
395
+ const mockedChannel = generateChannelResponse({
396
+ members: [generateMember({ user: user1 }), generateMember({ user: user2 })],
397
+ });
398
+
399
+ const chatClient = await getTestClientWithUser({ id: user1.id });
400
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
401
+ const channel = chatClient.channel('messaging', mockedChannel.id);
402
+ await channel.watch();
403
+
404
+ const channelUnreadState = {
405
+ last_read: new Date(),
406
+ last_read_message_id: '5',
407
+ unread_messages: 5,
408
+ };
409
+
410
+ channel.state = {
411
+ ...channelInitialState,
412
+ latestMessages: [],
413
+ messages,
414
+ };
415
+
416
+ const { queryByLabelText } = render(
417
+ <OverlayProvider>
418
+ <Chat client={chatClient}>
419
+ <Channel channel={channel}>
420
+ <MessageList channelUnreadState={channelUnreadState} />
421
+ </Channel>
422
+ </Chat>
423
+ </OverlayProvider>,
424
+ );
425
+
426
+ await waitFor(() => {
427
+ expect(queryByLabelText('Inline unread indicator')).toBeTruthy();
428
+ });
429
+ });
430
+
431
+ it("should not render the UnreadMessagesIndicator when there's no unread messages", async () => {
432
+ const user1 = generateUser();
433
+ const user2 = generateUser();
434
+ const messages = Array.from({ length: 10 }, (_, i) =>
435
+ generateMessage({ id: `${i}`, text: `message-${i}` }),
436
+ );
437
+ const mockedChannel = generateChannelResponse({
438
+ members: [generateMember({ user: user1 }), generateMember({ user: user2 })],
439
+ });
440
+
441
+ const chatClient = await getTestClientWithUser({ id: user1.id });
442
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
443
+ const channel = chatClient.channel('messaging', mockedChannel.id);
444
+ await channel.watch();
445
+
446
+ const channelUnreadState = {
447
+ last_read: new Date(),
448
+ unread_messages: 0,
449
+ };
450
+
451
+ channel.state = {
452
+ ...channelInitialState,
453
+ latestMessages: [],
454
+ messages,
455
+ };
456
+
457
+ const { queryByLabelText } = render(
458
+ <OverlayProvider>
459
+ <Chat client={chatClient}>
460
+ <Channel channel={channel}>
461
+ <MessageList channelUnreadState={channelUnreadState} />
462
+ </Channel>
463
+ </Chat>
464
+ </OverlayProvider>,
465
+ );
466
+
467
+ await waitFor(() => {
468
+ expect(queryByLabelText('Inline unread indicator')).not.toBeTruthy();
469
+ });
470
+ });
471
+
472
+ it('should call markRead function when message.new event is dispatched and new messages are received', async () => {
473
+ const user = generateUser();
474
+ const mockedChannel = generateChannelResponse({
475
+ members: [generateMember({ user })],
476
+ });
477
+
478
+ const chatClient = await getTestClientWithUser({ id: user.id });
479
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
480
+ const channel = chatClient.channel('messaging', mockedChannel.id);
481
+ await channel.watch();
482
+
483
+ const user2 = generateUser();
484
+ const newMessage = generateMessage({ user: user2 });
485
+
486
+ const markReadFn = jest.fn();
487
+
488
+ render(
489
+ <OverlayProvider>
490
+ <Chat client={chatClient}>
491
+ <Channel channel={channel}>
492
+ <MessageList markRead={markReadFn} />
493
+ </Channel>
494
+ </Chat>
495
+ </OverlayProvider>,
496
+ );
497
+
498
+ act(() => dispatchMessageNewEvent(chatClient, newMessage, mockedChannel.channel));
499
+
500
+ await waitFor(() => {
501
+ expect(markReadFn).toHaveBeenCalledTimes(1);
502
+ });
503
+ });
504
+
505
+ it("should scroll to the targeted message if it's present in the list", async () => {
506
+ const user = generateUser();
507
+ const mockedChannel = generateChannelResponse({
508
+ members: [generateMember({ user })],
509
+ });
510
+
511
+ const messages = Array.from({ length: 30 }, (_, i) =>
512
+ generateMessage({ id: `${i}`, text: `message-${i}` }),
513
+ );
514
+
515
+ const chatClient = await getTestClientWithUser({ id: user.id });
516
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
517
+ const channel = chatClient.channel('messaging', mockedChannel.id);
518
+ await channel.watch();
519
+
520
+ const targetedMessage = messages[15].id;
521
+
522
+ channel.state = {
523
+ ...channelInitialState,
524
+ latestMessages: [],
525
+ messages,
526
+ };
527
+
528
+ const flatListRefMock = jest
529
+ .spyOn(FlatList.prototype, 'scrollToIndex')
530
+ .mockImplementation(() => {});
531
+
532
+ render(
533
+ <OverlayProvider>
534
+ <Chat client={chatClient}>
535
+ <Channel channel={channel}>
536
+ <MessageList targetedMessage={targetedMessage} />
537
+ </Channel>
538
+ </Chat>
539
+ </OverlayProvider>,
540
+ );
541
+
542
+ await waitFor(() => {
543
+ expect(flatListRefMock).toHaveBeenCalledWith({
544
+ animated: true,
545
+ index: 14,
546
+ viewPosition: 0.5,
547
+ });
548
+ });
549
+ });
550
+
551
+ it("should load more messages around the message id if the targeted message isn't present in the list", async () => {
552
+ const user = generateUser();
553
+ const mockedChannel = generateChannelResponse({
554
+ members: [generateMember({ user })],
555
+ });
556
+
557
+ const messages = Array.from({ length: 20 }, (_, i) =>
558
+ generateMessage({ id: `${i}`, text: `message-${i}` }),
559
+ );
560
+
561
+ const chatClient = await getTestClientWithUser({ id: user.id });
562
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
563
+ const channel = chatClient.channel('messaging', mockedChannel.id);
564
+ await channel.watch();
565
+
566
+ const targetedMessage = 21;
567
+ const setTargetedMessage = jest.fn();
568
+
569
+ channel.state = {
570
+ ...channelInitialState,
571
+ latestMessages: [],
572
+ messages,
573
+ };
574
+
575
+ const loadChannelAroundMessage = jest.fn(() => Promise.resolve());
576
+
577
+ render(
578
+ <OverlayProvider>
579
+ <Chat client={chatClient}>
580
+ <Channel channel={channel}>
581
+ <MessageList
582
+ loadChannelAroundMessage={loadChannelAroundMessage}
583
+ setTargetedMessage={setTargetedMessage}
584
+ targetedMessage={targetedMessage}
585
+ />
586
+ </Channel>
587
+ </Chat>
588
+ </OverlayProvider>,
589
+ );
590
+
591
+ await waitFor(() => {
592
+ expect(loadChannelAroundMessage).toHaveBeenCalledWith({
593
+ messageId: targetedMessage,
594
+ setTargetedMessage,
595
+ });
596
+ });
597
+ });
385
598
  });
386
599
 
387
600
  describe('MessageList pagination', () => {
@@ -10,6 +10,7 @@ export type ActionType =
10
10
  | 'deleteMessage'
11
11
  | 'editMessage'
12
12
  | 'flagMessage'
13
+ | 'markUnread'
13
14
  | 'muteUser'
14
15
  | 'pinMessage'
15
16
  | 'selectReaction'
@@ -26,7 +27,7 @@ export type MessageActionType = {
26
27
  action: () => void;
27
28
  /**
28
29
  * Type of the action performed.
29
- * Eg: 'banUser', 'blockUser', 'copyMessage', 'deleteMessage', 'editMessage', 'flagMessage', 'muteUser', 'pinMessage', 'selectReaction', 'reply', 'retry', 'quotedReply', 'threadReply', 'unpinMessage'
30
+ * Eg: 'banUser', 'blockUser', 'copyMessage', 'deleteMessage', 'editMessage', 'flagMessage', 'markUnread , 'muteUser', 'pinMessage', 'selectReaction', 'reply', 'retry', 'quotedReply', 'threadReply', 'unpinMessage'
30
31
  */
31
32
  actionType: ActionType | string;
32
33
  /**