stream-chat-react-native-core 4.3.1 → 4.4.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 (186) hide show
  1. package/README.md +3 -3
  2. package/lib/commonjs/components/Attachment/Card.js +25 -28
  3. package/lib/commonjs/components/Attachment/Card.js.map +1 -1
  4. package/lib/commonjs/components/Attachment/FileAttachment.js +19 -24
  5. package/lib/commonjs/components/Attachment/FileAttachment.js.map +1 -1
  6. package/lib/commonjs/components/Attachment/Giphy.js +27 -25
  7. package/lib/commonjs/components/Attachment/Giphy.js.map +1 -1
  8. package/lib/commonjs/components/Attachment/hooks/useGoToURL.js +42 -0
  9. package/lib/commonjs/components/Attachment/hooks/useGoToURL.js.map +1 -0
  10. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +11 -7
  11. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  12. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  13. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js +4 -12
  14. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  15. package/lib/commonjs/components/Channel/hooks/useCreateThreadContext.js +4 -12
  16. package/lib/commonjs/components/Channel/hooks/useCreateThreadContext.js.map +1 -1
  17. package/lib/commonjs/components/Chat/Chat.js +8 -4
  18. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  19. package/lib/commonjs/components/Chat/hooks/useAppSettings.js +80 -0
  20. package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -0
  21. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js +3 -1
  22. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  23. package/lib/commonjs/components/Message/Message.js +27 -22
  24. package/lib/commonjs/components/Message/Message.js.map +1 -1
  25. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js +28 -14
  26. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  27. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +108 -40
  28. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  29. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js +117 -24
  30. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js.map +1 -1
  31. package/lib/commonjs/components/MessageInput/UploadProgressIndicator.js +52 -20
  32. package/lib/commonjs/components/MessageInput/UploadProgressIndicator.js.map +1 -1
  33. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js +8 -6
  34. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js.map +1 -1
  35. package/lib/commonjs/contexts/chatContext/ChatContext.js +2 -2
  36. package/lib/commonjs/contexts/chatContext/ChatContext.js.map +1 -1
  37. package/lib/commonjs/contexts/messageContext/MessageContext.js +2 -2
  38. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  39. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +145 -119
  40. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  41. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  42. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  43. package/lib/commonjs/i18n/en.json +2 -0
  44. package/lib/commonjs/i18n/fr.json +2 -0
  45. package/lib/commonjs/i18n/hi.json +2 -0
  46. package/lib/commonjs/i18n/it.json +2 -0
  47. package/lib/commonjs/i18n/ja.json +3 -1
  48. package/lib/commonjs/i18n/ko.json +3 -1
  49. package/lib/commonjs/i18n/nl.json +2 -0
  50. package/lib/commonjs/i18n/ru.json +2 -0
  51. package/lib/commonjs/i18n/tr.json +2 -0
  52. package/lib/commonjs/icons/Warning.js +38 -0
  53. package/lib/commonjs/icons/Warning.js.map +1 -0
  54. package/lib/commonjs/icons/index.js +13 -0
  55. package/lib/commonjs/icons/index.js.map +1 -1
  56. package/lib/commonjs/utils/utils.js +33 -2
  57. package/lib/commonjs/utils/utils.js.map +1 -1
  58. package/lib/commonjs/version.json +1 -1
  59. package/lib/module/components/Attachment/Card.js +25 -28
  60. package/lib/module/components/Attachment/Card.js.map +1 -1
  61. package/lib/module/components/Attachment/FileAttachment.js +19 -24
  62. package/lib/module/components/Attachment/FileAttachment.js.map +1 -1
  63. package/lib/module/components/Attachment/Giphy.js +27 -25
  64. package/lib/module/components/Attachment/Giphy.js.map +1 -1
  65. package/lib/module/components/Attachment/hooks/useGoToURL.js +42 -0
  66. package/lib/module/components/Attachment/hooks/useGoToURL.js.map +1 -0
  67. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +11 -7
  68. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  69. package/lib/module/components/Channel/Channel.js.map +1 -1
  70. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js +4 -12
  71. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  72. package/lib/module/components/Channel/hooks/useCreateThreadContext.js +4 -12
  73. package/lib/module/components/Channel/hooks/useCreateThreadContext.js.map +1 -1
  74. package/lib/module/components/Chat/Chat.js +8 -4
  75. package/lib/module/components/Chat/Chat.js.map +1 -1
  76. package/lib/module/components/Chat/hooks/useAppSettings.js +80 -0
  77. package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -0
  78. package/lib/module/components/Chat/hooks/useCreateChatContext.js +3 -1
  79. package/lib/module/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  80. package/lib/module/components/Message/Message.js +27 -22
  81. package/lib/module/components/Message/Message.js.map +1 -1
  82. package/lib/module/components/Message/MessageSimple/utils/renderText.js +28 -14
  83. package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  84. package/lib/module/components/MessageInput/FileUploadPreview.js +108 -40
  85. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  86. package/lib/module/components/MessageInput/ImageUploadPreview.js +117 -24
  87. package/lib/module/components/MessageInput/ImageUploadPreview.js.map +1 -1
  88. package/lib/module/components/MessageInput/UploadProgressIndicator.js +52 -20
  89. package/lib/module/components/MessageInput/UploadProgressIndicator.js.map +1 -1
  90. package/lib/module/components/MessageList/ScrollToBottomButton.js +8 -6
  91. package/lib/module/components/MessageList/ScrollToBottomButton.js.map +1 -1
  92. package/lib/module/contexts/chatContext/ChatContext.js +2 -2
  93. package/lib/module/contexts/chatContext/ChatContext.js.map +1 -1
  94. package/lib/module/contexts/messageContext/MessageContext.js +2 -2
  95. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  96. package/lib/module/contexts/messageInputContext/MessageInputContext.js +145 -119
  97. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  98. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  99. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  100. package/lib/module/i18n/en.json +2 -0
  101. package/lib/module/i18n/fr.json +2 -0
  102. package/lib/module/i18n/hi.json +2 -0
  103. package/lib/module/i18n/it.json +2 -0
  104. package/lib/module/i18n/ja.json +3 -1
  105. package/lib/module/i18n/ko.json +3 -1
  106. package/lib/module/i18n/nl.json +2 -0
  107. package/lib/module/i18n/ru.json +2 -0
  108. package/lib/module/i18n/tr.json +2 -0
  109. package/lib/module/icons/Warning.js +38 -0
  110. package/lib/module/icons/Warning.js.map +1 -0
  111. package/lib/module/icons/index.js +13 -0
  112. package/lib/module/icons/index.js.map +1 -1
  113. package/lib/module/utils/utils.js +33 -2
  114. package/lib/module/utils/utils.js.map +1 -1
  115. package/lib/module/version.json +1 -1
  116. package/lib/typescript/components/Attachment/FileAttachment.d.ts +0 -1
  117. package/lib/typescript/components/Attachment/hooks/useGoToURL.d.ts +2 -0
  118. package/lib/typescript/components/Chat/hooks/__tests__/useAppSettings.test.d.ts +1 -0
  119. package/lib/typescript/components/Chat/hooks/useAppSettings.d.ts +3 -0
  120. package/lib/typescript/components/Chat/hooks/useCreateChatContext.d.ts +1 -1
  121. package/lib/typescript/components/Message/Message.d.ts +12 -2
  122. package/lib/typescript/components/MessageInput/UploadProgressIndicator.d.ts +1 -3
  123. package/lib/typescript/contexts/chatContext/ChatContext.d.ts +5 -1
  124. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +4 -4
  125. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +3 -3
  126. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +1 -0
  127. package/lib/typescript/i18n/en.json +2 -0
  128. package/lib/typescript/i18n/fr.json +2 -0
  129. package/lib/typescript/i18n/hi.json +2 -0
  130. package/lib/typescript/i18n/it.json +2 -0
  131. package/lib/typescript/i18n/ja.json +3 -1
  132. package/lib/typescript/i18n/ko.json +3 -1
  133. package/lib/typescript/i18n/nl.json +2 -0
  134. package/lib/typescript/i18n/ru.json +2 -0
  135. package/lib/typescript/i18n/tr.json +2 -0
  136. package/lib/typescript/icons/Warning.d.ts +3 -0
  137. package/lib/typescript/icons/index.d.ts +1 -0
  138. package/lib/typescript/utils/Streami18n.d.ts +6 -0
  139. package/lib/typescript/utils/utils.d.ts +15 -2
  140. package/package.json +2 -2
  141. package/src/components/Attachment/Card.tsx +5 -13
  142. package/src/components/Attachment/FileAttachment.tsx +5 -13
  143. package/src/components/Attachment/Giphy.tsx +3 -1
  144. package/src/components/Attachment/__tests__/Attachment.test.js +39 -0
  145. package/src/components/Attachment/hooks/useGoToURL.ts +27 -0
  146. package/src/components/AttachmentPicker/AttachmentPicker.tsx +23 -13
  147. package/src/components/Channel/Channel.tsx +1 -1
  148. package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts +3 -9
  149. package/src/components/Channel/hooks/useCreateThreadContext.ts +3 -9
  150. package/src/components/ChannelList/hooks/listeners/__tests__/useChannelUpdated.test.tsx +1 -0
  151. package/src/components/Chat/Chat.tsx +4 -0
  152. package/src/components/Chat/hooks/__tests__/useAppSettings.test.tsx +34 -0
  153. package/src/components/Chat/hooks/useAppSettings.ts +39 -0
  154. package/src/components/Chat/hooks/useCreateChatContext.ts +2 -0
  155. package/src/components/Message/Message.tsx +56 -48
  156. package/src/components/Message/MessageSimple/utils/renderText.tsx +17 -2
  157. package/src/components/MessageInput/FileUploadPreview.tsx +60 -14
  158. package/src/components/MessageInput/ImageUploadPreview.tsx +95 -42
  159. package/src/components/MessageInput/UploadProgressIndicator.tsx +49 -22
  160. package/src/components/MessageInput/__tests__/FileUploadPreview.test.js +50 -80
  161. package/src/components/MessageInput/__tests__/ImageUploadPreview.test.js +49 -74
  162. package/src/components/MessageInput/__tests__/UploadProgressIndicator.test.js +36 -13
  163. package/src/components/MessageInput/__tests__/__snapshots__/MessageInput.test.js.snap +2 -2
  164. package/src/components/MessageInput/__tests__/__snapshots__/UploadProgressIndicator.test.js.snap +122 -17
  165. package/src/components/MessageList/ScrollToBottomButton.tsx +2 -1
  166. package/src/components/MessageList/__tests__/__snapshots__/ScrollToBottomButton.test.js.snap +1 -0
  167. package/src/contexts/chatContext/ChatContext.tsx +5 -1
  168. package/src/contexts/messageContext/MessageContext.tsx +7 -4
  169. package/src/contexts/messageInputContext/MessageInputContext.tsx +127 -96
  170. package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +2 -2
  171. package/src/contexts/themeContext/utils/theme.ts +1 -0
  172. package/src/i18n/en.json +2 -0
  173. package/src/i18n/fr.json +2 -0
  174. package/src/i18n/hi.json +2 -0
  175. package/src/i18n/it.json +2 -0
  176. package/src/i18n/ja.json +3 -1
  177. package/src/i18n/ko.json +3 -1
  178. package/src/i18n/nl.json +2 -0
  179. package/src/i18n/ru.json +2 -0
  180. package/src/i18n/tr.json +2 -0
  181. package/src/icons/Warning.tsx +12 -0
  182. package/src/icons/index.ts +1 -0
  183. package/src/utils/utils.ts +53 -1
  184. package/src/version.json +1 -1
  185. package/src/components/MessageInput/__tests__/__snapshots__/FileUploadPreview.test.js.snap +0 -4413
  186. package/src/components/MessageInput/__tests__/__snapshots__/ImageUploadPreview.test.js.snap +0 -2373
