stream-chat-react-native-core 4.3.0-beta.5 → 4.3.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/lib/commonjs/components/Attachment/Giphy.js +26 -22
  2. package/lib/commonjs/components/Attachment/Giphy.js.map +1 -1
  3. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  4. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  5. package/lib/commonjs/components/Chat/Chat.js +8 -4
  6. package/lib/commonjs/components/Chat/Chat.js.map +1 -1
  7. package/lib/commonjs/components/Chat/hooks/useAppSettings.js +80 -0
  8. package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -0
  9. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js +3 -1
  10. package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  11. package/lib/commonjs/components/ImageGallery/ImageGallery.js +21 -20
  12. package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
  13. package/lib/commonjs/components/Message/Message.js.map +1 -1
  14. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js +4 -4
  15. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js.map +1 -1
  16. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js +4 -4
  17. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  18. package/lib/commonjs/components/Message/MessageSimple/utils/renderText.md +1 -1
  19. package/lib/commonjs/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  20. package/lib/commonjs/contexts/channelContext/ChannelContext.js.map +1 -1
  21. package/lib/commonjs/contexts/channelContext/ChannelContext.md +2 -2
  22. package/lib/commonjs/contexts/channelsContext/ChannelsContext.js.map +1 -1
  23. package/lib/commonjs/contexts/channelsContext/ChannelsContext.md +2 -2
  24. package/lib/commonjs/contexts/chatContext/ChatContext.js +2 -2
  25. package/lib/commonjs/contexts/chatContext/ChatContext.js.map +1 -1
  26. package/lib/commonjs/contexts/chatContext/ChatContext.md +2 -2
  27. package/lib/commonjs/contexts/imageGalleryContext/ImageGalleryContext.md +2 -2
  28. package/lib/commonjs/contexts/keyboardContext/KeyboardContext.md +1 -1
  29. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  30. package/lib/commonjs/contexts/messageContext/MessageContext.md +1 -1
  31. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  32. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.md +1 -1
  33. package/lib/commonjs/contexts/messageOverlayContext/MessageOverlayContext.js.map +1 -1
  34. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  35. package/lib/commonjs/contexts/messagesContext/MessagesContext.md +1 -1
  36. package/lib/commonjs/contexts/overlayContext/OverlayContext.js.map +1 -1
  37. package/lib/commonjs/contexts/overlayContext/OverlayContext.md +2 -2
  38. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +1 -2
  39. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
  40. package/lib/commonjs/contexts/paginatedMessageListContext/PaginatedMessageListContext.md +2 -2
  41. package/lib/commonjs/contexts/suggestionsContext/SuggestionsContext.md +1 -1
  42. package/lib/commonjs/contexts/typingContext/TypingContext.md +2 -2
  43. package/lib/commonjs/version.json +1 -1
  44. package/lib/module/components/Attachment/Giphy.js +26 -22
  45. package/lib/module/components/Attachment/Giphy.js.map +1 -1
  46. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  47. package/lib/module/components/Channel/Channel.js.map +1 -1
  48. package/lib/module/components/Chat/Chat.js +8 -4
  49. package/lib/module/components/Chat/Chat.js.map +1 -1
  50. package/lib/module/components/Chat/hooks/useAppSettings.js +80 -0
  51. package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -0
  52. package/lib/module/components/Chat/hooks/useCreateChatContext.js +3 -1
  53. package/lib/module/components/Chat/hooks/useCreateChatContext.js.map +1 -1
  54. package/lib/module/components/ImageGallery/ImageGallery.js +21 -20
  55. package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
  56. package/lib/module/components/Message/Message.js.map +1 -1
  57. package/lib/module/components/Message/MessageSimple/MessageContent.js +4 -4
  58. package/lib/module/components/Message/MessageSimple/MessageContent.js.map +1 -1
  59. package/lib/module/components/Message/MessageSimple/MessageSimple.js +4 -4
  60. package/lib/module/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  61. package/lib/module/components/Message/MessageSimple/utils/renderText.md +1 -1
  62. package/lib/module/contexts/attachmentPickerContext/AttachmentPickerContext.js.map +1 -1
  63. package/lib/module/contexts/channelContext/ChannelContext.js.map +1 -1
  64. package/lib/module/contexts/channelContext/ChannelContext.md +2 -2
  65. package/lib/module/contexts/channelsContext/ChannelsContext.js.map +1 -1
  66. package/lib/module/contexts/channelsContext/ChannelsContext.md +2 -2
  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/chatContext/ChatContext.md +2 -2
  70. package/lib/module/contexts/imageGalleryContext/ImageGalleryContext.md +2 -2
  71. package/lib/module/contexts/keyboardContext/KeyboardContext.md +1 -1
  72. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  73. package/lib/module/contexts/messageContext/MessageContext.md +1 -1
  74. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  75. package/lib/module/contexts/messageInputContext/MessageInputContext.md +1 -1
  76. package/lib/module/contexts/messageOverlayContext/MessageOverlayContext.js.map +1 -1
  77. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  78. package/lib/module/contexts/messagesContext/MessagesContext.md +1 -1
  79. package/lib/module/contexts/overlayContext/OverlayContext.js.map +1 -1
  80. package/lib/module/contexts/overlayContext/OverlayContext.md +2 -2
  81. package/lib/module/contexts/overlayContext/OverlayProvider.js +1 -2
  82. package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
  83. package/lib/module/contexts/paginatedMessageListContext/PaginatedMessageListContext.md +2 -2
  84. package/lib/module/contexts/suggestionsContext/SuggestionsContext.md +1 -1
  85. package/lib/module/contexts/typingContext/TypingContext.md +2 -2
  86. package/lib/module/version.json +1 -1
  87. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts +4 -4
  88. package/lib/typescript/components/Channel/Channel.d.ts +2 -2
  89. package/lib/typescript/components/Chat/Chat.d.ts +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/ImageGallery/ImageGallery.d.ts +1 -7
  94. package/lib/typescript/components/Message/Message.d.ts +2 -2
  95. package/lib/typescript/contexts/attachmentPickerContext/AttachmentPickerContext.d.ts +3 -3
  96. package/lib/typescript/contexts/channelContext/ChannelContext.d.ts +2 -2
  97. package/lib/typescript/contexts/channelsContext/ChannelsContext.d.ts +6 -6
  98. package/lib/typescript/contexts/chatContext/ChatContext.d.ts +5 -1
  99. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +2 -2
  100. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +6 -6
  101. package/lib/typescript/contexts/messageOverlayContext/MessageOverlayContext.d.ts +3 -3
  102. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +20 -20
  103. package/lib/typescript/contexts/overlayContext/OverlayContext.d.ts +1 -1
  104. package/package.json +1 -1
  105. package/src/components/Attachment/Giphy.tsx +4 -0
  106. package/src/components/Attachment/__tests__/Attachment.test.js +0 -61
  107. package/src/components/Attachment/__tests__/Giphy.test.js +290 -0
  108. package/src/components/AttachmentPicker/AttachmentPicker.tsx +4 -4
  109. package/src/components/Channel/Channel.tsx +2 -2
  110. package/src/components/Channel/__tests__/isAttachmentEqualHandler.test.js +1 -1
  111. package/src/components/ChannelList/hooks/listeners/__tests__/useChannelUpdated.test.tsx +1 -0
  112. package/src/components/Chat/Chat.tsx +5 -1
  113. package/src/components/Chat/hooks/__tests__/useAppSettings.test.tsx +34 -0
  114. package/src/components/Chat/hooks/useAppSettings.ts +39 -0
  115. package/src/components/Chat/hooks/useCreateChatContext.ts +2 -0
  116. package/src/components/ImageGallery/ImageGallery.tsx +9 -8
  117. package/src/components/Message/Message.tsx +2 -2
  118. package/src/components/Message/MessageSimple/MessageContent.tsx +16 -17
  119. package/src/components/Message/MessageSimple/MessageSimple.tsx +11 -12
  120. package/src/components/Message/MessageSimple/utils/renderText.md +1 -1
  121. package/src/contexts/attachmentPickerContext/AttachmentPickerContext.tsx +3 -3
  122. package/src/contexts/channelContext/ChannelContext.md +2 -2
  123. package/src/contexts/channelContext/ChannelContext.tsx +2 -2
  124. package/src/contexts/channelsContext/ChannelsContext.md +2 -2
  125. package/src/contexts/channelsContext/ChannelsContext.tsx +6 -6
  126. package/src/contexts/chatContext/ChatContext.md +2 -2
  127. package/src/contexts/chatContext/ChatContext.tsx +5 -1
  128. package/src/contexts/imageGalleryContext/ImageGalleryContext.md +2 -2
  129. package/src/contexts/keyboardContext/KeyboardContext.md +1 -1
  130. package/src/contexts/messageContext/MessageContext.md +1 -1
  131. package/src/contexts/messageContext/MessageContext.tsx +2 -2
  132. package/src/contexts/messageInputContext/MessageInputContext.md +1 -1
  133. package/src/contexts/messageInputContext/MessageInputContext.tsx +6 -6
  134. package/src/contexts/messageOverlayContext/MessageOverlayContext.tsx +3 -3
  135. package/src/contexts/messagesContext/MessagesContext.md +1 -1
  136. package/src/contexts/messagesContext/MessagesContext.tsx +20 -20
  137. package/src/contexts/overlayContext/OverlayContext.md +2 -2
  138. package/src/contexts/overlayContext/OverlayContext.tsx +1 -1
  139. package/src/contexts/overlayContext/OverlayProvider.tsx +1 -1
  140. package/src/contexts/paginatedMessageListContext/PaginatedMessageListContext.md +2 -2
  141. package/src/contexts/suggestionsContext/SuggestionsContext.md +1 -1
  142. package/src/contexts/typingContext/TypingContext.md +2 -2
  143. package/src/version.json +1 -1
