stream-chat-react-native-core 9.0.0-beta.32 → 9.0.0-beta.34

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 (96) hide show
  1. package/lib/commonjs/components/Attachment/Giphy/Giphy.js +5 -3
  2. package/lib/commonjs/components/Attachment/Giphy/Giphy.js.map +1 -1
  3. package/lib/commonjs/components/Channel/Channel.js +0 -3
  4. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  5. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +0 -2
  6. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  7. package/lib/commonjs/components/ChannelList/ChannelListView.js +6 -6
  8. package/lib/commonjs/components/ChannelList/ChannelListView.js.map +1 -1
  9. package/lib/commonjs/components/ChannelPreview/ChannelPreview.js +3 -3
  10. package/lib/commonjs/components/ChannelPreview/ChannelPreview.js.map +1 -1
  11. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessage.js +9 -9
  12. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessage.js.map +1 -1
  13. package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js +13 -13
  14. package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
  15. package/lib/commonjs/components/Message/MessageItemView/MessageItemView.js +5 -2
  16. package/lib/commonjs/components/Message/MessageItemView/MessageItemView.js.map +1 -1
  17. package/lib/commonjs/components/MessageList/hooks/useMessageList.js +2 -35
  18. package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
  19. package/lib/commonjs/contexts/channelsContext/ChannelsContext.js.map +1 -1
  20. package/lib/commonjs/contexts/componentsContext/PLAN.md +15 -15
  21. package/lib/commonjs/contexts/componentsContext/defaultComponents.js +14 -13
  22. package/lib/commonjs/contexts/componentsContext/defaultComponents.js.map +1 -1
  23. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  24. package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js +30 -22
  25. package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
  26. package/lib/commonjs/version.json +1 -1
  27. package/lib/module/components/Attachment/Giphy/Giphy.js +5 -3
  28. package/lib/module/components/Attachment/Giphy/Giphy.js.map +1 -1
  29. package/lib/module/components/Channel/Channel.js +0 -3
  30. package/lib/module/components/Channel/Channel.js.map +1 -1
  31. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +0 -2
  32. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  33. package/lib/module/components/ChannelList/ChannelListView.js +6 -6
  34. package/lib/module/components/ChannelList/ChannelListView.js.map +1 -1
  35. package/lib/module/components/ChannelPreview/ChannelPreview.js +3 -3
  36. package/lib/module/components/ChannelPreview/ChannelPreview.js.map +1 -1
  37. package/lib/module/components/ChannelPreview/ChannelPreviewMessage.js +9 -9
  38. package/lib/module/components/ChannelPreview/ChannelPreviewMessage.js.map +1 -1
  39. package/lib/module/components/ChannelPreview/ChannelPreviewView.js +13 -13
  40. package/lib/module/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
  41. package/lib/module/components/Message/MessageItemView/MessageItemView.js +5 -2
  42. package/lib/module/components/Message/MessageItemView/MessageItemView.js.map +1 -1
  43. package/lib/module/components/MessageList/hooks/useMessageList.js +2 -35
  44. package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
  45. package/lib/module/contexts/channelsContext/ChannelsContext.js.map +1 -1
  46. package/lib/module/contexts/componentsContext/PLAN.md +15 -15
  47. package/lib/module/contexts/componentsContext/defaultComponents.js +14 -13
  48. package/lib/module/contexts/componentsContext/defaultComponents.js.map +1 -1
  49. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  50. package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js +30 -22
  51. package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
  52. package/lib/module/version.json +1 -1
  53. package/lib/typescript/components/Channel/Channel.d.ts +1 -1
  54. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  55. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
  56. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
  57. package/lib/typescript/components/ChannelList/ChannelListView.d.ts.map +1 -1
  58. package/lib/typescript/components/ChannelPreview/ChannelPreviewMessage.d.ts.map +1 -1
  59. package/lib/typescript/components/ChannelPreview/ChannelPreviewView.d.ts.map +1 -1
  60. package/lib/typescript/components/Message/MessageItemView/MessageItemView.d.ts.map +1 -1
  61. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts +0 -5
  62. package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
  63. package/lib/typescript/contexts/channelsContext/ChannelsContext.d.ts +2 -1
  64. package/lib/typescript/contexts/channelsContext/ChannelsContext.d.ts.map +1 -1
  65. package/lib/typescript/contexts/componentsContext/ComponentsContext.d.ts +14 -13
  66. package/lib/typescript/contexts/componentsContext/ComponentsContext.d.ts.map +1 -1
  67. package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts +15 -13
  68. package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts.map +1 -1
  69. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +0 -8
  70. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
  71. package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts +7 -0
  72. package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts.map +1 -1
  73. package/package.json +1 -1
  74. package/src/__tests__/offline-support/offline-feature.js +12 -4
  75. package/src/components/Attachment/Giphy/Giphy.tsx +11 -6
  76. package/src/components/Attachment/__tests__/Giphy.test.js +25 -0
  77. package/src/components/Channel/Channel.tsx +0 -3
  78. package/src/components/Channel/hooks/useCreateMessagesContext.ts +0 -2
  79. package/src/components/ChannelList/ChannelListView.tsx +6 -5
  80. package/src/components/ChannelList/__tests__/ChannelList.test.js +35 -35
  81. package/src/components/ChannelPreview/ChannelPreview.tsx +3 -3
  82. package/src/components/ChannelPreview/ChannelPreviewMessage.tsx +11 -8
  83. package/src/components/ChannelPreview/ChannelPreviewView.tsx +17 -13
  84. package/src/components/ChannelPreview/__tests__/ChannelPreview.test.tsx +2 -2
  85. package/src/components/Message/MessageItemView/MessageItemView.tsx +2 -0
  86. package/src/components/MessageList/__tests__/MessageList.test.js +1 -130
  87. package/src/components/MessageList/hooks/useMessageList.ts +1 -41
  88. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +24 -4
  89. package/src/contexts/channelsContext/ChannelsContext.tsx +2 -1
  90. package/src/contexts/componentsContext/PLAN.md +15 -15
  91. package/src/contexts/componentsContext/__tests__/defaultComponents.test.ts +1 -0
  92. package/src/contexts/componentsContext/defaultComponents.ts +15 -13
  93. package/src/contexts/messagesContext/MessagesContext.tsx +0 -9
  94. package/src/contexts/overlayContext/MessageOverlayHostLayer.tsx +36 -16
  95. package/src/contexts/overlayContext/__tests__/MessageOverlayHostLayer.test.tsx +59 -1
  96. package/src/version.json +1 -1