@@ -5,6 +5,7 @@ import Dayjs from 'dayjs';
5
5
 
6
6
  import type { Channel } from 'stream-chat';
7
7
 
8
+ import { useAppSettings } from './hooks/useAppSettings';
8
9
  import { useCreateChatContext } from './hooks/useCreateChatContext';
9
10
  import { useIsOnline } from './hooks/useIsOnline';
10
11
  import { useMutedUsers } from './hooks/useMutedUsers';
@@ -161,7 +162,10 @@ const ChatWithContext = <
161
162
 
162
163
  const setActiveChannel = (newChannel?: Channel<StreamChatGenerics>) => setChannel(newChannel);
163
164
 
165
+ const appSettings = useAppSettings(client, isOnline);
166
+
164
167
  const chatContext = useCreateChatContext({
168
+ appSettings,
165
169
  channel,
166
170
  client,
167
171
  connectionRecovering,
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { Text } from 'react-native';
3
+
4
+ import { render, waitFor } from '@testing-library/react-native';
5
+
6
+ import type { StreamChat } from 'stream-chat';
7
+
8
+ import { useAppSettings } from '../useAppSettings';
9
+
10
+ describe('useAppSettings', () => {
11
+ it('will return a settings object if the backend call is successful', async () => {
12
+ const TestComponent = () => {
13
+ const isOnline = true;
14
+ const appSettings = useAppSettings(
15
+ {
16
+ getAppSettings: jest.fn().mockReturnValue(
17
+ Promise.resolve({
18
+ auto_translation_enabled: true,
19
+ }),
20
+ ),
21
+ } as unknown as StreamChat,
22
+ isOnline,
23
+ );
24
+
25
+ return <Text>{JSON.stringify(appSettings)}</Text>;
26
+ };
27
+
28
+ const { getByText } = render(<TestComponent />);
29
+
30
+ await waitFor(() => {
31
+ expect(getByText(JSON.stringify({ auto_translation_enabled: true }))).toBeTruthy();
32
+ });
33
+ });
34
+ });
@@ -0,0 +1,39 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+
3
+ import type { AppSettingsAPIResponse, StreamChat } from 'stream-chat';
4
+ import type { DefaultStreamChatGenerics } from 'stream-chat-react-native';
5
+
6
+ export const useAppSettings = <
7
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
8
+ >(
9
+ client: StreamChat<StreamChatGenerics>,
10
+ isOnline: boolean,
11
+ ): AppSettingsAPIResponse | null => {
12
+ const [appSettings, setAppSettings] = useState<AppSettingsAPIResponse | null>(null);
13
+ const isMounted = useRef(true);
14
+
15
+ useEffect(() => {
16
+ async function getAppSettings() {
17
+ try {
18
+ const appSettings = await client.getAppSettings();
19
+ if (isMounted.current) {
20
+ setAppSettings(appSettings);
21
+ }
22
+ } catch (error: unknown) {
23
+ if (error instanceof Error) {
24
+ console.error(`An error occurred while getting app settings: ${error}`);
25
+ }
26
+ }
27
+ }
28
+
29
+ if (isOnline) {
30
+ getAppSettings();
31
+ }
32
+
33
+ return () => {
34
+ isMounted.current = false;
35
+ };
36
+ }, [client, isOnline]);
37
+
38
+ return appSettings;
39
+ };
@@ -6,6 +6,7 @@ import type { DefaultStreamChatGenerics } from '../../../types/types';
6
6
  export const useCreateChatContext = <
7
7
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
8
8
  >({
9
+ appSettings,
9
10
  channel,
10
11
  client,
11
12
  connectionRecovering,
@@ -21,6 +22,7 @@ export const useCreateChatContext = <
21
22
 
22
23
  const chatContext: ChatContextValue<StreamChatGenerics> = useMemo(
23
24
  () => ({
25
+ appSettings,
24
26
  channel,
25
27
  client,
26
28
  connectionRecovering,
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { GestureResponderEvent, Keyboard, StyleProp, View, ViewStyle } from 'react-native';
3
3
 
4
- import type { Attachment } from 'stream-chat';
4
+ import type { Attachment, UserResponse } from 'stream-chat';
5
5
 
6
6
  import { useCreateMessageContext } from './hooks/useCreateMessageContext';
7
7
  import { useMessageActionHandlers } from './hooks/useMessageActionHandlers';
@@ -52,21 +52,34 @@ import {
52
52
  } from '../MessageList/hooks/useMessageList';
53
53
  import type { MessageActionListItemProps } from '../MessageOverlay/MessageActionListItem';
54
54
 
55
+ export type TouchableEmitter =
56
+ | 'card'
57
+ | 'fileAttachment'
58
+ | 'gallery'
59
+ | 'giphy'
60
+ | 'message'
61
+ | 'messageContent'
62
+ | 'messageReplies'
63
+ | 'reactionList'
64
+ | 'textLink';
65
+
66
+ export type TextMentionTouchableHandlerPayload<
67
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
68
+ > = {
69
+ emitter: 'textMention';
70
+ additionalInfo?: { user?: UserResponse<StreamChatGenerics> };
71
+ };
72
+
55
73
  export type TouchableHandlerPayload = {
56
74
  defaultHandler?: () => void;
57
- emitter?:
58
- | 'card'
59
- | 'fileAttachment'
60
- | 'gallery'
61
- | 'giphy'
62
- | 'message'
63
- | 'messageContent'
64
- | 'messageReplies'
65
- | 'reactionList'
66
- | 'textLink'
67
- | 'textMention';
68
75
  event?: GestureResponderEvent;
69
- };
76
+ } & (
77
+ | {
78
+ additionalInfo?: Record<string, unknown>;
79
+ emitter?: TouchableEmitter;
80
+ }
81
+ | TextMentionTouchableHandlerPayload
82
+ );
70
83
 
71
84
  export type MessageTouchableHandlerPayload<
72
85
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -595,45 +608,40 @@ const MessageWithContext = <
595
608
  onlyEmojis,
596
609
  onOpenThread,
597
610
  onPress: (payload) => {
598
- onPressProp
599
- ? onPressProp({
600
- actionHandlers,
601
- defaultHandler: payload.defaultHandler || onPress,
602
- emitter: payload.emitter || 'message',
603
- event: payload.event,
604
- message,
605
- })
606
- : onPressMessageProp
607
- ? onPressMessageProp({
608
- actionHandlers,
609
- defaultHandler: payload.defaultHandler || onPress,
610
- emitter: payload.emitter || 'message',
611
- event: payload.event,
612
- message,
613
- })
614
- : payload.defaultHandler
615
- ? payload.defaultHandler()
616
- : onPress();
611
+ const onPressArgs = {
612
+ actionHandlers,
613
+ additionalInfo: payload.additionalInfo,
614
+ defaultHandler: payload.defaultHandler || onPress,
615
+ emitter: payload.emitter || 'message',
616
+ event: payload.event,
617
+ message,
618
+ };
619
+
620
+ const handleOnPress = () => {
621
+ if (onPressProp) return onPressProp(onPressArgs);
622
+ if (onPressMessageProp) return onPressMessageProp(onPressArgs);
623
+ if (payload.defaultHandler) return payload.defaultHandler();
624
+
625
+ return onPress();
626
+ };
627
+
628
+ handleOnPress();
617
629
  },
618
630
  onPressIn:
619
631
  onPressInProp || onPressInMessageProp
620
632
  ? (payload) => {
621
- onPressInProp
622
- ? onPressInProp({
623
- actionHandlers,
624
- defaultHandler: payload.defaultHandler,
625
- emitter: payload.emitter || 'message',
626
- event: payload.event,
627
- message,
628
- })
629
- : onPressInMessageProp &&
630
- onPressInMessageProp({
631
- actionHandlers,
632
- defaultHandler: payload.defaultHandler,
633
- emitter: payload.emitter || 'message',
634
- event: payload.event,
635
- message,
636
- });
633
+ const onPressInArgs = {
634
+ actionHandlers,
635
+ defaultHandler: payload.defaultHandler,
636
+ emitter: payload.emitter || 'message',
637
+ event: payload.event,
638
+ message,
639
+ };
640
+ const handleOnpressIn = () => {
641
+ if (onPressInProp) return onPressInProp(onPressInArgs);
642
+ if (onPressInMessageProp) return onPressInMessageProp(onPressInArgs);
643
+ };
644
+ handleOnpressIn();
637
645
  }
638
646
  : null,
639
647
  otherAttachments: attachments.other,
@@ -17,6 +17,8 @@ import {
17
17
  State,
18
18
  } from 'simple-markdown';
19
19
 
20
+ import type { UserResponse } from 'stream-chat';
21
+
20
22
  import { parseLinksFromText } from './parseLinks';
21
23
 
22
24
  import type { MessageContextValue } from '../../../../contexts/messageContext/MessageContext';
@@ -147,10 +149,16 @@ export const renderText = <
147
149
  },
148
150
  };
149
151
 
150
- const onLink = (url: string) =>
151
- onLinkParams
152
+ const onLink = (url: string) => {
153
+ const pattern = new RegExp(/^\S+:\/\//);
154
+ if (!pattern.test(url)) {
155
+ url = 'http://' + url;
156
+ }
157
+
158
+ return onLinkParams
152
159
  ? onLinkParams(url)
153
160
  : Linking.canOpenURL(url).then((canOpenUrl) => canOpenUrl && Linking.openURL(url));
161
+ };
154
162
 
155
163
  const link: ReactNodeOutput = (node, output, { ...state }) => {
156
164
  const onPress = (event: GestureResponderEvent) => {
@@ -205,9 +213,16 @@ export const renderText = <
205
213
  const match: MatchFunction = (source) => regEx.exec(source);
206
214
 
207
215
  const mentionsReact: ReactNodeOutput = (node, output, { ...state }) => {
216
+ /**removes the @ prefix of username */
217
+ const userName = node.content[0]?.content?.substring(1);
208
218
  const onPress = (event: GestureResponderEvent) => {
209
219
  if (!preventPress && onPressParam) {
210
220
  onPressParam({
221
+ additionalInfo: {
222
+ user: mentioned_users?.find(
223
+ (user: UserResponse<StreamChatGenerics>) => userName === user.name,
224
+ ),
225
+ },
211
226
  emitter: 'textMention',
212
227
  event,
213
228
  });
@@ -13,13 +13,15 @@ import {
13
13
  useMessagesContext,
14
14
  } from '../../contexts/messagesContext/MessagesContext';
15
15
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
16
+ import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
16
17
  import { Close } from '../../icons/Close';
18
+ import { Warning } from '../../icons/Warning';
17
19
  import type { DefaultStreamChatGenerics } from '../../types/types';
18
- import { FileState, ProgressIndicatorTypes } from '../../utils/utils';
19
-
20
+ import { getIndicatorTypeForFileState, ProgressIndicatorTypes } from '../../utils/utils';
20
21
  import { getFileSizeDisplayText } from '../Attachment/FileAttachment';
21
22
 
22
23
  const FILE_PREVIEW_HEIGHT = 60;
24
+ const WARNING_ICON_SIZE = 16;
23
25
 
24
26
  const styles = StyleSheet.create({
25
27
  dismiss: {
@@ -59,8 +61,55 @@ const styles = StyleSheet.create({
59
61
  marginLeft: 8,
60
62
  marginRight: 8,
61
63
  },
64
+ unsupportedFile: {
65
+ flexDirection: 'row',
66
+ paddingLeft: 10,
67
+ },
68
+ unsupportedFileText: {
69
+ fontSize: 16,
70
+ },
71
+ warningIconStyle: {
72
+ borderRadius: 24,
73
+ marginTop: 4,
74
+ },
62
75
  });
63
76
 
77
+ const UnsupportedFileTypeOrFileSizeIndicator = ({
78
+ indicatorType,
79
+ item,
80
+ }: {
81
+ indicatorType: typeof ProgressIndicatorTypes[keyof typeof ProgressIndicatorTypes];
82
+ item: FileUpload;
83
+ }) => {
84
+ const {
85
+ theme: {
86
+ colors: { accent_red, grey },
87
+ messageInput: {
88
+ fileUploadPreview: { fileSizeText },
89
+ },
90
+ },
91
+ } = useTheme();
92
+
93
+ const { t } = useTranslationContext();
94
+ return indicatorType === ProgressIndicatorTypes.NOT_SUPPORTED ? (
95
+ <View style={styles.unsupportedFile}>
96
+ <Warning
97
+ height={WARNING_ICON_SIZE}
98
+ pathFill={accent_red}
99
+ style={styles.warningIconStyle}
100
+ width={WARNING_ICON_SIZE}
101
+ />
102
+ <Text style={[styles.unsupportedFileText, { color: grey }]}>
103
+ {t('File type not supported')}
104
+ </Text>
105
+ </View>
106
+ ) : (
107
+ <Text style={[styles.fileSizeText, { color: grey }, fileSizeText]}>
108
+ {getFileSizeDisplayText(item.file.size)}
109
+ </Text>
110
+ );
111
+ };
112
+
64
113
  type FileUploadPreviewPropsWithContext<
65
114
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
66
115
  > = Pick<
@@ -81,14 +130,13 @@ const FileUploadPreviewWithContext = <
81
130
 
82
131
  const {
83
132
  theme: {
84
- colors: { black, grey, grey_whisper, overlay },
133
+ colors: { black, grey_whisper, overlay },
85
134
  messageInput: {
86
135
  fileUploadPreview: {
87
136
  dismiss,
88
137
  fileContainer,
89
138
  fileContentContainer,
90
139
  filenameText,
91
- fileSizeText,
92
140
  fileTextContainer,
93
141
  flatList,
94
142
  },
@@ -97,12 +145,7 @@ const FileUploadPreviewWithContext = <
97
145
  } = useTheme();
98
146
 
99
147
  const renderItem = ({ index, item }: { index: number; item: FileUpload }) => {
100
- const indicatorType =
101
- item.state === FileState.UPLOADING
102
- ? ProgressIndicatorTypes.IN_PROGRESS
103
- : item.state === FileState.UPLOAD_FAILED
104
- ? ProgressIndicatorTypes.RETRY
105
- : undefined;
148
+ const indicatorType = getIndicatorTypeForFileState(item.state);
106
149
 
107
150
  return (
108
151
  <>
@@ -110,7 +153,6 @@ const FileUploadPreviewWithContext = <
110
153
  action={() => {
111
154
  uploadFile({ newFile: item });
112
155
  }}
113
- active={item.state !== FileState.UPLOADED && item.state !== FileState.FINISHED}
114
156
  style={styles.overlay}
115
157
  type={indicatorType}
116
158
  >
@@ -150,9 +192,12 @@ const FileUploadPreviewWithContext = <
150
192
  >
151
193
  {item.file.name || ''}
152
194
  </Text>
153
- <Text style={[styles.fileSizeText, { color: grey }, fileSizeText]}>
154
- {getFileSizeDisplayText(item.file.size)}
155
- </Text>
195
+ {indicatorType !== null && (
196
+ <UnsupportedFileTypeOrFileSizeIndicator
197
+ indicatorType={indicatorType}
198
+ item={item}
199
+ />
200
+ )}
156
201
  </View>
157
202
  </View>
158
203
  </View>
@@ -235,6 +280,7 @@ export const FileUploadPreview = <
235
280
  props: FileUploadPreviewProps<StreamChatGenerics>,
236
281
  ) => {
237
282
  const { fileUploads, removeFile, uploadFile } = useMessageInputContext<StreamChatGenerics>();
283
+
238
284
  const { FileAttachmentIcon } = useMessagesContext<StreamChatGenerics>();
239
285
 
240
286
  return (
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { FlatList, Image, StyleSheet, TouchableOpacity, View } from 'react-native';
2
+ import { FlatList, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3
3
 
4
4
  import { UploadProgressIndicator } from './UploadProgressIndicator';
5
5
 
@@ -9,11 +9,14 @@ import {
9
9
  useMessageInputContext,
10
10
  } from '../../contexts/messageInputContext/MessageInputContext';
11
11
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
12
+ import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
12
13
  import { Close } from '../../icons/Close';
14
+ import { Warning } from '../../icons/Warning';
13
15
  import type { DefaultStreamChatGenerics } from '../../types/types';
14
- import { FileState, ProgressIndicatorTypes } from '../../utils/utils';
16
+ import { getIndicatorTypeForFileState, ProgressIndicatorTypes } from '../../utils/utils';
15
17
 
16
18
  const IMAGE_PREVIEW_SIZE = 100;
19
+ const WARNING_ICON_SIZE = 16;
17
20
 
18
21
  const styles = StyleSheet.create({
19
22
  dismiss: {
@@ -22,17 +25,45 @@ const styles = StyleSheet.create({
22
25
  right: 8,
23
26
  top: 8,
24
27
  },
28
+ fileSizeText: {
29
+ fontSize: 12,
30
+ paddingLeft: 10,
31
+ },
25
32
  flatList: { paddingBottom: 12 },
33
+ iconContainer: {
34
+ alignItems: 'center',
35
+ flexDirection: 'row',
36
+ justifyContent: 'center',
37
+ },
26
38
  itemContainer: {
27
39
  flexDirection: 'row',
28
40
  height: IMAGE_PREVIEW_SIZE,
29
41
  marginLeft: 8,
30
42
  },
43
+ unsupportedImage: {
44
+ borderRadius: 20,
45
+ bottom: 8,
46
+ flexDirection: 'row',
47
+ marginLeft: 3,
48
+ position: 'absolute',
49
+ },
31
50
  upload: {
32
51
  borderRadius: 10,
33
52
  height: IMAGE_PREVIEW_SIZE,
34
53
  width: IMAGE_PREVIEW_SIZE,
35
54
  },
55
+ warningIconStyle: {
56
+ borderRadius: 24,
57
+ marginLeft: 4,
58
+ marginTop: 4,
59
+ },
60
+ warningText: {
61
+ alignItems: 'center',
62
+ color: 'black',
63
+ fontSize: 10,
64
+ justifyContent: 'center',
65
+ paddingRight: 8,
66
+ },
36
67
  });
37
68
 
38
69
  type ImageUploadPreviewPropsWithContext<
@@ -46,6 +77,8 @@ export type ImageUploadPreviewProps<
46
77
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
47
78
  > = Partial<ImageUploadPreviewPropsWithContext<StreamChatGenerics>>;
48
79
 
80
+ type ImageUploadPreviewItem = { index: number; item: ImageUpload };
81
+
49
82
  const ImageUploadPreviewWithContext = <
50
83
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
51
84
  >(
@@ -55,52 +88,72 @@ const ImageUploadPreviewWithContext = <
55
88
 
56
89
  const {
57
90
  theme: {
58
- colors: { overlay, white },
91
+ colors: { overlay },
59
92
  messageInput: {
60
93
  imageUploadPreview: { dismiss, flatList, itemContainer, upload },
61
94
  },
62
95
  },
63
96
  } = useTheme();
64
97
 
65
- const renderItem = ({ index, item }: { index: number; item: ImageUpload }) => (
66
- <View
67
- style={[
68
- styles.itemContainer,
69
- index === imageUploads.length - 1 ? { marginRight: 8 } : {},
70
- itemContainer,
71
- ]}
72
- >
73
- <UploadProgressIndicator
74
- action={() => {
75
- uploadImage({ newImage: item });
76
- }}
77
- active={item.state !== FileState.UPLOADED && item.state !== FileState.FINISHED}
78
- style={styles.upload}
79
- type={
80
- item.state === FileState.UPLOADING
81
- ? ProgressIndicatorTypes.IN_PROGRESS
82
- : item.state === FileState.UPLOAD_FAILED
83
- ? ProgressIndicatorTypes.RETRY
84
- : undefined
85
- }
86
- >
87
- <Image
88
- resizeMode='cover'
89
- source={{ uri: item.file.uri || item.url }}
90
- style={[styles.upload, upload]}
91
- />
92
- </UploadProgressIndicator>
93
- <TouchableOpacity
94
- onPress={() => {
95
- removeImage(item.id);
96
- }}
97
- style={[styles.dismiss, { backgroundColor: overlay }, dismiss]}
98
- testID='remove-image-upload-preview'
99
- >
100
- <Close pathFill={white} />
101
- </TouchableOpacity>
102
- </View>
103
- );
98
+ const UnsupportedImageTypeIndicator = ({
99
+ indicatorType,
100
+ }: {
101
+ indicatorType: typeof ProgressIndicatorTypes[keyof typeof ProgressIndicatorTypes] | null;
102
+ }) => {
103
+ const {
104
+ theme: {
105
+ colors: { accent_red, overlay, white },
106
+ },
107
+ } = useTheme();
108
+
109
+ const { t } = useTranslationContext();
110
+ return indicatorType === ProgressIndicatorTypes.NOT_SUPPORTED ? (
111
+ <View style={[styles.unsupportedImage, { backgroundColor: overlay }]}>
112
+ <View style={[styles.iconContainer]}>
113
+ <Warning
114
+ height={WARNING_ICON_SIZE}
115
+ pathFill={accent_red}
116
+ style={styles.warningIconStyle}
117
+ width={WARNING_ICON_SIZE}
118
+ />
119
+ <Text style={[styles.warningText, { color: white }]}>{t('Not supported')}</Text>
120
+ </View>
121
+ </View>
122
+ ) : null;
123
+ };
124
+
125
+ const renderItem = ({ index, item }: ImageUploadPreviewItem) => {
126
+ const indicatorType = getIndicatorTypeForFileState(item.state);
127
+ const itemMarginForIndex = index === imageUploads.length - 1 ? { marginRight: 8 } : {};
128
+
129
+ return (
130
+ <View style={[styles.itemContainer, itemMarginForIndex, itemContainer]}>
131
+ <UploadProgressIndicator
132
+ action={() => {
133
+ uploadImage({ newImage: item });
134
+ }}
135
+ style={styles.upload}
136
+ type={indicatorType}
137
+ >
138
+ <Image
139
+ resizeMode='cover'
140
+ source={{ uri: item.file.uri || item.url }}
141
+ style={[styles.upload, upload]}
142
+ />
143
+ </UploadProgressIndicator>
144
+ <TouchableOpacity
145
+ onPress={() => {
146
+ removeImage(item.id);
147
+ }}
148
+ style={[styles.dismiss, { backgroundColor: overlay }, dismiss]}
149
+ testID='remove-image-upload-preview'
150
+ >
151
+ <Close />
152
+ </TouchableOpacity>
153
+ <UnsupportedImageTypeIndicator indicatorType={indicatorType} />
154
+ </View>
155
+ );
156
+ };
104
157
 
105
158
  return imageUploads.length > 0 ? (
106
159
  <FlatList