stream-chat-react-native-core 4.4.0-beta.2 → 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 (147) hide show
  1. package/README.md +2 -2
  2. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  3. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js +4 -12
  4. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  5. package/lib/commonjs/components/Channel/hooks/useCreateThreadContext.js +4 -12
  6. package/lib/commonjs/components/Channel/hooks/useCreateThreadContext.js.map +1 -1
  7. package/lib/commonjs/components/Chat/Chat.js +8 -4
  8. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  9. package/lib/commonjs/components/Chat/hooks/useAppSettings.js +80 -0
  10. package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -0
  11. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js +3 -1
  12. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  13. package/lib/commonjs/components/Message/Message.js +27 -22
  14. package/lib/commonjs/components/Message/Message.js.map +1 -1
  15. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js +22 -14
  16. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  17. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +108 -40
  18. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  19. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js +117 -24
  20. package/lib/commonjs/components/MessageInput/ImageUploadPreview.js.map +1 -1
  21. package/lib/commonjs/components/MessageInput/UploadProgressIndicator.js +52 -20
  22. package/lib/commonjs/components/MessageInput/UploadProgressIndicator.js.map +1 -1
  23. package/lib/commonjs/contexts/chatContext/ChatContext.js +2 -2
  24. package/lib/commonjs/contexts/chatContext/ChatContext.js.map +1 -1
  25. package/lib/commonjs/contexts/messageContext/MessageContext.js +2 -2
  26. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  27. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +145 -119
  28. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  29. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  30. package/lib/commonjs/i18n/en.json +2 -0
  31. package/lib/commonjs/i18n/fr.json +2 -0
  32. package/lib/commonjs/i18n/hi.json +2 -0
  33. package/lib/commonjs/i18n/it.json +2 -0
  34. package/lib/commonjs/i18n/ja.json +3 -1
  35. package/lib/commonjs/i18n/ko.json +3 -1
  36. package/lib/commonjs/i18n/nl.json +2 -0
  37. package/lib/commonjs/i18n/ru.json +2 -0
  38. package/lib/commonjs/i18n/tr.json +2 -0
  39. package/lib/commonjs/icons/Warning.js +38 -0
  40. package/lib/commonjs/icons/Warning.js.map +1 -0
  41. package/lib/commonjs/icons/index.js +13 -0
  42. package/lib/commonjs/icons/index.js.map +1 -1
  43. package/lib/commonjs/utils/utils.js +33 -2
  44. package/lib/commonjs/utils/utils.js.map +1 -1
  45. package/lib/commonjs/version.json +1 -1
  46. package/lib/module/components/Channel/Channel.js.map +1 -1
  47. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js +4 -12
  48. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  49. package/lib/module/components/Channel/hooks/useCreateThreadContext.js +4 -12
  50. package/lib/module/components/Channel/hooks/useCreateThreadContext.js.map +1 -1
  51. package/lib/module/components/Chat/Chat.js +8 -4
  52. package/lib/module/components/Chat/Chat.js.map +1 -1
  53. package/lib/module/components/Chat/hooks/useAppSettings.js +80 -0
  54. package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -0
  55. package/lib/module/components/Chat/hooks/useCreateChatContext.js +3 -1
  56. package/lib/module/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  57. package/lib/module/components/Message/Message.js +27 -22
  58. package/lib/module/components/Message/Message.js.map +1 -1
  59. package/lib/module/components/Message/MessageSimple/utils/renderText.js +22 -14
  60. package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
  61. package/lib/module/components/MessageInput/FileUploadPreview.js +108 -40
  62. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  63. package/lib/module/components/MessageInput/ImageUploadPreview.js +117 -24
  64. package/lib/module/components/MessageInput/ImageUploadPreview.js.map +1 -1
  65. package/lib/module/components/MessageInput/UploadProgressIndicator.js +52 -20
  66. package/lib/module/components/MessageInput/UploadProgressIndicator.js.map +1 -1
  67. package/lib/module/contexts/chatContext/ChatContext.js +2 -2
  68. package/lib/module/contexts/chatContext/ChatContext.js.map +1 -1
  69. package/lib/module/contexts/messageContext/MessageContext.js +2 -2
  70. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  71. package/lib/module/contexts/messageInputContext/MessageInputContext.js +145 -119
  72. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  73. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  74. package/lib/module/i18n/en.json +2 -0
  75. package/lib/module/i18n/fr.json +2 -0
  76. package/lib/module/i18n/hi.json +2 -0
  77. package/lib/module/i18n/it.json +2 -0
  78. package/lib/module/i18n/ja.json +3 -1
  79. package/lib/module/i18n/ko.json +3 -1
  80. package/lib/module/i18n/nl.json +2 -0
  81. package/lib/module/i18n/ru.json +2 -0
  82. package/lib/module/i18n/tr.json +2 -0
  83. package/lib/module/icons/Warning.js +38 -0
  84. package/lib/module/icons/Warning.js.map +1 -0
  85. package/lib/module/icons/index.js +13 -0
  86. package/lib/module/icons/index.js.map +1 -1
  87. package/lib/module/utils/utils.js +33 -2
  88. package/lib/module/utils/utils.js.map +1 -1
  89. package/lib/module/version.json +1 -1
  90. package/lib/typescript/components/Chat/hooks/__tests__/useAppSettings.test.d.ts +1 -0
  91. package/lib/typescript/components/Chat/hooks/useAppSettings.d.ts +3 -0
  92. package/lib/typescript/components/Chat/hooks/useCreateChatContext.d.ts +1 -1
  93. package/lib/typescript/components/Message/Message.d.ts +12 -2
  94. package/lib/typescript/components/MessageInput/UploadProgressIndicator.d.ts +1 -3
  95. package/lib/typescript/contexts/chatContext/ChatContext.d.ts +5 -1
  96. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +4 -4
  97. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +3 -3
  98. package/lib/typescript/i18n/en.json +2 -0
  99. package/lib/typescript/i18n/fr.json +2 -0
  100. package/lib/typescript/i18n/hi.json +2 -0
  101. package/lib/typescript/i18n/it.json +2 -0
  102. package/lib/typescript/i18n/ja.json +3 -1
  103. package/lib/typescript/i18n/ko.json +3 -1
  104. package/lib/typescript/i18n/nl.json +2 -0
  105. package/lib/typescript/i18n/ru.json +2 -0
  106. package/lib/typescript/i18n/tr.json +2 -0
  107. package/lib/typescript/icons/Warning.d.ts +3 -0
  108. package/lib/typescript/icons/index.d.ts +1 -0
  109. package/lib/typescript/utils/Streami18n.d.ts +6 -0
  110. package/lib/typescript/utils/utils.d.ts +15 -2
  111. package/package.json +1 -1
  112. package/src/components/Channel/Channel.tsx +1 -1
  113. package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts +3 -9
  114. package/src/components/Channel/hooks/useCreateThreadContext.ts +3 -9
  115. package/src/components/ChannelList/hooks/listeners/__tests__/useChannelUpdated.test.tsx +1 -0
  116. package/src/components/Chat/Chat.tsx +4 -0
  117. package/src/components/Chat/hooks/__tests__/useAppSettings.test.tsx +34 -0
  118. package/src/components/Chat/hooks/useAppSettings.ts +39 -0
  119. package/src/components/Chat/hooks/useCreateChatContext.ts +2 -0
  120. package/src/components/Message/Message.tsx +56 -48
  121. package/src/components/Message/MessageSimple/utils/renderText.tsx +9 -0
  122. package/src/components/MessageInput/FileUploadPreview.tsx +60 -14
  123. package/src/components/MessageInput/ImageUploadPreview.tsx +95 -42
  124. package/src/components/MessageInput/UploadProgressIndicator.tsx +49 -22
  125. package/src/components/MessageInput/__tests__/FileUploadPreview.test.js +50 -80
  126. package/src/components/MessageInput/__tests__/ImageUploadPreview.test.js +49 -74
  127. package/src/components/MessageInput/__tests__/UploadProgressIndicator.test.js +36 -13
  128. package/src/components/MessageInput/__tests__/__snapshots__/UploadProgressIndicator.test.js.snap +122 -17
  129. package/src/contexts/chatContext/ChatContext.tsx +5 -1
  130. package/src/contexts/messageContext/MessageContext.tsx +7 -4
  131. package/src/contexts/messageInputContext/MessageInputContext.tsx +127 -96
  132. package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +2 -2
  133. package/src/i18n/en.json +2 -0
  134. package/src/i18n/fr.json +2 -0
  135. package/src/i18n/hi.json +2 -0
  136. package/src/i18n/it.json +2 -0
  137. package/src/i18n/ja.json +3 -1
  138. package/src/i18n/ko.json +3 -1
  139. package/src/i18n/nl.json +2 -0
  140. package/src/i18n/ru.json +2 -0
  141. package/src/i18n/tr.json +2 -0
  142. package/src/icons/Warning.tsx +12 -0
  143. package/src/icons/index.ts +1 -0
  144. package/src/utils/utils.ts +53 -1
  145. package/src/version.json +1 -1
  146. package/src/components/MessageInput/__tests__/__snapshots__/FileUploadPreview.test.js.snap +0 -4413
  147. package/src/components/MessageInput/__tests__/__snapshots__/ImageUploadPreview.test.js.snap +0 -2373