@@ -92,7 +92,7 @@ describe('MessageList', () => {
92
92
  });
93
93
  });
94
94
 
95
- it('should render deleted message in the list when `deleteMessagesVisibilityType` is set to default(always)', async () => {
95
+ it('should render deleted message in the list', async () => {
96
96
  const user1 = generateUser();
97
97
  const mockedChannel = generateChannelResponse({
98
98
  members: [generateMember({ user: user1 })],
@@ -124,135 +124,6 @@ describe('MessageList', () => {
124
124
  });
125
125
  });
126
126
 
127
- it('should render deleted message in the list when `deleteMessagesVisibilityType` is set to sender', async () => {
128
- const user1 = generateUser();
129
- const user2 = generateUser({ id: 'testID' });
130
- const mockedChannel = generateChannelResponse({
131
- members: [generateMember({ user: user1 })],
132
- messages: [
133
- generateMessage({ type: 'deleted', user: user2 }),
134
- generateMessage({ type: 'system', user: undefined }),
135
- generateMessage({ user: user1 }),
136
- ],
137
- });
138
-
139
- const chatClient = await getTestClientWithUser({ id: 'testID' });
140
- useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
141
- const channel = chatClient.channel('messaging', mockedChannel.id);
142
- await channel.watch();
143
-
144
- const { queryByTestId } = render(
145
- <OverlayProvider>
146
- <Chat client={chatClient}>
147
- <Channel channel={channel} deletedMessagesVisibilityType='sender'>
148
- <MessageList />
149
- </Channel>
150
- </Chat>
151
- </OverlayProvider>,
152
- );
153
-
154
- await waitFor(() => {
155
- expect(queryByTestId('message-deleted')).toBeTruthy();
156
- });
157
- });
158
-
159
- it('should render deleted message in the list when `deleteMessagesVisibilityType` is set to receiver', async () => {
160
- const user1 = generateUser();
161
- const user2 = generateUser({ id: 'testID' });
162
- const mockedChannel = generateChannelResponse({
163
- members: [generateMember({ user: user1 })],
164
- messages: [
165
- generateMessage({ user: user2 }),
166
- generateMessage({ type: 'system', user: undefined }),
167
- generateMessage({ type: 'deleted', user: user1 }),
168
- ],
169
- });
170
-
171
- const chatClient = await getTestClientWithUser({ id: 'testID' });
172
- useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
173
- const channel = chatClient.channel('messaging', mockedChannel.id);
174
- await channel.watch();
175
-
176
- const { getByTestId, queryByTestId } = render(
177
- <OverlayProvider>
178
- <Chat client={chatClient}>
179
- <Channel channel={channel} deletedMessagesVisibilityType='receiver'>
180
- <MessageList />
181
- </Channel>
182
- </Chat>
183
- </OverlayProvider>,
184
- );
185
-
186
- await waitFor(() => {
187
- expect(getByTestId('message-deleted')).toBeTruthy();
188
- expect(queryByTestId('only-visible-to-you')).toBeNull();
189
- });
190
- });
191
-
192
- it('should render deleted message in the list when `deleteMessagesVisibilityType` is set to never', async () => {
193
- const user1 = generateUser();
194
- const user2 = generateUser({ id: 'testID' });
195
- const mockedChannel = generateChannelResponse({
196
- members: [generateMember({ user: user1 })],
197
- messages: [
198
- generateMessage({ user: user2 }),
199
- generateMessage({ type: 'system', user: undefined }),
200
- generateMessage({ type: 'deleted', user: user1 }),
201
- ],
202
- });
203
-
204
- const chatClient = await getTestClientWithUser({ id: 'testID' });
205
- useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
206
- const channel = chatClient.channel('messaging', mockedChannel.id);
207
- await channel.watch();
208
-
209
- const { queryByTestId } = render(
210
- <OverlayProvider>
211
- <Chat client={chatClient}>
212
- <Channel channel={channel} deletedMessagesVisibilityType='never'>
213
- <MessageList />
214
- </Channel>
215
- </Chat>
216
- </OverlayProvider>,
217
- );
218
-
219
- await waitFor(() => {
220
- expect(queryByTestId('message-deleted')).toBeNull();
221
- expect(queryByTestId('only-visible-to-you')).toBeNull();
222
- });
223
- });
224
-
225
- it('should render deleted message in the list', async () => {
226
- const user1 = generateUser();
227
- const mockedChannel = generateChannelResponse({
228
- members: [generateMember({ user: user1 })],
229
- messages: [
230
- generateMessage({ type: 'deleted', user: user1 }),
231
- generateMessage({ type: 'system', user: undefined }),
232
- generateMessage({ user: user1 }),
233
- ],
234
- });
235
-
236
- const chatClient = await getTestClientWithUser({ id: 'testID' });
237
- useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
238
- const channel = chatClient.channel('messaging', mockedChannel.id);
239
- await channel.watch();
240
-
241
- const { getByTestId } = render(
242
- <OverlayProvider>
243
- <Chat client={chatClient}>
244
- <Channel channel={channel}>
245
- <MessageList />
246
- </Channel>
247
- </Chat>
248
- </OverlayProvider>,
249
- );
250
-
251
- await waitFor(() => {
252
- expect(getByTestId('message-deleted')).toBeTruthy();
253
- });
254
- });
255
-
256
127
  it('should render the typing indicator when typing object is non empty', async () => {
257
128
  const user1 = generateUser();
258
129
  const mockedChannel = generateChannelResponse({
@@ -2,11 +2,6 @@ import { useMemo } from 'react';
2
2
 
3
3
  import type { LocalMessage } from 'stream-chat';
4
4
 
5
- import { useChatContext } from '../../../contexts/chatContext/ChatContext';
6
- import {
7
- DeletedMessagesVisibilityType,
8
- useMessagesContext,
9
- } from '../../../contexts/messagesContext/MessagesContext';
10
5
  import { usePaginatedMessageListContext } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext';
11
6
  import { useThreadContext } from '../../../contexts/threadContext/ThreadContext';
12
7
 
@@ -27,35 +22,8 @@ export type MessageGroupStyles = {
27
22
  [key: string]: string[];
28
23
  };
29
24
 
30
- export const shouldIncludeMessageInList = (
31
- message: LocalMessage,
32
- options: { deletedMessagesVisibilityType?: DeletedMessagesVisibilityType; userId?: string },
33
- ) => {
34
- const { deletedMessagesVisibilityType, userId } = options;
35
- const isMessageTypeDeleted = message.type === 'deleted';
36
- const isSender = message.user?.id === userId;
37
-
38
- if (!isMessageTypeDeleted) {
39
- return true;
40
- }
41
-
42
- switch (deletedMessagesVisibilityType) {
43
- case 'always':
44
- return true;
45
- case 'sender':
46
- return isSender;
47
- case 'receiver':
48
- return !isSender;
49
- case 'never':
50
- default:
51
- return false;
52
- }
53
- };
54
-
55
25
  export const useMessageList = (params: UseMessageListParams) => {
56
26
  const { threadList, isLiveStreaming, isFlashList = false } = params;
57
- const { client } = useChatContext();
58
- const { deletedMessagesVisibilityType } = useMessagesContext();
59
27
  const { messages, viewabilityChangedCallback } = usePaginatedMessageListContext();
60
28
  const { threadMessages } = useThreadContext();
61
29
  const messageList = threadList ? threadMessages : messages;
@@ -63,14 +31,6 @@ export const useMessageList = (params: UseMessageListParams) => {
63
31
  const processedMessageList = useMemo<LocalMessage[]>(() => {
64
32
  const newMessageList = [];
65
33
  for (const message of messageList) {
66
- if (
67
- !shouldIncludeMessageInList(message, {
68
- deletedMessagesVisibilityType,
69
- userId: client.userID,
70
- })
71
- ) {
72
- continue;
73
- }
74
34
  if (isFlashList) {
75
35
  newMessageList.push(message);
76
36
  } else {
@@ -78,7 +38,7 @@ export const useMessageList = (params: UseMessageListParams) => {
78
38
  }
79
39
  }
80
40
  return newMessageList;
81
- }, [messageList, deletedMessagesVisibilityType, client.userID, isFlashList]);
41
+ }, [messageList, isFlashList]);
82
42
 
83
43
  const data = useRAFCoalescedValue(processedMessageList, isLiveStreaming);
84
44
 
@@ -465,7 +465,11 @@ exports[`Thread should match thread snapshot 1`] = `
465
465
  testID="message-components"
466
466
  >
467
467
  <View
468
- style={{}}
468
+ style={
469
+ {
470
+ "zIndex": 1,
471
+ }
472
+ }
469
473
  >
470
474
  <View
471
475
  style={
@@ -606,6 +610,7 @@ exports[`Thread should match thread snapshot 1`] = `
606
610
  style={
607
611
  {
608
612
  "marginTop": -4,
613
+ "zIndex": 0,
609
614
  }
610
615
  }
611
616
  />
@@ -799,7 +804,11 @@ exports[`Thread should match thread snapshot 1`] = `
799
804
  testID="message-components"
800
805
  >
801
806
  <View
802
- style={{}}
807
+ style={
808
+ {
809
+ "zIndex": 1,
810
+ }
811
+ }
803
812
  >
804
813
  <View
805
814
  style={
@@ -940,6 +949,7 @@ exports[`Thread should match thread snapshot 1`] = `
940
949
  style={
941
950
  {
942
951
  "marginTop": -4,
952
+ "zIndex": 0,
943
953
  }
944
954
  }
945
955
  />
@@ -1166,7 +1176,11 @@ exports[`Thread should match thread snapshot 1`] = `
1166
1176
  testID="message-components"
1167
1177
  >
1168
1178
  <View
1169
- style={{}}
1179
+ style={
1180
+ {
1181
+ "zIndex": 1,
1182
+ }
1183
+ }
1170
1184
  >
1171
1185
  <View
1172
1186
  style={
@@ -1307,6 +1321,7 @@ exports[`Thread should match thread snapshot 1`] = `
1307
1321
  style={
1308
1322
  {
1309
1323
  "marginTop": -4,
1324
+ "zIndex": 0,
1310
1325
  }
1311
1326
  }
1312
1327
  />
@@ -1491,7 +1506,11 @@ exports[`Thread should match thread snapshot 1`] = `
1491
1506
  testID="message-components"
1492
1507
  >
1493
1508
  <View
1494
- style={{}}
1509
+ style={
1510
+ {
1511
+ "zIndex": 1,
1512
+ }
1513
+ }
1495
1514
  >
1496
1515
  <View
1497
1516
  style={
@@ -1632,6 +1651,7 @@ exports[`Thread should match thread snapshot 1`] = `
1632
1651
  style={
1633
1652
  {
1634
1653
  "marginTop": -4,
1654
+ "zIndex": 0,
1635
1655
  }
1636
1656
  }
1637
1657
  />
@@ -51,7 +51,8 @@ export type ChannelsContextValue = {
51
51
  */
52
52
  loadingChannels: boolean;
53
53
  /**
54
- * Whether or not additional channels are being loaded, triggers the FooterLoadingIndicator
54
+ * Whether or not additional channels are being loaded, triggers the
55
+ * ChannelListFooterLoadingIndicator
55
56
  */
56
57
  loadingNextPage: boolean;
57
58
  /**
@@ -69,26 +69,26 @@ const getDefaults = () => {
69
69
 
70
70
  Some component keys differ from their default component names to avoid collisions:
71
71
 
72
- | Override Key | Default Component | Why renamed |
73
- | ----------------------------- | --------------------------------------- | ---------------------------------------------------------- |
74
- | `FileAttachmentIcon` | `FileIcon` | Clarity |
75
- | `ChannelListLoadingIndicator` | `ChannelListLoadingIndicator` | Split from shared `LoadingIndicator` — renders skeleton UI |
76
- | `MessageListLoadingIndicator` | `LoadingIndicator` | Split from shared `LoadingIndicator` — renders text |
77
- | `ChatLoadingIndicator` | `undefined` | Optional, no default |
78
- | `ThreadMessageComposer` | `MessageComposer` | Avoid collision with `MessageComposer` component name |
79
- | `ThreadListComponent` | `DefaultThreadListComponent` | Avoid collision with exported `ThreadList` |
80
- | `StartAudioRecordingButton` | `AudioRecordingButton` | Historical naming |
81
- | `Preview` | `ChannelPreviewView` | ChannelList preview item |
82
- | `PreviewAvatar` | `ChannelAvatar` | ChannelList preview avatar |
83
- | `FooterLoadingIndicator` | `ChannelListFooterLoadingIndicator` | ChannelList footer |
84
- | `HeaderErrorIndicator` | `ChannelListHeaderErrorIndicator` | ChannelList header |
85
- | `HeaderNetworkDownIndicator` | `ChannelListHeaderNetworkDownIndicator` | ChannelList header |
72
+ | Override Key | Default Component | Why renamed |
73
+ | --------------------------------------- | --------------------------------------- | ---------------------------------------------------------- |
74
+ | `FileAttachmentIcon` | `FileIcon` | Clarity |
75
+ | `ChannelListLoadingIndicator` | `ChannelListLoadingIndicator` | Split from shared `LoadingIndicator` — renders skeleton UI |
76
+ | `MessageListLoadingIndicator` | `LoadingIndicator` | Split from shared `LoadingIndicator` — renders text |
77
+ | `ChatLoadingIndicator` | `undefined` | Optional, no default |
78
+ | `ThreadMessageComposer` | `MessageComposer` | Avoid collision with `MessageComposer` component name |
79
+ | `ThreadListComponent` | `DefaultThreadListComponent` | Avoid collision with exported `ThreadList` |
80
+ | `StartAudioRecordingButton` | `AudioRecordingButton` | Historical naming |
81
+ | `ChannelPreview` | `ChannelPreviewView` | ChannelList preview item |
82
+ | `ChannelPreviewAvatar` | `ChannelAvatar` | ChannelList preview avatar |
83
+ | `ChannelListFooterLoadingIndicator` | `ChannelListFooterLoadingIndicator` | ChannelList footer |
84
+ | `ChannelListHeaderErrorIndicator` | `ChannelListHeaderErrorIndicator` | ChannelList header |
85
+ | `ChannelListHeaderNetworkDownIndicator` | `ChannelListHeaderNetworkDownIndicator` | ChannelList header |
86
86
 
87
87
  ### Optional Components (no default)
88
88
 
89
89
  These exist in `DEFAULT_COMPONENTS` as `undefined` with `React.ComponentType<any> | undefined` type assertions:
90
90
 
91
- `AttachmentPickerIOSSelectMorePhotos`, `ChatLoadingIndicator`, `CreatePollContent`, `ImageComponent`, `Input`, `ListHeaderComponent`, `MessageContentBottomView`, `MessageContentLeadingView`, `MessageContentTopView`, `MessageContentTrailingView`, `MessageLocation`, `MessageSpacer`, `MessageText`, `PollContent`
91
+ `AttachmentPickerIOSSelectMorePhotos`, `ChatLoadingIndicator`, `CreatePollContent`, `ImageComponent`, `Input`, `ListHeaderComponent`, `MessageActions`, `MessageContentBottomView`, `MessageContentLeadingView`, `MessageContentTopView`, `MessageContentTrailingView`, `MessageLocation`, `MessageSpacer`, `MessageText`, `PollContent`
92
92
 
93
93
  ### Shared Component Keys (audited)
94
94
 
@@ -5,6 +5,7 @@ const OPTIONAL_KEYS = new Set([
5
5
  'AttachmentPickerIOSSelectMorePhotos',
6
6
  'ChatLoadingIndicator',
7
7
  'CreatePollContent',
8
+ 'MessageActions',
8
9
  'Input',
9
10
  'ListHeaderComponent',
10
11
  'MessageContentBottomView',
@@ -144,6 +144,7 @@ import { ThreadListUnreadBanner } from '../../components/ThreadList/ThreadListUn
144
144
  import { ThreadMessagePreviewDeliveryStatus } from '../../components/ThreadList/ThreadMessagePreviewDeliveryStatus';
145
145
  import { ChannelAvatar } from '../../components/ui/Avatar/ChannelAvatar';
146
146
  import { DefaultMessageOverlayBackground } from '../../contexts/overlayContext/MessageOverlayHostLayer';
147
+ import type { MessageActionsProps } from '../../contexts/overlayContext/MessageOverlayHostLayer';
147
148
 
148
149
  /**
149
150
  * All default component implementations used across the SDK.
@@ -177,11 +178,11 @@ export const DEFAULT_COMPONENTS = {
177
178
  FileUploadNotSupportedIndicator,
178
179
  FileUploadRetryIndicator,
179
180
  FilePreview,
180
- FooterLoadingIndicator: ChannelListFooterLoadingIndicator,
181
+ ChannelListFooterLoadingIndicator,
181
182
  Gallery,
182
183
  Giphy,
183
- HeaderErrorIndicator: ChannelListHeaderErrorIndicator,
184
- HeaderNetworkDownIndicator: ChannelListHeaderNetworkDownIndicator,
184
+ ChannelListHeaderErrorIndicator,
185
+ ChannelListHeaderNetworkDownIndicator,
185
186
  ImageAttachmentUploadPreview,
186
187
  ImageLoadingFailedIndicator,
187
188
  ImageLoadingIndicator,
@@ -231,16 +232,16 @@ export const DEFAULT_COMPONENTS = {
231
232
  MessageUserReactionsAvatar,
232
233
  MessageUserReactionsItem,
233
234
  NetworkDownIndicator,
234
- Preview: ChannelPreviewView,
235
- PreviewAvatar: ChannelAvatar,
236
- PreviewLastMessage: ChannelLastMessagePreview,
237
- PreviewMessage: ChannelPreviewMessage,
238
- PreviewMessageDeliveryStatus: ChannelMessagePreviewDeliveryStatus,
239
- PreviewMutedStatus: ChannelPreviewMutedStatus,
240
- PreviewStatus: ChannelPreviewStatus,
241
- PreviewTitle: ChannelPreviewTitle,
242
- PreviewTypingIndicator: ChannelPreviewTypingIndicator,
243
- PreviewUnreadCount: ChannelPreviewUnreadCount,
235
+ ChannelPreview: ChannelPreviewView,
236
+ ChannelPreviewAvatar: ChannelAvatar,
237
+ ChannelPreviewLastMessage: ChannelLastMessagePreview,
238
+ ChannelPreviewMessage,
239
+ ChannelPreviewMessageDeliveryStatus: ChannelMessagePreviewDeliveryStatus,
240
+ ChannelPreviewMutedStatus,
241
+ ChannelPreviewStatus,
242
+ ChannelPreviewTitle,
243
+ ChannelPreviewTypingIndicator,
244
+ ChannelPreviewUnreadCount,
244
245
  ReactionListBottom,
245
246
  ReactionListClustered,
246
247
  ReactionListCountItem,
@@ -309,6 +310,7 @@ export const DEFAULT_COMPONENTS = {
309
310
  ChatLoadingIndicator: undefined as React.ComponentType<any> | null | undefined,
310
311
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
311
312
  CreatePollContent: undefined as React.ComponentType<any> | undefined,
313
+ MessageActions: undefined as React.ComponentType<MessageActionsProps> | undefined,
312
314
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
313
315
  Input: undefined as React.ComponentType<any> | undefined,
314
316
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -39,7 +39,6 @@ export type MessageContentType =
39
39
  | 'ai_text'
40
40
  | 'text'
41
41
  | 'location';
42
- export type DeletedMessagesVisibilityType = 'always' | 'never' | 'receiver' | 'sender';
43
42
 
44
43
  export type MessageLocationProps = {
45
44
  message: LocalMessage;
@@ -112,14 +111,6 @@ export type MessagesContextValue = Pick<MessageContextValue, 'isMessageAIGenerat
112
111
  message: LocalMessage;
113
112
  }) => void;
114
113
 
115
- /**
116
- * Full override of the delete message button in the Message Actions
117
- *
118
- * Please check [cookbook](https://github.com/GetStream/stream-chat-react-native/wiki/Cookbook-v3.0#override-or-intercept-message-actions-edit-delete-reaction-reply-etc) for details.
119
- */
120
- /** Control if the deleted message is visible to both the send and reciever, either of them or none */
121
- deletedMessagesVisibilityType?: DeletedMessagesVisibilityType;
122
-
123
114
  disableTypingIndicator?: boolean;
124
115
  /**
125
116
  * Enable swipe to reply on messages.
@@ -4,8 +4,10 @@ import {
4
4
  Platform,
5
5
  Pressable,
6
6
  StyleSheet,
7
+ StyleProp,
7
8
  useWindowDimensions,
8
9
  View,
10
+ ViewStyle,
9
11
  } from 'react-native';
10
12
  import { Gesture, GestureDetector } from 'react-native-gesture-handler';
11
13
  import Animated, {
@@ -53,8 +55,15 @@ export const DefaultMessageOverlayBackground = () => {
53
55
  );
54
56
  };
55
57
 
58
+ export type MessageActionsProps = {
59
+ bottomItemStyle: StyleProp<ViewStyle>;
60
+ hostStyle: StyleProp<ViewStyle>;
61
+ portalHostStyle: StyleProp<ViewStyle>;
62
+ topItemStyle: StyleProp<ViewStyle>;
63
+ };
64
+
56
65
  export const MessageOverlayHostLayer = () => {
57
- const { MessageOverlayBackground } = useComponentsContext();
66
+ const { MessageActions, MessageOverlayBackground } = useComponentsContext();
58
67
  const { id, closing } = useOverlayController();
59
68
  const insets = useSafeAreaInsets();
60
69
  const { height: screenH } = useWindowDimensions();
@@ -259,21 +268,32 @@ export const MessageOverlayHostLayer = () => {
259
268
  />
260
269
  ) : null}
261
270
 
262
- <Animated.View style={topItemStyle} testID='message-overlay-top'>
263
- <PortalHost name='top-item' style={styles.absoluteFill} />
264
- </Animated.View>
265
-
266
- <Animated.View
267
- pointerEvents='box-none'
268
- style={hostStyle}
269
- testID='message-overlay-message'
270
- >
271
- <PortalHost name='message-overlay' style={styles.absoluteFill} />
272
- </Animated.View>
273
-
274
- <Animated.View style={bottomItemStyle} testID='message-overlay-bottom'>
275
- <PortalHost name='bottom-item' style={styles.absoluteFill} />
276
- </Animated.View>
271
+ {MessageActions ? (
272
+ <MessageActions
273
+ bottomItemStyle={bottomItemStyle}
274
+ hostStyle={hostStyle}
275
+ portalHostStyle={styles.absoluteFill}
276
+ topItemStyle={topItemStyle}
277
+ />
278
+ ) : (
279
+ <>
280
+ <Animated.View style={topItemStyle} testID='message-overlay-top'>
281
+ <PortalHost name='top-item' style={styles.absoluteFill} />
282
+ </Animated.View>
283
+
284
+ <Animated.View
285
+ pointerEvents='box-none'
286
+ style={hostStyle}
287
+ testID='message-overlay-message'
288
+ >
289
+ <PortalHost name='message-overlay' style={styles.absoluteFill} />
290
+ </Animated.View>
291
+
292
+ <Animated.View style={bottomItemStyle} testID='message-overlay-bottom'>
293
+ <PortalHost name='bottom-item' style={styles.absoluteFill} />
294
+ </Animated.View>
295
+ </>
296
+ )}
277
297
  </View>
278
298
 
279
299
  <ClosingPortalHostsLayer closeCoverOpacity={closeCoverOpacity} />
@@ -14,7 +14,7 @@ import {
14
14
  setOverlayTopH,
15
15
  } from '../../../state-store';
16
16
  import { WithComponents } from '../../componentsContext/ComponentsContext';
17
- import { MessageOverlayHostLayer } from '../MessageOverlayHostLayer';
17
+ import { MessageActionsProps, MessageOverlayHostLayer } from '../MessageOverlayHostLayer';
18
18
 
19
19
  jest.mock('react-native', () => {
20
20
  const actual = jest.requireActual('react-native');
@@ -93,6 +93,18 @@ const TOP_RECT = { h: 20, w: 90, x: 5, y: 0 };
93
93
  const MESSAGE_RECT = { h: 50, w: 180, x: 10, y: 0 };
94
94
  const BOTTOM_RECT = { h: 30, w: 140, x: 20, y: 100 };
95
95
  const NoopBackground = () => null;
96
+ const CustomMessageActions = ({
97
+ bottomItemStyle,
98
+ hostStyle,
99
+ topItemStyle,
100
+ }: MessageActionsProps) => (
101
+ <>
102
+ <Text testID='custom-message-actions'>Custom</Text>
103
+ <Text style={topItemStyle} testID='custom-message-actions-top' />
104
+ <Text style={hostStyle} testID='custom-message-actions-message' />
105
+ <Text style={bottomItemStyle} testID='custom-message-actions-bottom' />
106
+ </>
107
+ );
96
108
 
97
109
  const flushAnimationFrameQueue = () => {
98
110
  act(() => {
@@ -260,4 +272,50 @@ describe('MessageOverlayHostLayer', () => {
260
272
  height: 0,
261
273
  });
262
274
  });
275
+
276
+ it('renders MessageActions override instead of the default host wrappers when provided', () => {
277
+ const renderTree = () => (
278
+ <WithComponents
279
+ overrides={{
280
+ MessageActions: CustomMessageActions,
281
+ MessageOverlayBackground: NoopBackground,
282
+ }}
283
+ >
284
+ <MessageOverlayHostLayer />
285
+ </WithComponents>
286
+ );
287
+ const { rerender } = render(renderTree());
288
+
289
+ act(() => {
290
+ setOverlayTopH(TOP_RECT);
291
+ setOverlayMessageH(MESSAGE_RECT);
292
+ setOverlayBottomH(BOTTOM_RECT);
293
+ openOverlay('message-1');
294
+ });
295
+
296
+ rerender(renderTree());
297
+
298
+ expect(screen.getByTestId('custom-message-actions')).toBeTruthy();
299
+ expect(screen.queryByTestId('message-overlay-top')).toBeNull();
300
+ expect(screen.queryByTestId('message-overlay-message')).toBeNull();
301
+ expect(screen.queryByTestId('message-overlay-bottom')).toBeNull();
302
+ expect(
303
+ StyleSheet.flatten(screen.getByTestId('custom-message-actions-top').props.style),
304
+ ).toMatchObject({
305
+ height: TOP_RECT.h,
306
+ width: TOP_RECT.w,
307
+ });
308
+ expect(
309
+ StyleSheet.flatten(screen.getByTestId('custom-message-actions-message').props.style),
310
+ ).toMatchObject({
311
+ height: MESSAGE_RECT.h,
312
+ width: MESSAGE_RECT.w,
313
+ });
314
+ expect(
315
+ StyleSheet.flatten(screen.getByTestId('custom-message-actions-bottom').props.style),
316
+ ).toMatchObject({
317
+ height: BOTTOM_RECT.h,
318
+ width: BOTTOM_RECT.w,
319
+ });
320
+ });
263
321
  });
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "9.0.0-beta.32"
2
+ "version": "9.0.0-beta.34"
3
3
  }