stream-chat-react-native-core 4.8.0 → 4.9.0-beta.3

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 (119) hide show
  1. package/lib/commonjs/components/Attachment/GallaryImage.js +41 -0
  2. package/lib/commonjs/components/Attachment/GallaryImage.js.map +1 -0
  3. package/lib/commonjs/components/Attachment/Gallery.js +101 -36
  4. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  5. package/lib/commonjs/components/Attachment/Giphy.js +118 -25
  6. package/lib/commonjs/components/Attachment/Giphy.js.map +1 -1
  7. package/lib/commonjs/components/Attachment/ImageLoadingFailedIndicator.js +105 -0
  8. package/lib/commonjs/components/Attachment/ImageLoadingFailedIndicator.js.map +1 -0
  9. package/lib/commonjs/components/Attachment/ImageLoadingIndicator.js +58 -0
  10. package/lib/commonjs/components/Attachment/ImageLoadingIndicator.js.map +1 -0
  11. package/lib/commonjs/components/Attachment/hooks/useLoadingImage.js +32 -0
  12. package/lib/commonjs/components/Attachment/hooks/useLoadingImage.js.map +1 -0
  13. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js +3 -2
  14. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
  15. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +1 -1
  16. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.js.map +1 -1
  17. package/lib/commonjs/components/Channel/Channel.js +23 -13
  18. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  19. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  20. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  21. package/lib/commonjs/components/ChannelPreview/hooks/useLatestMessagePreview.js +43 -19
  22. package/lib/commonjs/components/ChannelPreview/hooks/useLatestMessagePreview.js.map +1 -1
  23. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +28 -21
  24. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  25. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js +16 -17
  26. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js.map +1 -1
  27. package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js +43 -0
  28. package/lib/commonjs/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
  29. package/lib/commonjs/components/Reply/Reply.js +7 -2
  30. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  31. package/lib/commonjs/contexts/messagesContext/MessagesContext.js +2 -2
  32. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  33. package/lib/commonjs/contexts/themeContext/utils/theme.js +4 -0
  34. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  35. package/lib/commonjs/mock-builders/api/channelMocks.js +299 -0
  36. package/lib/commonjs/mock-builders/api/channelMocks.js.map +1 -0
  37. package/lib/commonjs/version.json +1 -1
  38. package/lib/module/components/Attachment/GallaryImage.js +41 -0
  39. package/lib/module/components/Attachment/GallaryImage.js.map +1 -0
  40. package/lib/module/components/Attachment/Gallery.js +101 -36
  41. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  42. package/lib/module/components/Attachment/Giphy.js +118 -25
  43. package/lib/module/components/Attachment/Giphy.js.map +1 -1
  44. package/lib/module/components/Attachment/ImageLoadingFailedIndicator.js +105 -0
  45. package/lib/module/components/Attachment/ImageLoadingFailedIndicator.js.map +1 -0
  46. package/lib/module/components/Attachment/ImageLoadingIndicator.js +58 -0
  47. package/lib/module/components/Attachment/ImageLoadingIndicator.js.map +1 -0
  48. package/lib/module/components/Attachment/hooks/useLoadingImage.js +32 -0
  49. package/lib/module/components/Attachment/hooks/useLoadingImage.js.map +1 -0
  50. package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js +3 -2
  51. package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
  52. package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +1 -1
  53. package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.js.map +1 -1
  54. package/lib/module/components/Channel/Channel.js +23 -13
  55. package/lib/module/components/Channel/Channel.js.map +1 -1
  56. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +4 -0
  57. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  58. package/lib/module/components/ChannelPreview/hooks/useLatestMessagePreview.js +43 -19
  59. package/lib/module/components/ChannelPreview/hooks/useLatestMessagePreview.js.map +1 -1
  60. package/lib/module/components/MessageInput/FileUploadPreview.js +28 -21
  61. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  62. package/lib/module/components/MessageInput/ImageUploadPreview.js +16 -17
  63. package/lib/module/components/MessageInput/ImageUploadPreview.js.map +1 -1
  64. package/lib/module/components/RTLComponents/WritingDirectionAwareText.js +43 -0
  65. package/lib/module/components/RTLComponents/WritingDirectionAwareText.js.map +1 -0
  66. package/lib/module/components/Reply/Reply.js +7 -2
  67. package/lib/module/components/Reply/Reply.js.map +1 -1
  68. package/lib/module/contexts/messagesContext/MessagesContext.js +2 -2
  69. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  70. package/lib/module/contexts/themeContext/utils/theme.js +4 -0
  71. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  72. package/lib/module/mock-builders/api/channelMocks.js +299 -0
  73. package/lib/module/mock-builders/api/channelMocks.js.map +1 -0
  74. package/lib/module/version.json +1 -1
  75. package/lib/typescript/components/Attachment/GallaryImage.d.ts +5 -0
  76. package/lib/typescript/components/Attachment/Gallery.d.ts +1 -1
  77. package/lib/typescript/components/Attachment/Giphy.d.ts +1 -1
  78. package/lib/typescript/components/Attachment/ImageLoadingFailedIndicator.d.ts +3 -0
  79. package/lib/typescript/components/Attachment/ImageLoadingIndicator.d.ts +3 -0
  80. package/lib/typescript/components/Attachment/hooks/useLoadingImage.d.ts +7 -0
  81. package/lib/typescript/components/Channel/Channel.d.ts +1 -1
  82. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
  83. package/lib/typescript/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.d.ts +1 -0
  84. package/lib/typescript/components/RTLComponents/WritingDirectionAwareText.d.ts +4 -0
  85. package/lib/typescript/components/Reply/__tests__/Reply.test.d.ts +1 -0
  86. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +10 -0
  87. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +4 -0
  88. package/lib/typescript/mock-builders/api/channelMocks.d.ts +14 -0
  89. package/lib/typescript/mock-builders/api/getOrCreateChannel.d.ts +7 -0
  90. package/lib/typescript/mock-builders/api/useMockedApis.d.ts +1 -0
  91. package/lib/typescript/mock-builders/generator/channel.d.ts +116 -0
  92. package/package.json +3 -2
  93. package/src/components/Attachment/GallaryImage.tsx +22 -0
  94. package/src/components/Attachment/Gallery.tsx +68 -35
  95. package/src/components/Attachment/Giphy.tsx +68 -1
  96. package/src/components/Attachment/ImageLoadingFailedIndicator.tsx +56 -0
  97. package/src/components/Attachment/ImageLoadingIndicator.tsx +31 -0
  98. package/src/components/Attachment/__tests__/Attachment.test.js +9 -3
  99. package/src/components/Attachment/__tests__/Gallery.test.js +36 -1
  100. package/src/components/Attachment/__tests__/Giphy.test.js +110 -90
  101. package/src/components/Attachment/hooks/useLoadingImage.tsx +8 -0
  102. package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +2 -1
  103. package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx +1 -1
  104. package/src/components/Channel/Channel.tsx +8 -0
  105. package/src/components/Channel/hooks/useCreateMessagesContext.ts +4 -0
  106. package/src/components/ChannelPreview/__tests__/ChannelPreviewMessenger.test.js +0 -1
  107. package/src/components/ChannelPreview/hooks/__tests__/useLatestMessagePreview.test.tsx +145 -0
  108. package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts +50 -24
  109. package/src/components/MessageInput/FileUploadPreview.tsx +11 -8
  110. package/src/components/MessageInput/ImageUploadPreview.tsx +4 -5
  111. package/src/components/MessageInput/__tests__/__snapshots__/MessageInput.test.js.snap +1 -0
  112. package/src/components/RTLComponents/WritingDirectionAwareText.tsx +17 -0
  113. package/src/components/Reply/Reply.tsx +19 -3
  114. package/src/components/Reply/__tests__/Reply.test.tsx +48 -0
  115. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +1 -0
  116. package/src/contexts/messagesContext/MessagesContext.tsx +15 -0
  117. package/src/contexts/themeContext/utils/theme.ts +8 -0
  118. package/src/mock-builders/api/channelMocks.tsx +272 -0
  119. package/src/version.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
