stream-chat-react-native-core 5.6.0-beta.0 → 5.6.0-beta.2

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 (171) hide show
  1. package/lib/commonjs/components/Attachment/Gallery.js +21 -16
  2. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  3. package/lib/commonjs/components/Attachment/GalleryImage.js +3 -3
  4. package/lib/commonjs/components/Attachment/GalleryImage.js.map +1 -1
  5. package/lib/commonjs/components/Channel/Channel.js +43 -33
  6. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  7. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +5 -1
  8. package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  9. package/lib/commonjs/components/Chat/Chat.js +1 -1
  10. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  11. package/lib/commonjs/components/Chat/hooks/useAppSettings.js +51 -22
  12. package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -1
  13. package/lib/commonjs/components/Chat/hooks/useIsOnline.js +1 -1
  14. package/lib/commonjs/components/Chat/hooks/useIsOnline.js.map +1 -1
  15. package/lib/commonjs/components/Message/hooks/useMessageActions.js +2 -2
  16. package/lib/commonjs/components/Message/hooks/useMessageActions.js.map +1 -1
  17. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +18 -21
  18. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  19. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js +7 -32
  20. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js.map +1 -1
  21. package/lib/commonjs/components/index.js +1 -1
  22. package/lib/commonjs/components/index.js.map +1 -1
  23. package/lib/commonjs/contexts/chatContext/ChatContext.js.map +1 -1
  24. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +128 -89
  25. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  26. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js +1 -0
  27. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  28. package/lib/commonjs/store/QuickSqliteClient.js +46 -1
  29. package/lib/commonjs/store/QuickSqliteClient.js.map +1 -1
  30. package/lib/commonjs/store/QuickSqliteClient_v4.js +112 -0
  31. package/lib/commonjs/store/QuickSqliteClient_v4.js.map +1 -0
  32. package/lib/commonjs/store/apis/getAppSettings.js +23 -0
  33. package/lib/commonjs/store/apis/getAppSettings.js.map +1 -0
  34. package/lib/commonjs/store/apis/getPendingTasks.js.map +1 -1
  35. package/lib/commonjs/store/apis/index.js +26 -0
  36. package/lib/commonjs/store/apis/index.js.map +1 -1
  37. package/lib/commonjs/store/apis/queries/selectChannels.js.map +1 -1
  38. package/lib/commonjs/store/apis/queries/selectMembersForChannels.js.map +1 -1
  39. package/lib/commonjs/store/apis/queries/selectMessagesForChannels.js.map +1 -1
  40. package/lib/commonjs/store/apis/queries/selectReactionsForMessages.js.map +1 -1
  41. package/lib/commonjs/store/apis/queries/selectReadsForChannels.js.map +1 -1
  42. package/lib/commonjs/store/apis/upsertAppSettings.js +26 -0
  43. package/lib/commonjs/store/apis/upsertAppSettings.js.map +1 -0
  44. package/lib/commonjs/store/schema.js +1 -0
  45. package/lib/commonjs/store/schema.js.map +1 -1
  46. package/lib/commonjs/utils/DBSyncManager.js +16 -16
  47. package/lib/commonjs/utils/DBSyncManager.js.map +1 -1
  48. package/lib/commonjs/{components/Message/utils → utils}/removeReservedFields.js +1 -1
  49. package/lib/commonjs/utils/removeReservedFields.js.map +1 -0
  50. package/lib/commonjs/utils/utils.js +2 -2
  51. package/lib/commonjs/utils/utils.js.map +1 -1
  52. package/lib/commonjs/version.json +1 -1
  53. package/lib/module/components/Attachment/Gallery.js +21 -16
  54. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  55. package/lib/module/components/Attachment/GalleryImage.js +3 -3
  56. package/lib/module/components/Attachment/GalleryImage.js.map +1 -1
  57. package/lib/module/components/Channel/Channel.js +43 -33
  58. package/lib/module/components/Channel/Channel.js.map +1 -1
  59. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +5 -1
  60. package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
  61. package/lib/module/components/Chat/Chat.js +1 -1
  62. package/lib/module/components/Chat/Chat.js.map +1 -1
  63. package/lib/module/components/Chat/hooks/useAppSettings.js +51 -22
  64. package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -1
  65. package/lib/module/components/Chat/hooks/useIsOnline.js +1 -1
  66. package/lib/module/components/Chat/hooks/useIsOnline.js.map +1 -1
  67. package/lib/module/components/Message/hooks/useMessageActions.js +2 -2
  68. package/lib/module/components/Message/hooks/useMessageActions.js.map +1 -1
  69. package/lib/module/components/MessageInput/FileUploadPreview.js +18 -21
  70. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  71. package/lib/module/components/MessageInput/ImageUploadPreview.js +7 -32
  72. package/lib/module/components/MessageInput/ImageUploadPreview.js.map +1 -1
  73. package/lib/module/components/index.js +1 -1
  74. package/lib/module/components/index.js.map +1 -1
  75. package/lib/module/contexts/chatContext/ChatContext.js.map +1 -1
  76. package/lib/module/contexts/messageInputContext/MessageInputContext.js +128 -89
  77. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  78. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js +1 -0
  79. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  80. package/lib/module/store/QuickSqliteClient.js +46 -1
  81. package/lib/module/store/QuickSqliteClient.js.map +1 -1
  82. package/lib/module/store/QuickSqliteClient_v4.js +112 -0
  83. package/lib/module/store/QuickSqliteClient_v4.js.map +1 -0
  84. package/lib/module/store/apis/getAppSettings.js +23 -0
  85. package/lib/module/store/apis/getAppSettings.js.map +1 -0
  86. package/lib/module/store/apis/getPendingTasks.js.map +1 -1
  87. package/lib/module/store/apis/index.js +26 -0
  88. package/lib/module/store/apis/index.js.map +1 -1
  89. package/lib/module/store/apis/queries/selectChannels.js.map +1 -1
  90. package/lib/module/store/apis/queries/selectMembersForChannels.js.map +1 -1
  91. package/lib/module/store/apis/queries/selectMessagesForChannels.js.map +1 -1
  92. package/lib/module/store/apis/queries/selectReactionsForMessages.js.map +1 -1
  93. package/lib/module/store/apis/queries/selectReadsForChannels.js.map +1 -1
  94. package/lib/module/store/apis/upsertAppSettings.js +26 -0
  95. package/lib/module/store/apis/upsertAppSettings.js.map +1 -0
  96. package/lib/module/store/schema.js +1 -0
  97. package/lib/module/store/schema.js.map +1 -1
  98. package/lib/module/utils/DBSyncManager.js +16 -16
  99. package/lib/module/utils/DBSyncManager.js.map +1 -1
  100. package/lib/module/{components/Message/utils → utils}/removeReservedFields.js +1 -1
  101. package/lib/module/utils/removeReservedFields.js.map +1 -0
  102. package/lib/module/utils/utils.js +2 -2
  103. package/lib/module/utils/utils.js.map +1 -1
  104. package/lib/module/version.json +1 -1
  105. package/lib/typescript/components/Chat/hooks/useAppSettings.d.ts +2 -2
  106. package/lib/typescript/components/Chat/hooks/useIsOnline.d.ts +1 -1
  107. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts +1 -1
  108. package/lib/typescript/components/MessageInput/ImageUploadPreview.d.ts +1 -1
  109. package/lib/typescript/components/index.d.ts +1 -1
  110. package/lib/typescript/contexts/chatContext/ChatContext.d.ts +1 -1
  111. package/lib/typescript/store/QuickSqliteClient.d.ts +4 -1
  112. package/lib/typescript/store/QuickSqliteClient_v4.d.ts +12 -0
  113. package/lib/typescript/store/apis/getAppSettings.d.ts +4 -0
  114. package/lib/typescript/store/apis/getPendingTasks.d.ts +1 -1
  115. package/lib/typescript/store/apis/index.d.ts +2 -0
  116. package/lib/typescript/store/apis/upsertAppSettings.d.ts +6 -0
  117. package/lib/typescript/store/mappers/mapTaskToStorable.d.ts +0 -8
  118. package/lib/typescript/store/schema.d.ts +1 -0
  119. package/lib/typescript/store/types.d.ts +0 -4
  120. package/lib/typescript/utils/DBSyncManager.d.ts +1 -1
  121. package/lib/typescript/{components/Message/utils → utils}/removeReservedFields.d.ts +2 -2
  122. package/lib/typescript/utils/utils.d.ts +1 -1
  123. package/package.json +1 -1
  124. package/src/components/Attachment/Gallery.tsx +5 -1
  125. package/src/components/Attachment/GalleryImage.tsx +2 -0
  126. package/src/components/Attachment/__tests__/Gallery.test.js +9 -2
  127. package/src/components/Attachment/__tests__/Giphy.test.js +9 -5
  128. package/src/components/Channel/Channel.tsx +20 -12
  129. package/src/components/ChannelList/hooks/usePaginatedChannels.ts +6 -4
  130. package/src/components/Chat/Chat.tsx +1 -1
  131. package/src/components/Chat/hooks/__tests__/useAppSettings.test.tsx +1 -0
  132. package/src/components/Chat/hooks/useAppSettings.ts +19 -6
  133. package/src/components/Chat/hooks/useIsOnline.ts +1 -1
  134. package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +29 -15
  135. package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +12 -6
  136. package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +9 -4
  137. package/src/components/Message/hooks/useMessageActions.tsx +1 -1
  138. package/src/components/MessageInput/FileUploadPreview.tsx +4 -5
  139. package/src/components/MessageInput/ImageUploadPreview.tsx +10 -35
  140. package/src/components/index.ts +1 -1
  141. package/src/contexts/chatContext/ChatContext.tsx +1 -1
  142. package/src/contexts/messageInputContext/MessageInputContext.tsx +94 -75
  143. package/src/contexts/messageInputContext/__tests__/MessageInputContext.test.tsx +8 -3
  144. package/src/contexts/messageInputContext/__tests__/__snapshots__/sendMessage.test.tsx.snap +0 -3
  145. package/src/contexts/messageInputContext/__tests__/uploadFile.test.tsx +16 -6
  146. package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +1 -0
  147. package/src/store/QuickSqliteClient.ts +49 -5
  148. package/src/store/QuickSqliteClient_v4.ts +98 -0
  149. package/src/store/apis/getAppSettings.ts +19 -0
  150. package/src/store/apis/getPendingTasks.ts +2 -1
  151. package/src/store/apis/index.ts +2 -0
  152. package/src/store/apis/queries/selectChannels.ts +4 -1
  153. package/src/store/apis/queries/selectMembersForChannels.ts +1 -1
  154. package/src/store/apis/queries/selectMessagesForChannels.ts +1 -1
  155. package/src/store/apis/queries/selectReactionsForMessages.ts +1 -1
  156. package/src/store/apis/queries/selectReadsForChannels.ts +1 -1
  157. package/src/store/apis/upsertAppSettings.ts +23 -0
  158. package/src/store/schema.ts +2 -0
  159. package/src/store/types.ts +0 -5
  160. package/src/utils/DBSyncManager.ts +1 -1
  161. package/src/{components/Message/utils → utils}/removeReservedFields.ts +7 -3
  162. package/src/utils/utils.ts +7 -6
  163. package/src/version.json +1 -1
  164. package/lib/commonjs/components/Message/utils/removeReservedFields.js.map +0 -1
  165. package/lib/commonjs/utils/pendingTaskUtils.js +0 -302
  166. package/lib/commonjs/utils/pendingTaskUtils.js.map +0 -1
  167. package/lib/module/components/Message/utils/removeReservedFields.js.map +0 -1
  168. package/lib/module/utils/pendingTaskUtils.js +0 -302
  169. package/lib/module/utils/pendingTaskUtils.js.map +0 -1
  170. package/lib/typescript/utils/pendingTaskUtils.d.ts +0 -13
  171. package/src/utils/pendingTaskUtils.ts +0 -131