@@ -73,6 +73,7 @@ export * from './User';
73
73
  export * from './UserAdd';
74
74
  export * from './UserDelete';
75
75
  export * from './UserMinus';
76
+ export * from './Warning';
76
77
  export * from './WutReaction';
77
78
  export * from './XLS';
78
79
  export * from './XLSX';
@@ -131,6 +131,7 @@ export declare class Streami18n {
131
131
  "Error loading channel list...": string;
132
132
  "Error loading messages for this channel...": string;
133
133
  "Error while loading, please reload/refresh": string;
134
+ "File type not supported": string;
134
135
  Flag: string;
135
136
  "Flag Message": string;
136
137
  "Flag action failed either due to a network issue or the message is already flagged": string;
@@ -143,6 +144,7 @@ export declare class Streami18n {
143
144
  "Message deleted": string;
144
145
  "Message flagged": string;
145
146
  "Mute User": string;
147
+ "Not supported": string;
146
148
  "Nothing yet...": string;
147
149
  Ok: string;
148
150
  "Only visible to you": string;
@@ -152,6 +154,10 @@ export declare class Streami18n {
152
154
  "Please enable access to your photos and videos so you can share them.": string;
153
155
  "Please select a channel first": string;
154
156
  "Reconnecting...": string;
157
+ /**
158
+ * Hindi notation for meridiems are quite fuzzy in practice. While there exists
159
+ * a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
160
+ */
155
161
  Reply: string;
156
162
  "Reply to Message": string;
157
163
  Resend: string;
@@ -1,6 +1,6 @@
1
1
  import type React from 'react';
2
2
  import type { DebouncedFunc } from 'lodash';
3
- import type { Channel, CommandResponse, StreamChat } from 'stream-chat';
3
+ import type { Channel, CommandResponse, FormatMessageResponse, StreamChat } from 'stream-chat';
4
4
  import type { MentionAllAppUsersQuery } from '../contexts/messageInputContext/MessageInputContext';
5
5
  import type { SuggestionCommand, SuggestionComponentType, SuggestionUser } from '../contexts/suggestionsContext/SuggestionsContext';
6
6
  import { Emoji } from '../emoji-data/compiled';
@@ -12,13 +12,15 @@ export declare type ReactionData = {
12
12
  };
13
13
  export declare const FileState: Readonly<{
14
14
  FINISHED: string;
15
- NO_FILE: string;
15
+ NOT_SUPPORTED: string;
16
16
  UPLOAD_FAILED: string;
17
17
  UPLOADED: string;
18
18
  UPLOADING: string;
19
19
  }>;
20
20
  export declare const ProgressIndicatorTypes: {
21
21
  IN_PROGRESS: 'in_progress';
22
+ INACTIVE: 'inactive';
23
+ NOT_SUPPORTED: 'not_supported';
22
24
  RETRY: 'retry';
23
25
  };
24
26
  export declare const MessageStatusTypes: {
@@ -26,6 +28,10 @@ export declare const MessageStatusTypes: {
26
28
  RECEIVED: string;
27
29
  SENDING: string;
28
30
  };
31
+ export declare type FileStateValue = typeof FileState[keyof typeof FileState];
32
+ declare type ValueOf<T> = T[keyof T];
33
+ declare type Progress = ValueOf<typeof ProgressIndicatorTypes>;
34
+ export declare const getIndicatorTypeForFileState: (fileState: FileStateValue) => Progress | null;
29
35
  export declare const queryMembersDebounced: DebouncedFunc<(<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(channel: Channel<StreamChatGenerics>, query: SuggestionUser<StreamChatGenerics>["name"], onReady?: ((users: SuggestionUser<StreamChatGenerics>[]) => void) | undefined, options?: {
30
36
  limit?: number;
31
37
  }) => Promise<void>)>;
@@ -104,3 +110,10 @@ export declare const vh: (percentageHeight: number, rounded?: boolean) => number
104
110
  export declare const generateRandomId: (a?: string) => string;
105
111
  export declare const emojiRegex: RegExp;
106
112
  export declare const urlRegex: RegExp;
113
+ /**
114
+ * Reduces a list of messages to strings that are used in useEffect & useMemo
115
+ * @param {messages} messages - the array of messages to be compared
116
+ * @returns {string} The mapped message string
117
+ */
118
+ export declare const reduceMessagesToString: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(messages: FormatMessageResponse<StreamChatGenerics>[]) => string;
119
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stream-chat-react-native-core",
3
3
  "description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
4
- "version": "4.4.0-beta.2",
4
+ "version": "4.4.0-beta.3",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -1606,7 +1606,7 @@ const ChannelWithContext = <
1606
1606
  watchers,
1607
1607
  });
1608
1608
 
1609
- const inputMessageInputContext = useCreateInputMessageInputContext({
1609
+ const inputMessageInputContext = useCreateInputMessageInputContext<StreamChatGenerics>({
1610
1610
  additionalTextInputProps,
1611
1611
  AttachButton,
1612
1612
  autoCompleteSuggestionsLimit,
@@ -2,6 +2,7 @@ import { useMemo } from 'react';
2
2
 
3
3
  import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext';
4
4
  import type { DefaultStreamChatGenerics } from '../../../types/types';
5
+ import { reduceMessagesToString } from '../../../utils/utils';
5
6
 
6
7
  export const useCreatePaginatedMessageListContext = <
7
8
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -18,14 +19,7 @@ export const useCreatePaginatedMessageListContext = <
18
19
  }: PaginatedMessageListContextValue<StreamChatGenerics> & {
19
20
  channelId?: string;
20
21
  }) => {
21
- const messagesUpdated = messages
22
- .map(
23
- ({ deleted_at, latest_reactions, reply_count, status, updated_at }) =>
24
- `${deleted_at}${
25
- latest_reactions ? latest_reactions.map(({ type }) => type).join() : ''
26
- }${reply_count}${status}${updated_at?.toISOString?.() || updated_at}`,
27
- )
28
- .join();
22
+ const messagesStr = reduceMessagesToString(messages);
29
23
 
30
24
  const paginatedMessagesContext: PaginatedMessageListContextValue<StreamChatGenerics> = useMemo(
31
25
  () => ({
@@ -38,7 +32,7 @@ export const useCreatePaginatedMessageListContext = <
38
32
  setLoadingMore,
39
33
  setLoadingMoreRecent,
40
34
  }),
41
- [channelId, hasMore, loadingMoreRecent, loadingMore, messagesUpdated],
35
+ [channelId, hasMore, loadingMoreRecent, loadingMore, messagesStr],
42
36
  );
43
37
 
44
38
  return paginatedMessagesContext;
@@ -2,6 +2,7 @@ import { useMemo } from 'react';
2
2
 
3
3
  import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext';
4
4
  import type { DefaultStreamChatGenerics } from '../../../types/types';
5
+ import { reduceMessagesToString } from '../../../utils/utils';
5
6
 
6
7
  export const useCreateThreadContext = <
7
8
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -19,14 +20,7 @@ export const useCreateThreadContext = <
19
20
  }: ThreadContextValue<StreamChatGenerics>) => {
20
21
  const threadId = thread?.id;
21
22
  const threadReplyCount = thread?.reply_count;
22
- const threadMessagesUpdated = threadMessages
23
- .map(
24
- ({ deleted_at, latest_reactions, reply_count, status, updated_at }) =>
25
- `${deleted_at}${
26
- latest_reactions ? latest_reactions.map(({ type }) => type).join() : ''
27
- }${reply_count}${status}${updated_at.toISOString()}`,
28
- )
29
- .join();
23
+ const threadMessagesStr = reduceMessagesToString(threadMessages);
30
24
 
31
25
  const threadContext: ThreadContextValue<StreamChatGenerics> = useMemo(
32
26
  () => ({
@@ -46,7 +40,7 @@ export const useCreateThreadContext = <
46
40
  threadHasMore,
47
41
  threadId,
48
42
  threadLoadingMore,
49
- threadMessagesUpdated,
43
+ threadMessagesStr,
50
44
  threadReplyCount,
51
45
  ],
52
46
  );
@@ -55,6 +55,7 @@ describe('useChannelUpdated', () => {
55
55
  render(
56
56
  <ChatContext.Provider
57
57
  value={{
58
+ appSettings: null,
58
59
  client: mockClient,
59
60
  connectionRecovering: false,
60
61
  isOnline: true,
@@ -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';
@@ -211,9 +213,16 @@ export const renderText = <
211
213
  const match: MatchFunction = (source) => regEx.exec(source);
212
214
 
213
215
  const mentionsReact: ReactNodeOutput = (node, output, { ...state }) => {
216
+ /**removes the @ prefix of username */
217
+ const userName = node.content[0]?.content?.substring(1);
214
218
  const onPress = (event: GestureResponderEvent) => {
215
219
  if (!preventPress && onPressParam) {
216
220
  onPressParam({
221
+ additionalInfo: {
222
+ user: mentioned_users?.find(
223
+ (user: UserResponse<StreamChatGenerics>) => userName === user.name,
224
+ ),
225
+ },
217
226
  emitter: 'textMention',
218
227
  event,
219
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 (