2
 
3
- import type { Channel, ChannelState, MessageResponse, StreamChat } from 'stream-chat';
3
+ import type { Channel, ChannelState, MessageResponse, StreamChat, UserResponse } from 'stream-chat';
4
4
 
5
5
  import { useChatContext } from '../../../contexts/chatContext/ChatContext';
6
6
  import {
@@ -29,6 +29,43 @@ export type LatestMessagePreview<
29
29
  status: number;
30
30
  };
31
31
 
32
+ const getMessageSenderName = <
33
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
34
+ >(
35
+ message: LatestMessage<StreamChatGenerics> | undefined,
36
+ currentUserId: string | undefined,
37
+ t: (key: string) => string,
38
+ membersLength: number,
39
+ ) => {
40
+ if (message?.user?.id === currentUserId) {
41
+ return t('You');
42
+ }
43
+
44
+ if (membersLength > 2) {
45
+ return message?.user?.name || message?.user?.username || message?.user?.id || '';
46
+ }
47
+
48
+ return '';
49
+ };
50
+
51
+ const getMentionUsers = <
52
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
53
+ >(
54
+ mentionedUser: UserResponse<StreamChatGenerics>[] | undefined,
55
+ ) => {
56
+ if (Array.isArray(mentionedUser)) {
57
+ const mentionUserString = mentionedUser.reduce((acc, cur) => {
58
+ const userName = cur.name || cur.id || '';
59
+ if (userName) {
60
+ acc += `${acc.length ? '|' : ''}@${userName}`;
61
+ }
62
+ return acc;
63
+ }, '');
64
+ return mentionUserString;
65
+ }
66
+ return '';
67
+ };
68
+
32
69
  const getLatestMessageDisplayText = <