@@ -79,7 +79,6 @@ import * as dbApi from '../../store/apis';
79
79
  import type { DefaultStreamChatGenerics } from '../../types/types';
80
80
  import { addReactionToLocalState } from '../../utils/addReactionToLocalState';
81
81
  import { DBSyncManager } from '../../utils/DBSyncManager';
82
- import { dropPendingTasks, queueTask } from '../../utils/pendingTaskUtils';
83
82
  import { removeReactionFromLocalState } from '../../utils/removeReactionFromLocalState';
84
83
  import { generateRandomId, isLocalUrl, MessageStatusTypes, ReactionData } from '../../utils/utils';
85
84
  import { Attachment as AttachmentDefault } from '../Attachment/Attachment';
@@ -182,7 +181,7 @@ const throttleOptions = {
182
181
  trailing: true,
183
182
  };
184
183
  const debounceOptions = {
185
- leading: false,
184
+ leading: true,
186
185
  trailing: true,
187
186
  };
188
187
 
@@ -682,14 +681,14 @@ const ChannelWithContext = <
682
681
  ).current;
683
682
 
684
683
  const copyMessagesState = useRef(
685
- debounce(
684
+ throttle(
686
685
  () => {
687
686
  if (channel) {
688
687
  setMessages([...channel.state.messages]);
689
688
  }
690
689
  },
691
690
  newMessageStateUpdateThrottleInterval,
692
- debounceOptions,
691
+ throttleOptions,
693
692
  ),
694
693
  ).current;
695
694
 
@@ -718,7 +717,7 @@ const ChannelWithContext = <
718
717
  ).current;