@@ -22,9 +22,9 @@ export declare type OverlayProviderProps<StreamChatGenerics extends DefaultStrea
22
22
  /**
23
23
  * The giphy version to render - check the keys of the [Image Object](https://developers.giphy.com/docs/api/schema#image-object) for possible values. Uses 'fixed_height' by default
24
24
  * */
25
- giphyVersion: keyof NonNullable<Attachment['giphy']>;
26
25
  closePicker?: (ref: React.RefObject<BottomSheetMethods>) => void;
27
26
  error?: boolean | Error;
27
+ giphyVersion?: keyof NonNullable<Attachment['giphy']>;
28
28
  /** https://github.com/GetStream/stream-chat-react-native/wiki/Internationalization-(i18n) */
29
29
  i18nInstance?: Streami18n;
30
30
  imageGalleryGridHandleHeight?: number;
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.3.0-beta.5",
4
+ "version": "4.3.1-beta.2",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -201,6 +201,7 @@ const GiphyWithContext = <
201
201
  { backgroundColor: white, borderColor: `${black}0D` },
202
202
  selectionContainer,
203
203
  ]}
204
+ testID='giphy-action-attachment'
204
205
  >
205
206
  <View style={[styles.header, header]}>
206
207
  <GiphyIcon />
@@ -229,6 +230,7 @@ const GiphyWithContext = <
229
230
  { borderColor: grey_gainsboro, borderRightWidth: 1 },