33
70
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
34
71
  >(
@@ -40,32 +77,21 @@ const getLatestMessageDisplayText = <
40
77
  if (!message) return [{ bold: false, text: t('Nothing yet...') }];
41
78
  const isMessageTypeDeleted = message.type === 'deleted';
42
79
  if (isMessageTypeDeleted) return [{ bold: false, text: t('Message deleted') }];
43
- const currentUserId = client.userID;
44
- const messageOwnerId = message.user?.id;
80
+ const currentUserId = client?.userID;
45
81
  const members = Object.keys(channel.state.members);
46
- const owner =
47
- messageOwnerId === currentUserId
48
- ? t('You')
49
- : members.length > 2
50
- ? message.user?.name || message.user?.username || message.user?.id || ''
51
- : '';
52
- const ownerText = owner ? `${owner === t('You') ? '' : '@'}${owner}: ` : '';
53
- const boldOwner = ownerText.includes('@');
82
+
83
+ const messageSender = getMessageSenderName(message, currentUserId, t, members.length);
84
+ const messageSenderText = messageSender
85
+ ? `${messageSender === t('You') ? '' : '@'}${messageSender}: `
86
+ : '';
87
+ const boldOwner = messageSenderText.includes('@');
54
88
  if (message.text) {
55
89
  // rough guess optimization to limit string preview to max 100 characters
56
90
  const shortenedText = message.text.substring(0, 100).replace(/\n/g, ' ');
57
- const mentionedUsers = Array.isArray(message.mentioned_users)
58
- ? message.mentioned_users.reduce((acc, cur) => {
59
- const userName = cur.name || cur.id || '';
60
- if (userName) {
61
- acc += `${acc.length ? '|' : ''}@${userName}`;
62
- }
63
- return acc;
64
- }, '')
65
- : '';
91
+ const mentionedUsers = getMentionUsers(message.mentioned_users);
66
92
  const regEx = new RegExp(`^(${mentionedUsers})`);
67
93
  return [
68
- { bold: boldOwner, text: ownerText },
94
+ { bold: boldOwner, text: messageSenderText },
69
95
  ...shortenedText.split('').reduce(
70
96
  (acc, cur, index) => {
71
97
  if (cur === '@' && mentionedUsers && regEx.test(shortenedText.substring(index))) {
@@ -83,18 +109,18 @@ const getLatestMessageDisplayText = <
83
109
  }
84
110
  if (message.command) {
85
111
  return [
86
- { bold: boldOwner, text: ownerText },
112
+ { bold: boldOwner, text: messageSenderText },
87
113
  { bold: false, text: `/${message.command}` },
88
114
  ];
89
115
  }
90
116
  if (message.attachments?.length) {
91
117
  return [
92
- { bold: boldOwner, text: ownerText },
118
+ { bold: boldOwner, text: messageSenderText },
93
119
  { bold: false, text: t('🏙 Attachment...') },
94
120
  ];
95
121
  }
96
122
  return [
97
- { bold: boldOwner, text: ownerText },
123
+ { bold: boldOwner, text: messageSenderText },
98
124
  { bold: false, text: t('Empty message...') },
99
125
  ];
100
126
  };
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
- import { FlatList, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
2
+ import { FlatList, I18nManager, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3
3
 
4
4
  import { UploadProgressIndicator } from './UploadProgressIndicator';
5
5
 
@@ -19,6 +19,7 @@ import { Warning } from '../../icons/Warning';
19
19
  import type { DefaultStreamChatGenerics } from '../../types/types';
20
20
  import { getIndicatorTypeForFileState, ProgressIndicatorTypes } from '../../utils/utils';
21
21
  import { getFileSizeDisplayText } from '../Attachment/FileAttachment';
22
+ import { WritingDirectionAwareText } from '../RTLComponents/WritingDirectionAwareText';
22
23
 
23
24
  const FILE_PREVIEW_HEIGHT = 60;
24
25
  const WARNING_ICON_SIZE = 16;
@@ -45,11 +46,11 @@ const styles = StyleSheet.create({
45
46
  filenameText: {
46
47
  fontSize: 14,
47
48
  fontWeight: 'bold',
48
- paddingLeft: 10,
49
+ paddingHorizontal: 10,
49
50
  },
50
51
  fileSizeText: {
51
52
  fontSize: 12,
52
- paddingLeft: 10,
53
+ paddingHorizontal: 10,
53
54
  },
54
55
  fileTextContainer: {
55
56
  height: '100%',
@@ -66,11 +67,12 @@ const styles = StyleSheet.create({
66
67
  paddingLeft: 10,
67
68
  },
68
69
  unsupportedFileText: {
69
- fontSize: 16,
70
+ fontSize: 12,
71
+ marginHorizontal: 4,
70
72
  },
71
73
  warningIconStyle: {
72
74
  borderRadius: 24,
73
- marginTop: 4,
75
+ marginTop: 2,
74
76
  },
75
77
  });
76
78
 
@@ -104,9 +106,9 @@ const UnsupportedFileTypeOrFileSizeIndicator = ({
104
106
  </Text>
105
107
  </View>
106
108
  ) : (
107
- <Text style={[styles.fileSizeText, { color: grey }, fileSizeText]}>
108
- {item.file.duration ? item.file.duration : getFileSizeDisplayText(item.file.size)}
109
- </Text>
109
+ <WritingDirectionAwareText style={[styles.fileSizeText, { color: grey }, fileSizeText]}>
110
+ {item.file.duration || getFileSizeDisplayText(item.file.size)}
111
+ </WritingDirectionAwareText>
110
112
  );
111
113
  };
112
114
 
@@ -187,6 +189,7 @@ const FileUploadPreviewWithContext = <
187
189
  24 - // 24 = close icon size
188
190
  24, // 24 = internal padding
189
191
  },
192
+ I18nManager.isRTL ? { writingDirection: 'rtl' } : { writingDirection: 'ltr' },
190
193
  filenameText,
191
194
  ]}
192
195
  >
@@ -27,7 +27,7 @@ const styles = StyleSheet.create({
27
27
  },
28
28
  fileSizeText: {
29
29
  fontSize: 12,
30
- paddingLeft: 10,
30
+ paddingHorizontal: 10,
31
31
  },
32
32
  flatList: { paddingBottom: 12 },
33
33
  iconContainer: {
@@ -44,7 +44,7 @@ const styles = StyleSheet.create({
44
44
  borderRadius: 20,
45
45
  bottom: 8,
46
46
  flexDirection: 'row',
47
- marginLeft: 3,
47
+ marginHorizontal: 3,
48
48
  position: 'absolute',
49
49
  },
50
50
  upload: {
@@ -54,15 +54,14 @@ const styles = StyleSheet.create({
54
54
  },
55
55
  warningIconStyle: {
56
56
  borderRadius: 24,
57
- marginLeft: 4,
58
- marginTop: 4,
57
+ marginTop: 6,
59
58
  },
60
59
  warningText: {
61
60
  alignItems: 'center',
62
61
  color: 'black',
63
62
  fontSize: 10,
64
63
  justifyContent: 'center',
65
- paddingRight: 8,
64
+ marginHorizontal: 4,
66
65
  },
67
66
  });
68
67
 
@@ -286,6 +286,7 @@ Array [
286
286
  Object {
287
287
  "color": "#000000",
288
288
  "maxHeight": 85,
289
+ "textAlign": "left",
289
290
  },
290
291
  Object {},
291
292
  ]
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { I18nManager, StyleSheet, Text, ViewProps } from 'react-native';
3
+
4
+ const styles = StyleSheet.create({
5
+ defaultStyle: { writingDirection: I18nManager.isRTL ? 'rtl' : 'ltr' },
6
+ });
7
+
8
+ export type WritingDirectionAwareTextProps = ViewProps;
9
+
10
+ export const WritingDirectionAwareText: React.FC<WritingDirectionAwareTextProps> = (props) => {
11
+ const { children, style, ...rest } = props;
12
+ return (
13
+ <Text {...rest} style={[style, styles.defaultStyle]}>
14
+ {children}
15
+ </Text>
16
+ );
17
+ };
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { useContext, useState } from 'react';
2
2
  import { Image, ImageStyle, StyleSheet, View, ViewStyle } from 'react-native';
3
3
 
4
4
  import merge from 'lodash/merge';
@@ -7,8 +7,8 @@ import type { Attachment } from 'stream-chat';
7
7
 
8
8
  import { useMessageContext } from '../../contexts/messageContext/MessageContext';
9
9
  import {
10
+ MessageInputContext,
10
11
  MessageInputContextValue,
11
- useMessageInputContext,
12
12
  } from '../../contexts/messageInputContext/MessageInputContext';
13
13
  import {
14
14
  MessagesContextValue,
@@ -267,6 +267,22 @@ const ReplyWithContext = <
267
267
  );
268
268
  };
269
269
 
270
+ /**
271
+ * When a reply is rendered in a MessageSimple, it does
272
+ * not have a MessageInputContext. As this is deliberate,
273
+ * this function exists to avoid the error thrown when
274
+ * using a context outside of its provider.
275
+ * */
276
+ const useMessageInputContextIfAvailable = <
277
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
278
+ >() => {
279
+ const contextValue = useContext(
280
+ MessageInputContext,
281
+ ) as unknown as MessageInputContextValue<StreamChatGenerics>;
282
+
283
+ return contextValue;
284
+ };
285
+
270
286
  const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(
271
287
  prevProps: ReplyPropsWithContext<StreamChatGenerics>,
272
288
  nextProps: ReplyPropsWithContext<StreamChatGenerics>,
@@ -307,7 +323,7 @@ export const Reply = <
307
323
  const { FileAttachmentIcon = FileIconDefault, MessageAvatar = MessageAvatarDefault } =
308
324
  useMessagesContext<StreamChatGenerics>();
309
325
 
310
- const { editing, quotedMessage } = useMessageInputContext<StreamChatGenerics>();
326
+ const { editing, quotedMessage } = useMessageInputContextIfAvailable<StreamChatGenerics>();
311
327
 
312
328
  const quotedEditingMessage = (
313
329
  typeof editing !== 'boolean' ? editing?.quoted_message || false : false
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+
3
+ import { render, waitFor } from '@testing-library/react-native';
4
+
5
+ import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvider';
6
+ import { getOrCreateChannelApi } from '../../../mock-builders/api/getOrCreateChannel';
7
+ import { useMockedApis } from '../../../mock-builders/api/useMockedApis';
8
+ import { generateChannelResponse } from '../../../mock-builders/generator/channel';
9
+ import { getTestClientWithUser } from '../../../mock-builders/mock';
10
+ import { Channel } from '../../Channel/Channel';
11
+ import { Chat } from '../../Chat/Chat';
12
+ import { Reply } from '../Reply';
13
+
14
+ describe('<Reply/>', () => {
15
+ it('can be rendered outside of a MessageInputProvider', async () => {
16
+ const oldEnvironment = process.env;
17
+ process.env.NODE_ENV = 'not_test';
18
+
19
+ const chatClient = await getTestClientWithUser({ id: 'neil' });
20
+
21
+ const mockedChannel = generateChannelResponse();
22
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
23
+ const channel = chatClient.channel('messaging', 'some-chat');
24
+ await channel.watch();
25
+
26
+ const TestComponent = () => (
27
+ <OverlayProvider>
28
+ <Chat client={chatClient}>
29
+ <Channel channel={channel} client={chatClient}>
30
+ <Reply />
31
+ </Channel>
32
+ </Chat>
33
+ </OverlayProvider>
34
+ );
35
+
36
+ try {
37
+ const { toJSON } = render(<TestComponent />);
38
+
39
+ await waitFor(() => {
40
+ expect(toJSON()).not.toBeNull();
41
+ });
42
+ } catch (error: unknown) {
43
+ throw new Error(`Error thrown while rendering Reply: ${error}`);
44
+ }
45
+
46
+ process.env = oldEnvironment;
47
+ });
48
+ });
@@ -1623,6 +1623,7 @@ exports[`Thread should match thread snapshot 1`] = `
1623
1623
  Object {
1624
1624
  "color": "#000000",
1625
1625
  "maxHeight": 85,
1626
+ "textAlign": "left",
1626
1627
  },
1627
1628
  Object {},
1628
1629
  ]
@@ -2,6 +2,9 @@ import React, { PropsWithChildren, useContext } from 'react';
2
2
 
3
3
  import type { TouchableOpacityProps } from 'react-native';
4
4
 
5
+ import type { ImageLoadingFailedIndicatorProps } from 'src/components/Attachment/ImageLoadingFailedIndicator';
6
+ import type { ImageLoadingIndicatorProps } from 'src/components/Attachment/ImageLoadingIndicator';
7
+
5
8
  import type { MessagePinnedHeaderProps } from 'src/components/Message/MessageSimple/MessagePinnedHeader';
6
9
 
7
10
  import type { Attachment, ChannelState, MessageResponse } from 'stream-chat';
@@ -115,6 +118,17 @@ export type MessagesContextValue<
115
118
  * The giphy version to render - check the keys of the [Image Object](https://developers.giphy.com/docs/api/schema#image-object) for possible values. Uses 'fixed_height' by default
116
119
  * */
117
120
  giphyVersion: keyof NonNullable<Attachment['giphy']>;
121
+
122
+ /**
123
+ * The indicator rendered when loading an image fails.
124
+ */
125
+ ImageLoadingFailedIndicator: React.ComponentType<ImageLoadingFailedIndicatorProps>;
126
+
127
+ /**
128
+ * The indicator rendered when image is loading. By default renders <ActivityIndicator/>
129
+ */
130
+ ImageLoadingIndicator: React.ComponentType<ImageLoadingIndicatorProps>;
131
+
118
132
  /**
119
133
  * When true, messageList will be scrolled at first unread message, when opened.
120
134
  */
@@ -129,6 +143,7 @@ export type MessagesContextValue<
129
143
  * Defaults to: [InlineUnreadIndicator](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/Message/MessageSimple/InlineUnreadIndicator.tsx)
130
144
  **/
131
145
  InlineUnreadIndicator: React.ComponentType;
146
+
132
147
  Message: React.ComponentType<MessageProps<StreamChatGenerics>>;
133
148
  /**
134
149
  * UI component for MessageAvatar
@@ -454,6 +454,10 @@ export type Theme = {
454
454
  shuffle: TextStyle;
455
455
  title: TextStyle;
456
456
  };
457
+ loadingIndicator: {
458
+ container: ViewStyle;
459
+ roundedView: ViewStyle;
460
+ };
457
461
  pinnedHeader: {
458
462
  container: ViewStyle;
459
463
  label: TextStyle;
@@ -971,6 +975,10 @@ export const defaultTheme: Theme = {
971
975
  shuffle: {},
972
976
  title: {},
973
977
  },
978
+ loadingIndicator: {
979
+ container: {},
980
+ roundedView: {},
981
+ },
974
982
  pinnedHeader: {
975
983
  container: {},
976
984
  label: {},
@@ -0,0 +1,272 @@
1
+ import type {
2
+ Attachment,
3
+ Channel,
4
+ FormatMessageResponse,
5
+ MessageResponse,
6
+ UserResponse,
7
+ } from 'stream-chat';
8
+
9
+ import {
10
+ GROUP_CHANNEL_MEMBERS_MOCK,
11
+ ONE_MEMBER_WITH_EMPTY_USER_MOCK,
12
+ } from '../../mock-builders/api/queryMembers';
13
+
14
+ import type { DefaultStreamChatGenerics } from '../../types/types';
15
+
16
+ const channelName = 'okechukwu';
17
+ const CHANNEL = {
18
+ data: { name: channelName },
19
+ state: { messages: [] },
20
+ } as unknown as Channel<DefaultStreamChatGenerics>;
21
+
22
+ const CHANNEL_WITH_MESSAGES_TEXT = {
23
+ data: { name: channelName },
24
+ state: {
25
+ members: GROUP_CHANNEL_MEMBERS_MOCK,
26
+ messages: [
27
+ {
28
+ args: 'string',
29
+ attachments: [],
30
+ channel: CHANNEL,
31
+ cid: 'stridkncnng',
32
+ command: 'giphy',
33
+ command_info: { name: 'string' },
34
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
35
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
36
+ id: 'ljkblk',
37
+ text: 'jkbkbiubicbi',
38
+ type: 'MessageLabel',
39
+ user: { id: 'okechukwu' } as unknown as UserResponse<DefaultStreamChatGenerics>,
40
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
41
+ {
42
+ args: 'string',
43
+ attachments: [],
44
+ channel: CHANNEL,
45
+ cid: 'stridodong',
46
+ command: 'giphy',
47
+ command_info: { name: 'string' },
48
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
49
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
50
+ id: 'jbkjb',
51
+ text: 'jkbkbiubicbi',
52
+ type: 'MessageLabel',
53
+ user: { id: 'okechukwu' } as unknown as UserResponse<DefaultStreamChatGenerics>,
54
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
55
+ ],
56
+ },
57
+ } as unknown as Channel<DefaultStreamChatGenerics>;
58
+
59
+ const CHANNEL_WITH_DELETED_MESSAGES = {
60
+ data: { name: channelName },
61
+ state: {
62
+ members: GROUP_CHANNEL_MEMBERS_MOCK,
63
+ messages: [
64
+ {
65
+ type: 'deleted',
66
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
67
+ {
68
+ type: 'deleted',
69
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
70
+ ],
71
+ },
72
+ } as unknown as Channel<DefaultStreamChatGenerics>;
73
+
74
+ const CHANNEL_WITH_NO_MESSAGES = {
75
+ data: { name: channelName },
76
+ state: {
77
+ members: GROUP_CHANNEL_MEMBERS_MOCK,
78
+ messages: [],
79
+ },
80
+ } as unknown as Channel<DefaultStreamChatGenerics>;
81
+
82
+ const CHANNEL_WITH_MESSAGE_COMMAND = {
83
+ data: { name: channelName },
84
+ state: {
85
+ members: GROUP_CHANNEL_MEMBERS_MOCK,
86
+ messages: [
87
+ {
88
+ args: 'string',
89
+ attachments: [],
90
+ channel: CHANNEL,
91
+ cid: 'stridkncnng',
92
+ command: 'giphy',
93
+ command_info: { name: 'string' },
94
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
95
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
96
+ id: 'ljkblk',
97
+ user: { id: 'okechukwu' } as unknown as UserResponse<DefaultStreamChatGenerics>,
98
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
99
+ {
100
+ args: 'string',
101
+ attachments: [],
102
+ channel: CHANNEL,
103
+ cid: 'stridodong',
104
+ command: 'giphy',
105
+ command_info: { name: 'string' },
106
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
107
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
108
+ id: 'jbkjb',
109
+ user: { id: 'okechukwu' } as unknown as UserResponse<DefaultStreamChatGenerics>,
110
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
111
+ ],
112
+ },
113
+ } as unknown as Channel<DefaultStreamChatGenerics>;
114
+
115
+ const CHANNEL_WITH_MESSAGES_ATTACHMENTS = {
116
+ data: { name: channelName },
117
+ state: {
118
+ members: GROUP_CHANNEL_MEMBERS_MOCK,
119
+ messages: [
120
+ {
121
+ args: 'string',
122
+ attachments: [
123
+ {
124
+ actions: [],
125
+ asset_url: 'string',
126
+ author_icon: 'string',
127
+ author_link: 'string',
128
+ author_name: 'string',
129
+ color: 'string',
130
+ fallback: 'string',
131
+ fields: [],
132
+ file_size: 25,
133
+ footer: 'string',
134
+ footer_icon: 'string',
135
+ image_url: 'string',
136
+ mime_type: 'string',
137
+ og_scrape_url: 'string',
138
+ original_height: 5,
139
+ original_width: 4,
140
+ pretext: 'string',
141
+ text: 'string',
142
+ thumb_url: 'string',
143
+ title: 'string',
144
+ title_link: 'string',
145
+ type: 'string',
146
+ } as Attachment<DefaultStreamChatGenerics>,
147
+ ],
148
+ channel: CHANNEL,
149
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
150
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
151
+ id: 'ljkblk',
152
+ user: { id: 'okechukwu' } as unknown as UserResponse<DefaultStreamChatGenerics>,
153
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
154
+ ],
155
+ },
156
+ } as unknown as Channel<DefaultStreamChatGenerics>;
157
+
158
+ const LATEST_MESSAGE = {
159
+ args: 'string',
160
+ attachments: [],
161
+ channel: CHANNEL,
162
+ cid: 'string',
163
+ command: 'giphy',
164
+ command_info: { name: 'string' },
165
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
166
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
167
+ id: 'string',
168
+ text: 'jkbkbiubicbi',
169
+ type: 'MessageLabel',
170
+ user: { id: 'okechukwu' } as unknown as UserResponse<DefaultStreamChatGenerics>,
171
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>;
172
+
173
+ const FORMATTED_MESSAGE: FormatMessageResponse<DefaultStreamChatGenerics> = {
174
+ created_at: new Date('2021-02-12T12:12:35.862282Z'),
175
+ id: '',
176
+ message: {} as unknown as MessageResponse<DefaultStreamChatGenerics>,
177
+ pinned_at: new Date('2021-02-12T12:12:35.862282Z'),
178
+ status: 'received',
179
+ updated_at: new Date('2021-02-12T12:12:35.862282Z'),
180
+ };
181
+
182
+ const CHANNEL_WITH_MENTIONED_USERS = {
183
+ state: {
184
+ members: ONE_MEMBER_WITH_EMPTY_USER_MOCK,
185
+ messages: [
186
+ {
187
+ args: 'string',
188
+ attachments: [],
189
+ cid: 'stridkncnng',
190
+ command_info: { name: 'string' },
191
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
192
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
193
+ mentioned_users: [
194
+ { id: 'Max', name: 'Max' },
195
+ { id: 'Ada', name: 'Ada' },
196
+ { id: 'Enzo', name: 'Enzo' },
197
+ ] as UserResponse<DefaultStreamChatGenerics>[],
198
+ text: 'Max',
199
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
200
+ {
201
+ args: 'string',
202
+ attachments: [],
203
+ cid: 'stridodong',
204
+ command_info: { name: 'string' },
205
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
206
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
207
+ mentioned_users: [
208
+ { id: 'Max', name: 'Max' },
209
+ { id: 'Ada', name: 'Ada' },
210
+ { id: 'Enzo', name: 'Enzo' },
211
+ ] as UserResponse<DefaultStreamChatGenerics>[],
212
+ text: 'Max',
213
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
214
+ ],
215
+ },
216
+ } as unknown as Channel<DefaultStreamChatGenerics>;
217
+
218
+ const CHANNEL_WITH_EMPTY_MESSAGE = {
219
+ state: {
220
+ members: ONE_MEMBER_WITH_EMPTY_USER_MOCK,
221
+ messages: [
222
+ {
223
+ args: 'string',
224
+ attachments: [],
225
+ cid: 'stridkncnng',
226
+ command_info: { name: 'string' },
227
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
228
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
229
+ mentioned_users: [
230
+ { id: 'Max', name: 'Max' },
231
+ { id: 'Ada', name: 'Ada' },
232
+ { id: 'Enzo', name: 'Enzo' },
233
+ ] as UserResponse<DefaultStreamChatGenerics>[],
234
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
235
+ {
236
+ args: 'string',
237
+ attachments: [],
238
+ cid: 'stridodong',
239
+ command_info: { name: 'string' },
240
+ created_at: new Date('2021-02-12T12:12:35.862Z'),
241
+ deleted_at: new Date('2021-02-12T12:12:35.862Z'),
242
+ mentioned_users: [
243
+ { id: 'Max', name: 'Max' },
244
+ { id: 'Ada', name: 'Ada' },
245
+ { id: 'Enzo', name: 'Enzo' },
246
+ ] as UserResponse<DefaultStreamChatGenerics>[],
247
+ } as unknown as MessageResponse<DefaultStreamChatGenerics>,
248
+ ],
249
+ },
250
+ } as unknown as Channel<DefaultStreamChatGenerics>;
251
+
252
+ const CHANNEL_WITH_MESSAGES = {
253
+ data: { name: channelName },
254
+ state: {
255
+ members: GROUP_CHANNEL_MEMBERS_MOCK,
256
+ messages: [FORMATTED_MESSAGE, FORMATTED_MESSAGE],
257
+ },
258
+ } as unknown as Channel<DefaultStreamChatGenerics>;
259
+
260
+ export {
261
+ CHANNEL,
262
+ CHANNEL_WITH_EMPTY_MESSAGE,
263
+ CHANNEL_WITH_MESSAGES,
264
+ CHANNEL_WITH_MENTIONED_USERS,
265
+ FORMATTED_MESSAGE,
266
+ LATEST_MESSAGE,
267
+ CHANNEL_WITH_MESSAGES_ATTACHMENTS,
268
+ CHANNEL_WITH_MESSAGE_COMMAND as CHANNEL_WITH_MESSAGES_COMMAND,
269
+ CHANNEL_WITH_NO_MESSAGES,
270
+ CHANNEL_WITH_DELETED_MESSAGES,
271
+ CHANNEL_WITH_MESSAGES_TEXT,
272
+ };
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "4.8.0"
2
+ "version": "4.9.0-beta.3"
3
3
  }