719
718
 
720
719
  const copyChannelState = useRef(
721
- debounce(
720
+ throttle(
722
721
  () => {
723
722
  setLoading(false);
724
723
  if (channel) {
@@ -731,7 +730,7 @@ const ChannelWithContext = <
731
730
  }
732
731
  },
733
732
  stateUpdateThrottleInterval,
734
- debounceOptions,
733
+ throttleOptions,
735
734
  ),
736
735
  ).current;
737
736
 
@@ -1193,6 +1192,13 @@ const ChannelWithContext = <
1193
1192
  text,
1194
1193
  ...extraFields
1195
1194
  }: Partial<StreamMessage<StreamChatGenerics>>) => {
1195
+ // Exclude following properties from message.user within message preview,
1196
+ // since they could be long arrays and have no meaning as sender of message.
1197
+ // Storing such large value within user's table may cause sqlite queries to crash.
1198
+ // @ts-ignore
1199
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1200
+ const { channel_mutes, devices, mutes, ...messageUser } = client.user;
1201
+
1196
1202
  const preview = {
1197
1203
  __html: text,
1198
1204
  attachments,
@@ -1210,7 +1216,7 @@ const ChannelWithContext = <
1210
1216
  type: 'regular',
1211
1217
  user: {
1212
1218
  id: client.userID,
1213
- ...client.user,
1219
+ ...messageUser,
1214
1220
  },
1215
1221
  ...extraFields,
1216
1222
  } as unknown as MessageResponse<StreamChatGenerics>;
@@ -1233,7 +1239,6 @@ const ChannelWithContext = <
1233
1239
  const updatedMessage = { ...message };
1234
1240
  if (updatedMessage.attachments?.length) {
1235
1241
  for (let i = 0; i < updatedMessage.attachments?.length; i++) {
1236
- // TODO: abstract the following logic to a separate function for DRY within MessageInputContext
1237
1242
  const attachment = updatedMessage.attachments[i];
1238
1243
  const file = attachment.originalFile;
1239
1244
  // check if image_url is not a remote url
@@ -1270,6 +1275,9 @@ const ChannelWithContext = <
1270
1275
  ? await doDocUploadRequest(file, channel)
1271
1276
  : await channel.sendFile(file.uri, file.name, file.type);
1272
1277
  attachment.asset_url = response.file;
1278
+ if (response.thumb_url) {
1279
+ attachment.thumb_url = response.thumb_url;
1280
+ }
1273
1281
  delete attachment.originalFile;
1274
1282
  dbApi.updateMessage({
1275
1283
  message: { ...updatedMessage, cid: channel.cid },
@@ -1588,7 +1596,7 @@ const ChannelWithContext = <
1588
1596
 
1589
1597
  setMessages(channel.state.messages);
1590
1598
 
1591
- await queueTask<StreamChatGenerics>({
1599
+ await DBSyncManager.queueTask<StreamChatGenerics>({
1592
1600
  client,
1593
1601
  task: {
1594
1602
  channelId: channel.id,
@@ -1612,7 +1620,7 @@ const ChannelWithContext = <
1612
1620
  }
1613
1621
 
1614
1622
  if (message.status === MessageStatusTypes.FAILED) {
1615
- dropPendingTasks({ messageId: message.id });
1623
+ DBSyncManager.dropPendingTasks({ messageId: message.id });
1616
1624
  removeMessage(message);
1617
1625
  } else {
1618
1626
  updateMessage({
@@ -1622,7 +1630,7 @@ const ChannelWithContext = <
1622
1630
  type: 'deleted',
1623
1631
  });
1624
1632
 
1625
- const data = await queueTask<StreamChatGenerics>({
1633
+ const data = await DBSyncManager.queueTask<StreamChatGenerics>({
1626
1634
  client,
1627
1635
  task: {
1628
1636
  channelId: channel.id,
@@ -1663,7 +1671,7 @@ const ChannelWithContext = <
1663
1671
 
1664
1672
  setMessages(channel.state.messages);
1665
1673
 
1666
- await queueTask({
1674
+ await DBSyncManager.queueTask<StreamChatGenerics>({
1667
1675
  client,
1668
1676
  task: {
1669
1677
  channelId: channel.id,
@@ -2,6 +2,8 @@ import { useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import type { Channel, ChannelFilters, ChannelOptions, ChannelSort } from 'stream-chat';
4
4
 
5
+ import { useActiveChannelsRefContext } from '../../../contexts/activeChannelsRefContext/ActiveChannelsRefContext';
6
+
5
7
  import { useChatContext } from '../../../contexts/chatContext/ChatContext';
6
8
  import { useIsMountedRef } from '../../../hooks/useIsMountedRef';
7
9
 
@@ -48,7 +50,7 @@ export const usePaginatedChannels = <
48
50
  const { client } = useChatContext<StreamChatGenerics>();
49
51
  const [channels, setChannels] = useState<Channel<StreamChatGenerics>[] | null>(null);
50
52
  const [staticChannelsActive, setStaticChannelsActive] = useState<boolean>(false);
51
-
53
+ const activeChannels = useActiveChannelsRefContext();
52
54
  const [error, setError] = useState<Error>();
53
55
  const [hasNextPage, setHasNextPage] = useState(true);
54
56
  const lastRefresh = useRef(Date.now());
@@ -99,17 +101,17 @@ export const usePaginatedChannels = <
99
101
  };
100
102
 
101
103
  try {
102
- const activeChannelIds = [];
104
+ const activeChannelIds: string[] = [];
103
105
  for (const cid in client.activeChannels) {
104
106
  if (client.activeChannels[cid].id) {
107
+ // @ts-ignore
105
108
  activeChannelIds.push(client.activeChannels[cid].id);
106
109
  }
107
110
  }
108
111
 
109
112
  // TODO: Think about the implications of this.
110
113
  const channelQueryResponse = await client.queryChannels(filters, sort, newOptions, {
111
- // @ts-ignore
112
- skipInitialization: activeChannelIds,
114
+ skipInitialization: enableOfflineSupport ? activeChannelIds : activeChannels.current,
113
115
  });
114
116
  if (isQueryStale() || !isMountedRef.current) {
115
117
  return;
@@ -196,7 +196,7 @@ const ChatWithContext = <
196
196
 
197
197
  const setActiveChannel = (newChannel?: Channel<StreamChatGenerics>) => setChannel(newChannel);
198
198
 
199
- const appSettings = useAppSettings(client, isOnline);
199
+ const appSettings = useAppSettings(client, isOnline, enableOfflineSupport);
200
200
 
201
201
  const chatContext = useCreateChatContext({
202
202
  appSettings,
@@ -21,6 +21,7 @@ describe('useAppSettings', () => {
21
21
  userID: 'some-user-id',
22
22
  } as unknown as StreamChat,
23
23
  isOnline,
24
+ false,
24
25
  );
25
26
 
26
27
  return <Text>{JSON.stringify(appSettings)}</Text>;
@@ -1,23 +1,38 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
2
 
3
3
  import type { AppSettingsAPIResponse, StreamChat } from 'stream-chat';
4
- import type { DefaultStreamChatGenerics } from 'stream-chat-react-native';
5
4
 
5
+ import * as dbApi from '../../../store/apis';
6
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
6
7
  export const useAppSettings = <
7
8
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
8
9
  >(
9
10
  client: StreamChat<StreamChatGenerics>,
10
- isOnline: boolean,
11
+ isOnline: boolean | null,
12
+ enableOfflineSupport: boolean,
11
13
  ): AppSettingsAPIResponse | null => {
12
14
  const [appSettings, setAppSettings] = useState<AppSettingsAPIResponse | null>(null);
13
15
  const isMounted = useRef(true);
14
16
 
15
17
  useEffect(() => {
16
- async function getAppSettings() {
18
+ async function enforeAppSettings() {
19
+ if (!client.userID) return;
20
+
21
+ if (!isOnline && enableOfflineSupport) {
22
+ const appSettings = dbApi.getAppSettings({ currentUserId: client.userID });
23
+ setAppSettings(appSettings);
24
+ return;
25
+ }
26
+
17
27
  try {
18
28
  const appSettings = await client.getAppSettings();
19
29
  if (isMounted.current) {
20
30
  setAppSettings(appSettings);
31
+ enableOfflineSupport &&
32
+ dbApi.upsertAppSettings({
33
+ appSettings,
34
+ currentUserId: client.userID as string,
35
+ });
21
36
  }
22
37
  } catch (error: unknown) {
23
38
  if (error instanceof Error) {
@@ -26,9 +41,7 @@ export const useAppSettings = <
26
41
  }
27
42
  }
28
43
 
29
- if (isOnline && client.userID) {
30
- getAppSettings();
31
- }
44
+ enforeAppSettings();
32
45
 
33
46
  return () => {
34
47
  isMounted.current = false;
@@ -22,7 +22,7 @@ export const useIsOnline = <
22
22
  client: StreamChat<StreamChatGenerics>,
23
23
  closeConnectionOnBackground = true,
24
24
  ) => {
25
- const [isOnline, setIsOnline] = useState(true);
25
+ const [isOnline, setIsOnline] = useState<boolean | null>(null);
26
26
  const [connectionRecovering, setConnectionRecovering] = useState(false);
27
27
  const isMounted = useIsMountedRef();
28
28
  const clientExists = !!client;
@@ -4,7 +4,7 @@ import type { SharedValue } from 'react-native-reanimated';
4
4
 
5
5
  import { act } from 'react-test-renderer';
6
6
 
7
- import { fireEvent, render } from '@testing-library/react-native';
7
+ import { fireEvent, render, waitFor } from '@testing-library/react-native';
8
8
 
9
9
  import {
10
10
  ImageGalleryContext,
@@ -45,7 +45,7 @@ const getComponent = (props: Partial<ImageGalleryContextValue>) => (
45
45
  );
46
46
 
47
47
  describe('ImageGallery', () => {
48
- it('render image gallery component', () => {
48
+ it('render image gallery component', async () => {
49
49
  const { queryAllByA11yLabel } = render(
50
50
  getComponent({
51
51
  messages: [
@@ -59,11 +59,14 @@ describe('ImageGallery', () => {
59
59
  ] as unknown as MessageType<DefaultStreamChatGenerics>[],
60
60
  }),
61
61
  );
62
- expect(queryAllByA11yLabel('Image Item')).toHaveLength(2);
63
- expect(queryAllByA11yLabel('Image Gallery Video')).toHaveLength(1);
62
+
63
+ await waitFor(() => {
64
+ expect(queryAllByA11yLabel('Image Item')).toHaveLength(2);
65
+ expect(queryAllByA11yLabel('Image Gallery Video')).toHaveLength(1);
66
+ });
64
67
  });
65
68
 
66
- it('handle handleLoad function when video item present and payload duration is available', () => {
69
+ it('handle handleLoad function when video item present and payload duration is available', async () => {
67
70
  const attachment = generateVideoAttachment({ type: 'video' });
68
71
  const message = generateMessage({
69
72
  attachments: [attachment],
@@ -86,10 +89,13 @@ describe('ImageGallery', () => {
86
89
  });
87
90
 
88
91
  const videoDurationComponent = getByA11yLabel('Video Duration');
89
- expect(videoDurationComponent.children[0]).toBe('00:10');
92
+
93
+ await waitFor(() => {
94
+ expect(videoDurationComponent.children[0]).toBe('00:10');
95
+ });
90
96
  });
91
97
 
92
- it('handle handleLoad function when video item present and payload duration is undefined', () => {
98
+ it('handle handleLoad function when video item present and payload duration is undefined', async () => {
93
99
  const { getByA11yLabel } = render(
94
100
  getComponent({
95
101
  messages: [
@@ -109,10 +115,12 @@ describe('ImageGallery', () => {
109
115
  });
110
116
 
111
117
  const videoDurationComponent = getByA11yLabel('Video Duration');
112
- expect(videoDurationComponent.children[0]).toBe('00:00');
118
+ await waitFor(() => {
119
+ expect(videoDurationComponent.children[0]).toBe('00:00');
120
+ });
113
121
  });
114
122
 
115
- it('handle handleProgress function when video item present and payload is well defined', () => {
123
+ it('handle handleProgress function when video item present and payload is well defined', async () => {
116
124
  const attachment = generateVideoAttachment({ type: 'video' });
117
125
  const message = generateMessage({
118
126
  attachments: [attachment],
@@ -143,10 +151,12 @@ describe('ImageGallery', () => {
143
151
 
144
152
  const progressDurationComponent = getByA11yLabel('Progress Duration');
145
153
 
146
- expect(progressDurationComponent.children[0]).toBe('00:03');
154
+ await waitFor(() => {
155
+ expect(progressDurationComponent.children[0]).toBe('00:03');
156
+ });
147
157
  });
148
158
 
149
- it('handle handleProgress function when video item present and payload is not defined', () => {
159
+ it('handle handleProgress function when video item present and payload is not defined', async () => {
150
160
  const { getByA11yLabel } = render(
151
161
  getComponent({
152
162
  messages: [
@@ -171,10 +181,12 @@ describe('ImageGallery', () => {
171
181
 
172
182
  const progressDurationComponent = getByA11yLabel('Progress Duration');
173
183
 
174
- expect(progressDurationComponent.children[0]).toBe('00:00');
184
+ await waitFor(() => {
185
+ expect(progressDurationComponent.children[0]).toBe('00:00');
186
+ });
175
187
  });
176
188
 
177
- it('handle handleEnd function when video item present', () => {
189
+ it('handle handleEnd function when video item present', async () => {
178
190
  const attachment = generateVideoAttachment({ type: 'video' });
179
191
  const message = generateMessage({
180
192
  attachments: [attachment],
@@ -198,7 +210,9 @@ describe('ImageGallery', () => {
198
210
  });
199
211
 
200
212
  const progressDurationComponent = getByA11yLabel('Progress Duration');
201
- expect(getByA11yLabel('Play Icon')).not.toBeUndefined();
202
- expect(progressDurationComponent.children[0]).toBe('00:10');
213
+ await waitFor(() => {
214
+ expect(getByA11yLabel('Play Icon')).not.toBeUndefined();
215
+ expect(progressDurationComponent.children[0]).toBe('00:10');
216
+ });
203
217
  });
204
218
  });
@@ -97,10 +97,13 @@ describe('ImageGalleryFooter', () => {
97
97
  </ImageGalleryContext.Provider>
98
98
  </OverlayProvider>,
99
99
  );
100
- expect(queryAllByText('Left element')).toHaveLength(1);
101
- expect(queryAllByText('Right element')).toHaveLength(1);
102
- expect(queryAllByText('Center element')).toHaveLength(1);
103
- expect(queryAllByText('Video Control element')).toHaveLength(1);
100
+
101
+ await waitFor(() => {
102
+ expect(queryAllByText('Left element')).toHaveLength(1);
103
+ expect(queryAllByText('Right element')).toHaveLength(1);
104
+ expect(queryAllByText('Center element')).toHaveLength(1);
105
+ expect(queryAllByText('Video Control element')).toHaveLength(1);
106
+ });
104
107
  });
105
108
 
106
109
  it('render image gallery footer component with custom component footer Grid Icon and Share Icon component', async () => {
@@ -147,8 +150,11 @@ describe('ImageGalleryFooter', () => {
147
150
  </ImageGalleryContext.Provider>
148
151
  </OverlayProvider>,
149
152
  );
150
- expect(queryAllByText('Share Icon element')).toHaveLength(1);
151
- expect(queryAllByText('Grid Icon element')).toHaveLength(1);
153
+
154
+ await waitFor(() => {
155
+ expect(queryAllByText('Share Icon element')).toHaveLength(1);
156
+ expect(queryAllByText('Grid Icon element')).toHaveLength(1);
157
+ });
152
158
  });
153
159
 
154
160
  it('should trigger the share button onPress Handler', async () => {
@@ -90,9 +90,12 @@ describe('ImageGalleryHeader', () => {
90
90
  </ImageGalleryContext.Provider>
91
91
  </OverlayProvider>,
92
92
  );
93
- expect(queryAllByText('Left element')).toHaveLength(1);
94
- expect(queryAllByText('Right element')).toHaveLength(1);
95
- expect(queryAllByText('Center element')).toHaveLength(1);
93
+
94
+ await waitFor(() => {
95
+ expect(queryAllByText('Left element')).toHaveLength(1);
96
+ expect(queryAllByText('Right element')).toHaveLength(1);
97
+ expect(queryAllByText('Center element')).toHaveLength(1);
98
+ });
96
99
  });
97
100
 
98
101
  it('render image gallery header component with custom Close Icon component', async () => {
@@ -132,7 +135,9 @@ describe('ImageGalleryHeader', () => {
132
135
  </ImageGalleryContext.Provider>
133
136
  </OverlayProvider>,
134
137
  );
135
- expect(queryAllByText('Close Icon element')).toHaveLength(1);
138
+ await waitFor(() => {
139
+ expect(queryAllByText('Close Icon element')).toHaveLength(1);
140
+ });
136
141
  });
137
142
 
138
143
  it('should trigger the hideOverlay function on button onPress', async () => {
@@ -26,11 +26,11 @@ import {
26
26
  } from '../../../icons';
27
27
  import { setClipboardString } from '../../../native';
28
28
  import type { DefaultStreamChatGenerics } from '../../../types/types';
29
+ import { removeReservedFields } from '../../../utils/removeReservedFields';
29
30
  import { MessageStatusTypes } from '../../../utils/utils';
30
31
 
31
32
  import type { MessageType } from '../../MessageList/hooks/useMessageList';
32
33
  import type { MessageActionType } from '../../MessageOverlay/MessageActionListItem';
33
- import { removeReservedFields } from '../utils/removeReservedFields';
34
34
 
35
35
  export const useMessageActions = <
36
36
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -128,7 +128,7 @@ type FileUploadPreviewPropsWithContext<
128
128
  'fileUploads' | 'removeFile' | 'uploadFile' | 'setFileUploads'
129
129
  > &
130
130
  Pick<MessagesContextValue<StreamChatGenerics>, 'AudioAttachment' | 'FileAttachmentIcon'> &
131
- Pick<ChatContextValue<StreamChatGenerics>, 'isOnline' | 'enableOfflineSupport'>;
131
+ Pick<ChatContextValue<StreamChatGenerics>, 'enableOfflineSupport'>;
132
132
 
133
133
  const FileUploadPreviewWithContext = <
134
134
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -140,7 +140,6 @@ const FileUploadPreviewWithContext = <
140
140
  enableOfflineSupport,
141
141
  FileAttachmentIcon,
142
142
  fileUploads,
143
- isOnline,
144
143
  removeFile,
145
144
  setFileUploads,
146
145
  uploadFile,
@@ -215,7 +214,7 @@ const FileUploadPreviewWithContext = <
215
214
  } = useTheme();
216
215
 
217
216
  const renderItem = ({ index, item }: { index: number; item: FileUpload }) => {
218
- const indicatorType = getIndicatorTypeForFileState(item.state, isOnline, enableOfflineSupport);
217
+ const indicatorType = getIndicatorTypeForFileState(item.state, enableOfflineSupport);
219
218
 
220
219
  const lastIndexOfDot = item.file.name.lastIndexOf('.');
221
220
 
@@ -393,7 +392,7 @@ export const FileUploadPreview = <
393
392
  >(
394
393
  props: FileUploadPreviewProps<StreamChatGenerics>,
395
394
  ) => {
396
- const { enableOfflineSupport, isOnline } = useChatContext<StreamChatGenerics>();
395
+ const { enableOfflineSupport } = useChatContext<StreamChatGenerics>();
397
396
  const { fileUploads, removeFile, setFileUploads, uploadFile } =
398
397
  useMessageInputContext<StreamChatGenerics>();
399
398
  const { AudioAttachment, FileAttachmentIcon } = useMessagesContext<StreamChatGenerics>();
@@ -408,7 +407,7 @@ export const FileUploadPreview = <
408
407
  setFileUploads,
409
408
  uploadFile,
410
409
  }}
411
- {...{ enableOfflineSupport, isOnline }}
410
+ {...{ enableOfflineSupport }}
412
411
  {...props}
413
412
  />
414
413
  );
@@ -80,7 +80,7 @@ type ImageUploadPreviewPropsWithContext<
80
80
  MessageInputContextValue<StreamChatGenerics>,
81
81
  'imageUploads' | 'removeImage' | 'uploadImage'
82
82
  > &
83
- Pick<ChatContextValue<StreamChatGenerics>, 'isOnline' | 'enableOfflineSupport'>;
83
+ Pick<ChatContextValue<StreamChatGenerics>, 'enableOfflineSupport'>;
84
84
 
85
85
  export type ImageUploadPreviewProps<
86
86
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -93,7 +93,7 @@ const ImageUploadPreviewWithContext = <
93
93
  >(
94
94
  props: ImageUploadPreviewPropsWithContext<StreamChatGenerics>,
95
95
  ) => {
96
- const { enableOfflineSupport, imageUploads, isOnline, removeImage, uploadImage } = props;
96
+ const { enableOfflineSupport, imageUploads, removeImage, uploadImage } = props;
97
97
 
98
98
  const {
99
99
  theme: {
@@ -131,7 +131,7 @@ const ImageUploadPreviewWithContext = <
131
131
  };
132
132
 
133
133
  const renderItem = ({ index, item }: ImageUploadPreviewItem) => {
134
- const indicatorType = getIndicatorTypeForFileState(item.state, isOnline, enableOfflineSupport);
134
+ const indicatorType = getIndicatorTypeForFileState(item.state, enableOfflineSupport);
135
135
  const itemMarginForIndex = index === imageUploads.length - 1 ? { marginRight: 8 } : {};
136
136
 
137
137
  return (
@@ -202,40 +202,15 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
202
202
  prevProps: ImageUploadPreviewPropsWithContext<StreamChatGenerics>,
203
203
  nextProps: ImageUploadPreviewPropsWithContext<StreamChatGenerics>,
204
204
  ) => {
205
- const {
206
- enableOfflineSupport: prevEnableOfflineSupport,
207
- imageUploads: prevImageUploads,
208
- isOnline: prevIsOnline,
209
- } = prevProps;
210
- const {
211
- enableOfflineSupport: nextEnableOfflineSupport,
212
- imageUploads: nextImageUploads,
213
- isOnline: nextIsOnline,
214
- } = nextProps;
215
-
216
- const isOnlineEqual = prevIsOnline === nextIsOnline;
217
-
218
- if (!isOnlineEqual) {
219
- return false;
220
- }
221
-
222
- const enableOfflineSupportEqual = prevEnableOfflineSupport === nextEnableOfflineSupport;
223
-
224
- if (!enableOfflineSupportEqual) {
225
- return false;
226
- }
205
+ const { imageUploads: prevImageUploads } = prevProps;
206
+ const { imageUploads: nextImageUploads } = nextProps;
227
207
 
228
- const imageUploadsEqual =
208
+ return (
229
209
  prevImageUploads.length === nextImageUploads.length &&
230
210
  prevImageUploads.every(
231
211
  (prevImageUpload, index) => prevImageUpload.state === nextImageUploads[index].state,
232
- );
233
-
234
- if (!imageUploadsEqual) {
235
- return false;
236
- }
237
-
238
- return true;
212
+ )
213
+ );
239
214
  };
240
215
 
241
216
  const MemoizedImageUploadPreviewWithContext = React.memo(
@@ -251,13 +226,13 @@ export const ImageUploadPreview = <
251
226
  >(
252
227
  props: ImageUploadPreviewProps<StreamChatGenerics>,
253
228
  ) => {
254
- const { enableOfflineSupport, isOnline } = useChatContext<StreamChatGenerics>();
229
+ const { enableOfflineSupport } = useChatContext<StreamChatGenerics>();
255
230
  const { imageUploads, removeImage, uploadImage } = useMessageInputContext<StreamChatGenerics>();
256
231
 
257
232
  return (
258
233
  <MemoizedImageUploadPreviewWithContext
259
234
  {...{ imageUploads, removeImage, uploadImage }}
260
- {...{ enableOfflineSupport, isOnline }}
235
+ {...{ enableOfflineSupport }}
261
236
  {...props}
262
237
  />
263
238
  );
@@ -108,7 +108,7 @@ export * from './Message/MessageSimple/MessageTextContainer';
108
108
  export * from './Message/MessageSimple/ReactionList';
109
109
  export * from './Message/MessageSimple/utils/renderText';
110
110
  export * from './Message/utils/messageActions';
111
- export * from './Message/utils/removeReservedFields';
111
+ export * from '../utils/removeReservedFields';
112
112
 
113
113
  export * from './MessageInput/AttachButton';
114
114
  export * from './MessageInput/CommandsButton';
@@ -36,7 +36,7 @@ export type ChatContextValue<
36
36
  connectionRecovering: boolean;
37
37
  enableOfflineSupport: boolean;
38
38
  ImageComponent: React.ComponentType<ImageProps>;
39
- isOnline: boolean;
39
+ isOnline: boolean | null;
40
40
  mutedUsers: Mute<StreamChatGenerics>[];
41
41
  /**
42
42
  * @param newChannel Channel to set as active.