230
231
  buttonContainer,
231
232
  ]}
233
+ testID={`${actions?.[2].value}-action-button`}
232
234
  >
233
235
  <Text style={[styles.cancel, { color: grey }, cancel]}>{actions?.[2].text}</Text>
234
236
  </TouchableOpacity>
@@ -243,6 +245,7 @@ const GiphyWithContext = <
243
245
  { borderColor: grey_gainsboro, borderRightWidth: 1 },
244
246
  buttonContainer,
245
247
  ]}
248
+ testID={`${actions?.[1].value}-action-button`}
246
249
  >
247
250
  <Text style={[styles.shuffle, { color: grey }, shuffle]}>{actions?.[1].text}</Text>
248
251
  </TouchableOpacity>
@@ -253,6 +256,7 @@ const GiphyWithContext = <
253
256
  }
254
257
  }}
255
258
  style={[styles.buttonContainer, { borderColor: grey_gainsboro }, buttonContainer]}
259
+ testID={`${actions?.[0].value}-action-button`}
256
260
  >
257
261
  <Text style={[styles.send, { color: accent_blue }, send]}>{actions?.[0].text}</Text>
258
262
  </TouchableOpacity>
@@ -10,9 +10,7 @@ import {
10
10
  generateAudioAttachment,
11
11
  generateCardAttachment,
12
12
  generateFileAttachment,
13
- generateGiphyAttachment,
14
13
  generateImageAttachment,
15
- generateImgurAttachment,
16
14
  } from '../../../mock-builders/generator/attachment';
17
15
  import { generateMessage } from '../../../mock-builders/generator/message';
18
16
  import { Attachment } from '../Attachment';
@@ -53,65 +51,6 @@ describe('Attachment', () => {
53
51
  });
54
52
  });
55
53
 
56
- it('should render Card component for "imgur" type attachment', async () => {
57
- const attachment = generateImgurAttachment();
58
- const { getByTestId } = render(getAttachmentComponent({ attachment }));
59
-
60
- await waitFor(() => {
61
- expect(getByTestId('giphy-attachment')).toBeTruthy();
62
- });
63
- });
64
-
65
- it('should render Card component for "giphy" type attachment', async () => {
66
- const attachment = generateGiphyAttachment();
67
- const { getByTestId } = render(getAttachmentComponent({ attachment }));
68
-
69
- await waitFor(() => {
70
- expect(getByTestId('giphy-attachment')).toBeTruthy();
71
- });
72
- });
73
-
74
- it('"giphy" attachment size should be customisable', async () => {
75
- const attachment = generateGiphyAttachment();
76
- attachment.giphy = {
77
- fixed_height: {
78
- height: '200',
79
- url: 'https://media1.giphy.com/media/test/fixed_height.gif',
80
- width: '375',
81
- },
82
- original: {
83
- height: '256',
84
- url: 'https://media1.giphy.com/media/test/original.gif',
85
- width: '480',
86
- },
87
- };
88
- const { getByTestId: getByTestIdFixedHeight } = render(
89
- getAttachmentComponent({ attachment, giphyVersion: 'fixed_height' }),
90
- );
91
- const { getByTestId: getByTestIdOriginal } = render(
92
- getAttachmentComponent({ attachment, giphyVersion: 'original' }),
93
- );
94
- await waitFor(() => {
95
- const checkImageProps = (imageProps, specificSizedGiphyData) => {
96
- let imageStyle = imageProps.style;
97
- if (Array.isArray(imageStyle)) {
98
- imageStyle = Object.assign({}, ...imageStyle);
99
- }
100
- expect(imageStyle.height).toBe(parseFloat(specificSizedGiphyData.height));
101
- expect(imageStyle.width).toBe(parseFloat(specificSizedGiphyData.width));
102
- expect(imageProps.source.uri).toBe(specificSizedGiphyData.url);
103
- };
104
- checkImageProps(
105
- getByTestIdFixedHeight('giphy-attachment-image').props,
106
- attachment.giphy.fixed_height,
107
- );
108
- checkImageProps(
109
- getByTestIdOriginal('giphy-attachment-image').props,
110
- attachment.giphy.original,
111
- );
112
- });
113
- });
114
-
115
54
  it('should render UrlPreview component if attachment has title_link or og_scrape_url', async () => {
116
55
  const attachment = generateImageAttachment({
117
56
  og_scrape_url: uuidv4(),
@@ -0,0 +1,290 @@
1
+ import React from 'react';
2
+
3
+ import { fireEvent, render, waitFor } from '@testing-library/react-native';
4
+
5
+ import { MessageProvider } from '../../../contexts/messageContext/MessageContext';
6
+ import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvider';
7
+
8
+ import { ThemeProvider } from '../../../contexts/themeContext/ThemeContext';
9
+ import { getOrCreateChannelApi } from '../../../mock-builders/api/getOrCreateChannel';
10
+ import { useMockedApis } from '../../../mock-builders/api/useMockedApis';
11
+ import {
12
+ generateGiphyAttachment,
13
+ generateImgurAttachment,
14
+ } from '../../../mock-builders/generator/attachment';
15
+ import { generateChannelResponse } from '../../../mock-builders/generator/channel';
16
+ import { generateMember } from '../../../mock-builders/generator/member';
17
+ import { generateMessage } from '../../../mock-builders/generator/message';
18
+ import { generateUser } from '../../../mock-builders/generator/user';
19
+ import { getTestClientWithUser } from '../../../mock-builders/mock';
20
+ import { Channel } from '../../Channel/Channel';
21
+ import { Chat } from '../../Chat/Chat';
22
+ import { MessageList } from '../../MessageList/MessageList';
23
+ import { Giphy } from '../Giphy';
24
+
25
+ describe('Giphy', () => {
26
+ const getAttachmentComponent = (props) => {
27
+ const message = generateMessage();
28
+ return (
29
+ <ThemeProvider>
30
+ <MessageProvider value={{ message }}>
31
+ <Giphy {...props} />
32
+ </MessageProvider>
33
+ </ThemeProvider>
34
+ );
35
+ };
36
+
37
+ it('should render Card component for "imgur" type attachment', async () => {
38
+ const attachment = generateImgurAttachment();
39
+ const { getByTestId } = render(getAttachmentComponent({ attachment }));
40
+
41
+ await waitFor(() => {
42
+ expect(getByTestId('giphy-attachment')).toBeTruthy();
43
+ });
44
+ });
45
+
46
+ it('should render Card component for "giphy" type attachment', async () => {
47
+ const attachment = generateGiphyAttachment();
48
+ const { getByTestId } = render(getAttachmentComponent({ attachment }));
49
+
50
+ await waitFor(() => {
51
+ expect(getByTestId('giphy-attachment')).toBeTruthy();
52
+ });
53
+ });
54
+
55
+ it('"giphy" attachment size should be customisable', async () => {
56
+ const attachment = generateGiphyAttachment();
57
+ attachment.giphy = {
58
+ fixed_height: {
59
+ height: '200',
60
+ url: 'https://media1.giphy.com/media/test/fixed_height.gif',
61
+ width: '375',
62
+ },
63
+ original: {
64
+ height: '256',
65
+ url: 'https://media1.giphy.com/media/test/original.gif',
66
+ width: '480',
67
+ },
68
+ };
69
+ const { getByTestId: getByTestIdFixedHeight } = render(
70
+ getAttachmentComponent({ attachment, giphyVersion: 'fixed_height' }),
71
+ );
72
+ const { getByTestId: getByTestIdOriginal } = render(
73
+ getAttachmentComponent({ attachment, giphyVersion: 'original' }),
74
+ );
75
+ await waitFor(() => {
76
+ const checkImageProps = (imageProps, specificSizedGiphyData) => {
77
+ let imageStyle = imageProps.style;
78
+ if (Array.isArray(imageStyle)) {
79
+ imageStyle = Object.assign({}, ...imageStyle);
80
+ }
81
+ expect(imageStyle.height).toBe(parseFloat(specificSizedGiphyData.height));
82
+ expect(imageStyle.width).toBe(parseFloat(specificSizedGiphyData.width));
83
+ expect(imageProps.source.uri).toBe(specificSizedGiphyData.url);
84
+ };
85
+ checkImageProps(
86
+ getByTestIdFixedHeight('giphy-attachment-image').props,
87
+ attachment.giphy.fixed_height,
88
+ );
89
+ checkImageProps(
90
+ getByTestIdOriginal('giphy-attachment-image').props,
91
+ attachment.giphy.original,
92
+ );
93
+ });
94
+ });
95
+
96
+ it('show render giphy action UI and all the 3 action buttons', async () => {
97
+ const attachment = generateGiphyAttachment();
98
+ attachment.actions = [
99
+ { name: 'image_action', text: 'Send', value: 'send' },
100
+ { name: 'image_action', text: 'Shuffle', value: 'shuffle' },
101
+ {
102
+ name: 'image_action',
103
+ text: 'Cancel',
104
+ value: 'cancel',
105
+ },
106
+ ];
107
+ const { getByTestId } = render(
108
+ getAttachmentComponent({ attachment, giphyVersion: 'fixed_height' }),
109
+ );
110
+
111
+ await waitFor(() => {
112
+ expect(getByTestId('giphy-action-attachment')).toBeTruthy();
113
+ expect(getByTestId('cancel-action-button')).toBeTruthy();
114
+ expect(getByTestId('shuffle-action-button')).toBeTruthy();
115
+ expect(getByTestId('send-action-button')).toBeTruthy();
116
+ });
117
+ });
118
+
119
+ it('should trigger the cancel giphy action', async () => {
120
+ const attachment = generateGiphyAttachment();
121
+ const handleAction = jest.fn();
122
+ attachment.actions = [
123
+ { name: 'image_action', text: 'Send', value: 'send' },
124
+ { name: 'image_action', text: 'Shuffle', value: 'shuffle' },
125
+ {
126
+ name: 'image_action',
127
+ text: 'Cancel',
128
+ value: 'cancel',
129
+ },
130
+ ];
131
+ const { getByTestId } = render(
132
+ getAttachmentComponent({
133
+ attachment,
134
+ giphyVersion: 'fixed_height',
135
+ handleAction,
136
+ }),
137
+ );
138
+
139
+ await waitFor(() => getByTestId(`${attachment.actions[2].value}-action-button`));
140
+
141
+ expect(getByTestId('giphy-action-attachment')).toContainElement(
142
+ getByTestId(`${attachment.actions[2].value}-action-button`),
143
+ );
144
+
145
+ fireEvent.press(getByTestId(`${attachment.actions[2].value}-action-button`));
146
+
147
+ await waitFor(() => {
148
+ expect(handleAction).toHaveBeenCalledTimes(1);
149
+ });
150
+ });
151
+
152
+ it('should trigger the shuffle giphy action', async () => {
153
+ const attachment = generateGiphyAttachment();
154
+ const handleAction = jest.fn();
155
+ attachment.actions = [
156
+ { name: 'image_action', text: 'Send', value: 'send' },
157
+ { name: 'image_action', text: 'Shuffle', value: 'shuffle' },
158
+ {
159
+ name: 'image_action',
160
+ text: 'Cancel',
161
+ value: 'cancel',
162
+ },
163
+ ];
164
+ const { getByTestId } = render(
165
+ getAttachmentComponent({
166
+ attachment,
167
+ giphyVersion: 'fixed_height',
168
+ handleAction,
169
+ }),
170
+ );
171
+
172
+ await waitFor(() => getByTestId(`${attachment.actions[1].value}-action-button`));
173
+
174
+ expect(getByTestId('giphy-action-attachment')).toContainElement(
175
+ getByTestId(`${attachment.actions[1].value}-action-button`),
176
+ );
177
+
178
+ fireEvent.press(getByTestId(`${attachment.actions[1].value}-action-button`));
179
+
180
+ await waitFor(() => {
181
+ expect(handleAction).toHaveBeenCalledTimes(1);
182
+ });
183
+ });
184
+
185
+ it('should trigger the send giphy action', async () => {
186
+ const attachment = generateGiphyAttachment();
187
+ const handleAction = jest.fn();
188
+ attachment.actions = [
189
+ { name: 'image_action', text: 'Send', value: 'send' },
190
+ { name: 'image_action', text: 'Shuffle', value: 'shuffle' },
191
+ {
192
+ name: 'image_action',
193
+ text: 'Cancel',
194
+ value: 'cancel',
195
+ },
196
+ ];
197
+ const { getByTestId } = render(
198
+ getAttachmentComponent({
199
+ attachment,
200
+ giphyVersion: 'fixed_height',
201
+ handleAction,
202
+ }),
203
+ );
204
+
205
+ await waitFor(() => getByTestId(`${attachment.actions[0].value}-action-button`));
206
+
207
+ expect(getByTestId('giphy-action-attachment')).toContainElement(
208
+ getByTestId(`${attachment.actions[0].value}-action-button`),
209
+ );
210
+
211
+ fireEvent.press(getByTestId(`${attachment.actions[0].value}-action-button`));
212
+
213
+ await waitFor(() => {
214
+ expect(handleAction).toHaveBeenCalledTimes(1);
215
+ });
216
+ });
217
+
218
+ it('giphy attachment UI should render within the message list with actions', async () => {
219
+ const user1 = generateUser();
220
+ const attachment = generateGiphyAttachment();
221
+ attachment.actions = [
222
+ { name: 'image_action', text: 'Send', value: 'send' },
223
+ { name: 'image_action', text: 'Shuffle', value: 'shuffle' },
224
+ {
225
+ name: 'image_action',
226
+ text: 'Cancel',
227
+ value: 'cancel',
228
+ },
229
+ ];
230
+ const mockedChannel = generateChannelResponse({
231
+ members: [generateMember({ user: user1 })],
232
+ messages: [
233
+ generateMessage({ user: user1 }),
234
+ generateMessage({ type: 'system', user: undefined }),
235
+ generateMessage({ attachments: [{ ...attachment }], user: user1 }),
236
+ ],
237
+ });
238
+
239
+ const chatClient = await getTestClientWithUser({ id: 'testID' });
240
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
241
+ const channel = chatClient.channel('messaging', mockedChannel.id);
242
+ await channel.watch();
243
+
244
+ const { getByTestId, queryByTestId } = render(
245
+ <OverlayProvider>
246
+ <Chat client={chatClient}>
247
+ <Channel channel={channel}>
248
+ <MessageList />
249
+ </Channel>
250
+ </Chat>
251
+ </OverlayProvider>,
252
+ );
253
+
254
+ expect(queryByTestId('giphy-action-attachment')).toBeTruthy();
255
+ expect(getByTestId('cancel-action-button')).toBeTruthy();
256
+ expect(getByTestId('shuffle-action-button')).toBeTruthy();
257
+ expect(getByTestId('send-action-button')).toBeTruthy();
258
+ });
259
+
260
+ it('giphy attachment UI should render within the message list', async () => {
261
+ const user1 = generateUser();
262
+ const attachment = generateGiphyAttachment();
263
+
264
+ const mockedChannel = generateChannelResponse({
265
+ members: [generateMember({ user: user1 })],
266
+ messages: [
267
+ generateMessage({ user: user1 }),
268
+ generateMessage({ type: 'system', user: undefined }),
269
+ generateMessage({ attachments: [{ ...attachment }], user: user1 }),
270
+ ],
271
+ });
272
+
273
+ const chatClient = await getTestClientWithUser({ id: 'testID' });
274
+ useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
275
+ const channel = chatClient.channel('messaging', mockedChannel.id);
276
+ await channel.watch();
277
+
278
+ const { queryByTestId } = render(
279
+ <OverlayProvider>
280
+ <Chat client={chatClient}>
281
+ <Channel channel={channel}>
282
+ <MessageList />
283
+ </Channel>
284
+ </Chat>
285
+ </OverlayProvider>,
286
+ );
287
+
288
+ expect(queryByTestId('giphy-attachment')).toBeTruthy();
289
+ });
290
+ });
@@ -132,25 +132,25 @@ export type AttachmentPickerProps = {
132
132
  /**
133
133
  * Custom UI component to render [draggable handle](https://github.com/GetStream/stream-chat-react-native/blob/master/screenshots/docs/1.png) of attachment picker.
134
134
  *
135
- * **Default** [AttachmentPickerBottomSheetHandle](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.tsx)
135
+ * **Default** [AttachmentPickerBottomSheetHandle](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/AttachmentPicker/components/AttachmentPickerBottomSheetHandle.tsx)
136
136
  */
137
137
  AttachmentPickerBottomSheetHandle: React.FC<BottomSheetHandleProps>;
138
138
  /**
139
139
  * Custom UI component to render error component while opening attachment picker.
140
140
  *
141
- * **Default** [AttachmentPickerError](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/AttachmentPicker/components/AttachmentPickerError.tsx)
141
+ * **Default** [AttachmentPickerError](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/AttachmentPicker/components/AttachmentPickerError.tsx)
142
142
  */
143
143
  AttachmentPickerError: React.ComponentType<AttachmentPickerErrorProps>;
144
144
  /**
145
145
  * Custom UI component to render error image for attachment picker
146
146
  *
147
- * **Default** [AttachmentPickerErrorImage](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/AttachmentPicker/components/AttachmentPickerErrorImage.tsx)
147
+ * **Default** [AttachmentPickerErrorImage](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/AttachmentPicker/components/AttachmentPickerErrorImage.tsx)
148
148
  */
149
149
  AttachmentPickerErrorImage: React.ComponentType;
150
150
  /**
151
151
  * Custom UI component to render overlay component, that shows up on top of [selected image](https://github.com/GetStream/stream-chat-react-native/blob/master/screenshots/docs/1.png) (with tick mark)
152
152
  *
153
- * **Default** [ImageOverlaySelectedComponent](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/AttachmentPicker/components/ImageOverlaySelectedComponent.tsx)
153
+ * **Default** [ImageOverlaySelectedComponent](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/AttachmentPicker/components/ImageOverlaySelectedComponent.tsx)
154
154
  */
155
155
  ImageOverlaySelectedComponent: React.ComponentType;
156
156
  attachmentPickerBottomSheetHandleHeight?: number;
@@ -304,7 +304,7 @@ export type ChannelPropsWithContext<
304
304
  /**
305
305
  * When true, disables the KeyboardCompatibleView wrapper
306
306
  *
307
- * Channel internally uses the [KeyboardCompatibleView](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx)
307
+ * Channel internally uses the [KeyboardCompatibleView](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx)
308
308
  * component to adjust the height of Channel when the keyboard is opened or dismissed. This prop provides the ability to disable this functionality in case you
309
309
  * want to use [KeyboardAvoidingView](https://facebook.github.io/react-native/docs/keyboardavoidingview) or handle dismissal yourself.
310
310
  * KeyboardAvoidingView works well when your component occupies 100% of screen height, otherwise it may raise some issues.
@@ -345,7 +345,7 @@ export type ChannelPropsWithContext<
345
345
  keyboardBehavior?: KeyboardAvoidingViewProps['behavior'];
346
346
  /**
347
347
  * Custom wrapper component that handles height adjustment of Channel component when keyboard is opened or dismissed
348
- * Default component (accepts the same props): [KeyboardCompatibleView](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx)
348
+ * Default component (accepts the same props): [KeyboardCompatibleView](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/KeyboardCompatibleView/KeyboardCompatibleView.tsx)
349
349
  *
350
350
  * **Example:**
351
351
  *
@@ -18,7 +18,7 @@ import { Channel } from '../../Channel/Channel';
18
18
  import { Chat } from '../../Chat/Chat';
19
19
  import { MessageList } from '../../MessageList/MessageList';
20
20
 
21
- describe('Message', () => {
21
+ describe('isAttachmentEqualHandler', () => {
22
22
  let channel;
23
23
  let chatClient;
24
24
 
@@ -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';
@@ -90,7 +91,7 @@ export type ChatProps<
90
91
  */
91
92
  i18nInstance?: Streami18n;
92
93
  /**
93
- * You can pass the theme object to customize the styles of Chat components. You can check the default theme in [theme.ts](https://github.com/GetStream/stream-chat-react-native/blob/master/src/contexts/themeContext/utils/theme.ts)
94
+ * You can pass the theme object to customize the styles of Chat components. You can check the default theme in [theme.ts](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/contexts/themeContext/utils/theme.ts)
94
95
  *
95
96
  * Please check section about [themes in cookbook](https://github.com/GetStream/stream-chat-react-native/wiki/Cookbook-v3.0#theme) for details.
96
97
  *
@@ -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,
@@ -127,13 +127,13 @@ export type ImageGalleryCustomComponents<
127
127
  type Props<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
128
128
  ImageGalleryCustomComponents<StreamChatGenerics> & {
129
129
  overlayOpacity: Animated.SharedValue<number>;
130
- imageGalleryGridHandleHeight?: number;
131
- /**
132
- * This should be
133
- */
134
- imageGalleryGridSnapPoints?: [string | number, string | number];
135
- numberOfImageGalleryGridColumns?: number;
136
- } & Pick<OverlayProviderProps<StreamChatGenerics>, 'giphyVersion'>;
130
+ } & Pick<
131
+ OverlayProviderProps<StreamChatGenerics>,
132
+ | 'giphyVersion'
133
+ | 'imageGalleryGridSnapPoints'
134
+ | 'imageGalleryGridHandleHeight'
135
+ | 'numberOfImageGalleryGridColumns'
136
+ >;
137
137
 
138
138
  export const ImageGallery = <
139
139
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -141,7 +141,7 @@ export const ImageGallery = <
141
141
  props: Props<StreamChatGenerics>,
142
142
  ) => {
143
143
  const {
144
- giphyVersion,
144
+ giphyVersion = 'fixed_height',
145
145
  imageGalleryCustomComponents,
146
146
  imageGalleryGridHandleHeight,
147
147
  imageGalleryGridSnapPoints,
@@ -308,6 +308,7 @@ export const ImageGallery = <
308
308
  * Photos array created from all currently available
309
309
  * photo attachments
310
310
  */
311
+
311
312
  const photos = images.reduce((acc: Photo<StreamChatGenerics>[], cur) => {
312
313
  const attachmentImages =
313
314
  cur.attachments?.filter(
@@ -147,7 +147,7 @@ export type MessagePropsWithContext<
147
147
  * You can call methods available on the Message
148
148
  * component such as handleEdit, handleDelete, handleAction etc.
149
149
  *
150
- * Source - [Message](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/Message/Message.tsx)
150
+ * Source - [Message](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/Message/Message.tsx)
151
151
  *
152
152
  * By default, we show the overlay with all the message actions on long press.
153
153
  *
@@ -160,7 +160,7 @@ export type MessagePropsWithContext<
160
160
  * You can call methods available on the Message
161
161
  * component such as handleEdit, handleDelete, handleAction etc.
162
162
  *
163
- * Source - [Message](https://github.com/GetStream/stream-chat-react-native/blob/master/src/components/Message/Message.tsx)
163
+ * Source - [Message](https://github.com/GetStream/stream-chat-react-native/blob/master/package/src/components/Message/Message.tsx)
164
164
  *
165
165
  * By default, we will dismiss the keyboard on press.
166
166
  *