stream-chat-react-native-core 9.0.0-beta.25 → 9.0.0-beta.27

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 (196) hide show
  1. package/lib/commonjs/components/Attachment/Giphy/Giphy.js +19 -7
  2. package/lib/commonjs/components/Attachment/Giphy/Giphy.js.map +1 -1
  3. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js +3 -3
  4. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  5. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerGenericContent.js +24 -16
  6. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerGenericContent.js.map +1 -1
  7. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionList.js +2 -1
  8. package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionList.js.map +1 -1
  9. package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js +1 -1
  10. package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
  11. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessage.js +2 -0
  12. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessage.js.map +1 -1
  13. package/lib/commonjs/components/ImageGallery/components/ImageGrid.js +5 -4
  14. package/lib/commonjs/components/ImageGallery/components/ImageGrid.js.map +1 -1
  15. package/lib/commonjs/components/Indicators/LoadingIndicator.js +3 -3
  16. package/lib/commonjs/components/Indicators/LoadingIndicator.js.map +1 -1
  17. package/lib/commonjs/components/Message/Message.js +0 -9
  18. package/lib/commonjs/components/Message/Message.js.map +1 -1
  19. package/lib/commonjs/components/Message/MessageItemView/MessageContent.js +39 -5
  20. package/lib/commonjs/components/Message/MessageItemView/MessageContent.js.map +1 -1
  21. package/lib/commonjs/components/Message/MessageItemView/MessageItemView.js +5 -5
  22. package/lib/commonjs/components/Message/MessageItemView/MessageItemView.js.map +1 -1
  23. package/lib/commonjs/components/Message/MessageItemView/MessageReplies.js +1 -1
  24. package/lib/commonjs/components/Message/MessageItemView/MessageReplies.js.map +1 -1
  25. package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js +18 -8
  26. package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js.map +1 -1
  27. package/lib/commonjs/components/Message/MessageItemView/utils/generateMarkdownText.js +3 -2
  28. package/lib/commonjs/components/Message/MessageItemView/utils/generateMarkdownText.js.map +1 -1
  29. package/lib/commonjs/components/Message/MessageItemView/utils/generateMarkdownText.test.js +1 -1
  30. package/lib/commonjs/components/Message/MessageItemView/utils/generateMarkdownText.test.js.map +1 -1
  31. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js +2 -2
  32. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  33. package/lib/commonjs/components/MessageInput/ShowThreadMessageInChannelButton.js +2 -1
  34. package/lib/commonjs/components/MessageInput/ShowThreadMessageInChannelButton.js.map +1 -1
  35. package/lib/commonjs/components/Poll/components/MultipleVotesSettings.js +8 -0
  36. package/lib/commonjs/components/Poll/components/MultipleVotesSettings.js.map +1 -1
  37. package/lib/commonjs/components/Poll/components/PollOption.js +15 -5
  38. package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
  39. package/lib/commonjs/components/ThreadList/ThreadList.js +3 -1
  40. package/lib/commonjs/components/ThreadList/ThreadList.js.map +1 -1
  41. package/lib/commonjs/components/ui/Button/hooks/useButtonStyles.js +1 -1
  42. package/lib/commonjs/components/ui/Button/hooks/useButtonStyles.js.map +1 -1
  43. package/lib/commonjs/contexts/themeContext/utils/theme.js +1 -0
  44. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  45. package/lib/commonjs/hooks/useAfterKeyboardOpenCallback.js +1 -3
  46. package/lib/commonjs/hooks/useAfterKeyboardOpenCallback.js.map +1 -1
  47. package/lib/commonjs/i18n/en.json +3 -2
  48. package/lib/commonjs/i18n/es.json +3 -2
  49. package/lib/commonjs/i18n/fr.json +3 -2
  50. package/lib/commonjs/i18n/he.json +3 -2
  51. package/lib/commonjs/i18n/hi.json +3 -2
  52. package/lib/commonjs/i18n/it.json +3 -2
  53. package/lib/commonjs/i18n/ja.json +3 -2
  54. package/lib/commonjs/i18n/ko.json +3 -2
  55. package/lib/commonjs/i18n/nl.json +3 -2
  56. package/lib/commonjs/i18n/pt-br.json +3 -2
  57. package/lib/commonjs/i18n/ru.json +3 -2
  58. package/lib/commonjs/i18n/tr.json +3 -2
  59. package/lib/commonjs/version.json +1 -1
  60. package/lib/module/components/Attachment/Giphy/Giphy.js +19 -7
  61. package/lib/module/components/Attachment/Giphy/Giphy.js.map +1 -1
  62. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js +3 -3
  63. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  64. package/lib/module/components/AttachmentPicker/components/AttachmentPickerGenericContent.js +24 -16
  65. package/lib/module/components/AttachmentPicker/components/AttachmentPickerGenericContent.js.map +1 -1
  66. package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionList.js +2 -1
  67. package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionList.js.map +1 -1
  68. package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js +1 -1
  69. package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
  70. package/lib/module/components/ChannelPreview/ChannelPreviewMessage.js +2 -0
  71. package/lib/module/components/ChannelPreview/ChannelPreviewMessage.js.map +1 -1
  72. package/lib/module/components/ImageGallery/components/ImageGrid.js +5 -4
  73. package/lib/module/components/ImageGallery/components/ImageGrid.js.map +1 -1
  74. package/lib/module/components/Indicators/LoadingIndicator.js +3 -3
  75. package/lib/module/components/Indicators/LoadingIndicator.js.map +1 -1
  76. package/lib/module/components/Message/Message.js +0 -9
  77. package/lib/module/components/Message/Message.js.map +1 -1
  78. package/lib/module/components/Message/MessageItemView/MessageContent.js +39 -5
  79. package/lib/module/components/Message/MessageItemView/MessageContent.js.map +1 -1
  80. package/lib/module/components/Message/MessageItemView/MessageItemView.js +5 -5
  81. package/lib/module/components/Message/MessageItemView/MessageItemView.js.map +1 -1
  82. package/lib/module/components/Message/MessageItemView/MessageReplies.js +1 -1
  83. package/lib/module/components/Message/MessageItemView/MessageReplies.js.map +1 -1
  84. package/lib/module/components/Message/MessageItemView/MessageStatus.js +18 -8
  85. package/lib/module/components/Message/MessageItemView/MessageStatus.js.map +1 -1
  86. package/lib/module/components/Message/MessageItemView/utils/generateMarkdownText.js +3 -2
  87. package/lib/module/components/Message/MessageItemView/utils/generateMarkdownText.js.map +1 -1
  88. package/lib/module/components/Message/MessageItemView/utils/generateMarkdownText.test.js +1 -1
  89. package/lib/module/components/Message/MessageItemView/utils/generateMarkdownText.test.js.map +1 -1
  90. package/lib/module/components/Message/hooks/useMessageActionHandlers.js +2 -2
  91. package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  92. package/lib/module/components/MessageInput/ShowThreadMessageInChannelButton.js +2 -1
  93. package/lib/module/components/MessageInput/ShowThreadMessageInChannelButton.js.map +1 -1
  94. package/lib/module/components/Poll/components/MultipleVotesSettings.js +8 -0
  95. package/lib/module/components/Poll/components/MultipleVotesSettings.js.map +1 -1
  96. package/lib/module/components/Poll/components/PollOption.js +15 -5
  97. package/lib/module/components/Poll/components/PollOption.js.map +1 -1
  98. package/lib/module/components/ThreadList/ThreadList.js +3 -1
  99. package/lib/module/components/ThreadList/ThreadList.js.map +1 -1
  100. package/lib/module/components/ui/Button/hooks/useButtonStyles.js +1 -1
  101. package/lib/module/components/ui/Button/hooks/useButtonStyles.js.map +1 -1
  102. package/lib/module/contexts/themeContext/utils/theme.js +1 -0
  103. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  104. package/lib/module/hooks/useAfterKeyboardOpenCallback.js +1 -3
  105. package/lib/module/hooks/useAfterKeyboardOpenCallback.js.map +1 -1
  106. package/lib/module/i18n/en.json +3 -2
  107. package/lib/module/i18n/es.json +3 -2
  108. package/lib/module/i18n/fr.json +3 -2
  109. package/lib/module/i18n/he.json +3 -2
  110. package/lib/module/i18n/hi.json +3 -2
  111. package/lib/module/i18n/it.json +3 -2
  112. package/lib/module/i18n/ja.json +3 -2
  113. package/lib/module/i18n/ko.json +3 -2
  114. package/lib/module/i18n/nl.json +3 -2
  115. package/lib/module/i18n/pt-br.json +3 -2
  116. package/lib/module/i18n/ru.json +3 -2
  117. package/lib/module/i18n/tr.json +3 -2
  118. package/lib/module/version.json +1 -1
  119. package/lib/typescript/components/Attachment/Giphy/Giphy.d.ts +1 -1
  120. package/lib/typescript/components/Attachment/Giphy/Giphy.d.ts.map +1 -1
  121. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerGenericContent.d.ts.map +1 -1
  122. package/lib/typescript/components/AutoCompleteInput/AutoCompleteSuggestionList.d.ts.map +1 -1
  123. package/lib/typescript/components/ChannelPreview/ChannelPreviewMessage.d.ts.map +1 -1
  124. package/lib/typescript/components/ImageGallery/components/ImageGrid.d.ts.map +1 -1
  125. package/lib/typescript/components/Indicators/LoadingIndicator.d.ts.map +1 -1
  126. package/lib/typescript/components/Message/Message.d.ts.map +1 -1
  127. package/lib/typescript/components/Message/MessageItemView/MessageContent.d.ts.map +1 -1
  128. package/lib/typescript/components/Message/MessageItemView/MessageItemView.d.ts.map +1 -1
  129. package/lib/typescript/components/Message/MessageItemView/MessageStatus.d.ts.map +1 -1
  130. package/lib/typescript/components/Message/MessageItemView/utils/generateMarkdownText.d.ts.map +1 -1
  131. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts +1 -0
  132. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
  133. package/lib/typescript/components/MessageInput/ShowThreadMessageInChannelButton.d.ts.map +1 -1
  134. package/lib/typescript/components/Poll/components/MultipleVotesSettings.d.ts.map +1 -1
  135. package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
  136. package/lib/typescript/components/ThreadList/ThreadList.d.ts.map +1 -1
  137. package/lib/typescript/contexts/themeContext/ThemeContext.d.ts +1 -0
  138. package/lib/typescript/contexts/themeContext/ThemeContext.d.ts.map +1 -1
  139. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +1 -0
  140. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  141. package/lib/typescript/hooks/useAfterKeyboardOpenCallback.d.ts.map +1 -1
  142. package/lib/typescript/i18n/en.json +3 -2
  143. package/lib/typescript/i18n/es.json +3 -2
  144. package/lib/typescript/i18n/fr.json +3 -2
  145. package/lib/typescript/i18n/he.json +3 -2
  146. package/lib/typescript/i18n/hi.json +3 -2
  147. package/lib/typescript/i18n/it.json +3 -2
  148. package/lib/typescript/i18n/ja.json +3 -2
  149. package/lib/typescript/i18n/ko.json +3 -2
  150. package/lib/typescript/i18n/nl.json +3 -2
  151. package/lib/typescript/i18n/pt-br.json +3 -2
  152. package/lib/typescript/i18n/ru.json +3 -2
  153. package/lib/typescript/i18n/tr.json +3 -2
  154. package/lib/typescript/utils/i18n/Streami18n.d.ts +3 -2
  155. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  156. package/package.json +1 -1
  157. package/src/components/Attachment/Giphy/Giphy.tsx +19 -7
  158. package/src/components/Attachment/__tests__/Giphy.test.js +33 -1
  159. package/src/components/AttachmentPicker/components/AttachmentPickerContent.tsx +3 -3
  160. package/src/components/AttachmentPicker/components/AttachmentPickerGenericContent.tsx +23 -13
  161. package/src/components/AutoCompleteInput/AutoCompleteSuggestionList.tsx +3 -1
  162. package/src/components/ChannelPreview/ChannelDetailsBottomSheet.tsx +1 -1
  163. package/src/components/ChannelPreview/ChannelPreviewMessage.tsx +3 -1
  164. package/src/components/ImageGallery/components/ImageGrid.tsx +3 -1
  165. package/src/components/Indicators/LoadingIndicator.tsx +7 -5
  166. package/src/components/Message/Message.tsx +0 -11
  167. package/src/components/Message/MessageItemView/MessageContent.tsx +44 -7
  168. package/src/components/Message/MessageItemView/MessageItemView.tsx +8 -5
  169. package/src/components/Message/MessageItemView/MessageReplies.tsx +1 -1
  170. package/src/components/Message/MessageItemView/MessageStatus.tsx +16 -5
  171. package/src/components/Message/MessageItemView/__tests__/MessageContent.test.js +44 -1
  172. package/src/components/Message/MessageItemView/__tests__/MessageItemView.test.js +21 -1
  173. package/src/components/Message/MessageItemView/utils/generateMarkdownText.test.ts +3 -0
  174. package/src/components/Message/MessageItemView/utils/generateMarkdownText.ts +4 -2
  175. package/src/components/Message/hooks/useMessageActionHandlers.ts +3 -1
  176. package/src/components/MessageInput/ShowThreadMessageInChannelButton.tsx +1 -0
  177. package/src/components/MessageInput/__tests__/__snapshots__/AttachButton.test.js.snap +1 -1
  178. package/src/components/Poll/components/MultipleVotesSettings.tsx +8 -0
  179. package/src/components/Poll/components/PollOption.tsx +25 -9
  180. package/src/components/ThreadList/ThreadList.tsx +1 -1
  181. package/src/components/ui/Button/hooks/useButtonStyles.ts +1 -1
  182. package/src/contexts/themeContext/utils/theme.ts +2 -0
  183. package/src/hooks/useAfterKeyboardOpenCallback.ts +1 -4
  184. package/src/i18n/en.json +3 -2
  185. package/src/i18n/es.json +3 -2
  186. package/src/i18n/fr.json +3 -2
  187. package/src/i18n/he.json +3 -2
  188. package/src/i18n/hi.json +3 -2
  189. package/src/i18n/it.json +3 -2
  190. package/src/i18n/ja.json +3 -2
  191. package/src/i18n/ko.json +3 -2
  192. package/src/i18n/nl.json +3 -2
  193. package/src/i18n/pt-br.json +3 -2
  194. package/src/i18n/ru.json +3 -2
  195. package/src/i18n/tr.json +3 -2
  196. package/src/version.json +1 -1
@@ -22,7 +22,7 @@ import { Button } from '../../ui/';
22
22
 
23
23
  export type GiphyPropsWithContext = Pick<
24
24
  MessageContextValue,
25
- 'handleAction' | 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress'
25
+ 'handleAction' | 'isMyMessage' | 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress'
26
26
  > &
27
27
  Pick<MessagesContextValue, 'additionalPressableProps' | 'giphyVersion'> & {
28
28
  attachment: Attachment;
@@ -34,6 +34,7 @@ const GiphyWithContext = (props: GiphyPropsWithContext) => {
34
34
  attachment,
35
35
  giphyVersion,
36
36
  handleAction,
37
+ isMyMessage,
37
38
  onLongPress,
38
39
  onPress,
39
40
  onPressIn,
@@ -53,7 +54,7 @@ const GiphyWithContext = (props: GiphyPropsWithContext) => {
53
54
  },
54
55
  } = useTheme();
55
56
 
56
- const styles = useStyles();
57
+ const styles = useStyles({ isMyMessage });
57
58
 
58
59
  const uri = image_url || thumb_url;
59
60
 
@@ -122,7 +123,7 @@ const GiphyWithContext = (props: GiphyPropsWithContext) => {
122
123
  }
123
124
  }}
124
125
  testID='giphy-attachment'
125
- style={styles.container}
126
+ style={[styles.container, container]}
126
127
  {...additionalPressableProps}
127
128
  >
128
129
  <GiphyImage attachment={attachment} giphyVersion={giphyVersion} />
@@ -134,10 +135,12 @@ const areEqual = (prevProps: GiphyPropsWithContext, nextProps: GiphyPropsWithCon
134
135
  const {
135
136
  attachment: { actions: prevActions, image_url: prevImageUrl, thumb_url: prevThumbUrl },
136
137
  giphyVersion: prevGiphyVersion,
138
+ isMyMessage: prevIsMyMessage,
137
139
  } = prevProps;
138
140
  const {
139
141
  attachment: { actions: nextActions, image_url: nextImageUrl, thumb_url: nextThumbUrl },
140
142
  giphyVersion: nextGiphyVersion,
143
+ isMyMessage: nextIsMyMessage,
141
144
  } = nextProps;
142
145
 
143
146
  const imageUrlEqual = prevImageUrl === nextImageUrl;
@@ -165,6 +168,11 @@ const areEqual = (prevProps: GiphyPropsWithContext, nextProps: GiphyPropsWithCon
165
168
  return false;
166
169
  }
167
170
 
171
+ const isMyMessageEqual = prevIsMyMessage === nextIsMyMessage;
172
+ if (!isMyMessageEqual) {
173
+ return false;
174
+ }
175
+
168
176
  return true;
169
177
  };
170
178
 
@@ -178,7 +186,8 @@ export type GiphyProps = Partial<GiphyPropsWithContext> & {
178
186
  * UI component for card in attachments.
179
187
  */
180
188
  export const Giphy = (props: GiphyProps) => {
181
- const { handleAction, onLongPress, onPress, onPressIn, preventPress } = useMessageContext();
189
+ const { handleAction, isMyMessage, onLongPress, onPress, onPressIn, preventPress } =
190
+ useMessageContext();
182
191
  const { additionalPressableProps, giphyVersion } = useMessagesContext();
183
192
 
184
193
  return (
@@ -187,6 +196,7 @@ export const Giphy = (props: GiphyProps) => {
187
196
  additionalPressableProps,
188
197
  giphyVersion,
189
198
  handleAction,
199
+ isMyMessage,
190
200
  onLongPress,
191
201
  onPress,
192
202
  onPressIn,
@@ -199,14 +209,16 @@ export const Giphy = (props: GiphyProps) => {
199
209
 
200
210
  Giphy.displayName = 'Giphy{messageItemView{giphy}}';
201
211
 
202
- const useStyles = () => {
212
+ const useStyles = ({ isMyMessage }: Pick<GiphyPropsWithContext, 'isMyMessage'>) => {
203
213
  const {
204
214
  theme: { semantics },
205
215
  } = useTheme();
206
216
  return useMemo(() => {
207
217
  return StyleSheet.create({
208
218
  container: {
209
- backgroundColor: semantics.chatBgOutgoing,
219
+ backgroundColor: isMyMessage
220
+ ? semantics.chatBgAttachmentOutgoing
221
+ : semantics.chatBgAttachmentIncoming,
210
222
  borderRadius: primitives.radiusLg,
211
223
  maxWidth: 256, // TODO: Not sure how to fix this
212
224
  overflow: 'hidden',
@@ -240,5 +252,5 @@ const useStyles = () => {
240
252
  lineHeight: primitives.typographyLineHeightTight,
241
253
  },
242
254
  });
243
- }, [semantics]);
255
+ }, [isMyMessage, semantics]);
244
256
  };
@@ -14,7 +14,7 @@ import { MessageProvider } from '../../../contexts/messageContext/MessageContext
14
14
  import { MessagesProvider } from '../../../contexts/messagesContext/MessagesContext';
15
15
  import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvider';
16
16
 
17
- import { ThemeProvider } from '../../../contexts/themeContext/ThemeContext';
17
+ import { mergeThemes, ThemeProvider } from '../../../contexts/themeContext/ThemeContext';
18
18
  import { getOrCreateChannelApi } from '../../../mock-builders/api/getOrCreateChannel';
19
19
  import { useMockedApis } from '../../../mock-builders/api/useMockedApis';
20
20
  import { generateGiphyAttachment } from '../../../mock-builders/generator/attachment';
@@ -36,6 +36,8 @@ const streami18n = new Streami18n({
36
36
  });
37
37
 
38
38
  describe('Giphy', () => {
39
+ const lightTheme = mergeThemes({ scheme: 'light' });
40
+
39
41
  const getAttachmentComponent = (props, messageContextValue = {}) => {
40
42
  const message = generateMessage();
41
43
  return (
@@ -115,6 +117,36 @@ describe('Giphy', () => {
115
117
  });
116
118
  });
117
119
 
120
+ it('uses the outgoing attachment background for outgoing giphys', async () => {
121
+ render(getAttachmentComponent({ attachment }, { isMyMessage: true }));
122
+
123
+ await waitFor(() => {
124
+ const style = screen.getByTestId('giphy-attachment').props.style;
125
+ expect(style).toEqual(
126
+ expect.arrayContaining([
127
+ expect.objectContaining({
128
+ backgroundColor: lightTheme.semantics.chatBgAttachmentOutgoing,
129
+ }),
130
+ ]),
131
+ );
132
+ });
133
+ });
134
+
135
+ it('uses the incoming attachment background for incoming giphys', async () => {
136
+ render(getAttachmentComponent({ attachment }, { isMyMessage: false }));
137
+
138
+ await waitFor(() => {
139
+ const style = screen.getByTestId('giphy-attachment').props.style;
140
+ expect(style).toEqual(
141
+ expect.arrayContaining([
142
+ expect.objectContaining({
143
+ backgroundColor: lightTheme.semantics.chatBgAttachmentIncoming,
144
+ }),
145
+ ]),
146
+ );
147
+ });
148
+ });
149
+
118
150
  it('"giphy" attachment size should be customisable', async () => {
119
151
  attachment.giphy = giphy;
120
152
  render(getAttachmentComponent({ attachment, giphyVersion: 'fixed_height' }));
@@ -201,7 +201,7 @@ export const AttachmentCameraPicker = (
201
201
  onPress={openCameraPicker}
202
202
  height={height}
203
203
  buttonText={t('Open Camera')}
204
- description={t('Take a video and share')}
204
+ description={t(videoOnly ? 'Take a video and share' : 'Take a photo and share')}
205
205
  />
206
206
  );
207
207
  };
@@ -216,8 +216,8 @@ export const AttachmentFilePicker = (props: AttachmentPickerContentProps) => {
216
216
  Icon={FilePickerIcon}
217
217
  onPress={pickFile}
218
218
  height={height}
219
- buttonText={t('Pick document')}
220
- description={t('Pick a document to share it with everyone')}
219
+ buttonText={t('Open Files')}
220
+ description={t('Select files to share')}
221
221
  />
222
222
  );
223
223
  };
@@ -21,12 +21,20 @@ const useStyles = () => {
21
21
  paddingHorizontal: primitives.spacing2xl,
22
22
  paddingBottom: primitives.spacing3xl,
23
23
  },
24
- infoContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
24
+ infoContainer: {
25
+ flex: 1,
26
+ gap: primitives.spacingSm,
27
+ alignItems: 'center',
28
+ justifyContent: 'center',
29
+ },
30
+ actionContainer: {
31
+ gap: primitives.spacingMd,
32
+ alignItems: 'center',
33
+ justifyContent: 'center',
34
+ },
25
35
  text: {
26
36
  fontSize: primitives.typographyFontSizeMd,
27
37
  color: semantics.textSecondary,
28
- marginTop: 8,
29
- marginHorizontal: 24,
30
38
  textAlign: 'center',
31
39
  maxWidth: 200,
32
40
  },
@@ -54,13 +62,13 @@ export const AttachmentPickerGenericContent = (props: AttachmentPickerGenericCon
54
62
  theme: {
55
63
  semantics,
56
64
  attachmentPicker: {
57
- content: { container, text, infoContainer },
65
+ content: { actionContainer, container, text, infoContainer },
58
66
  },
59
67
  },
60
68
  } = useTheme();
61
69
 
62
70
  const ThemedIcon = useCallback(
63
- () => <Icon width={22} height={22} stroke={semantics.textTertiary} />,
71
+ () => <Icon width={32} height={32} stroke={semantics.textTertiary} />,
64
72
  [Icon, semantics.textTertiary],
65
73
  );
66
74
 
@@ -76,15 +84,17 @@ export const AttachmentPickerGenericContent = (props: AttachmentPickerGenericCon
76
84
  >
77
85
  <View style={[styles.infoContainer, infoContainer]}>
78
86
  <ThemedIcon />
79
- <Text style={[styles.text, text]}>{description}</Text>
87
+ <View style={[styles.actionContainer, actionContainer]}>
88
+ <Text style={[styles.text, text]}>{description}</Text>
89
+ <Button
90
+ variant={'secondary'}
91
+ type={'outline'}
92
+ size={'md'}
93
+ label={buttonText}
94
+ onPress={onPress}
95
+ />
96
+ </View>
80
97
  </View>
81
- <Button
82
- variant={'secondary'}
83
- type={'outline'}
84
- size={'lg'}
85
- label={buttonText}
86
- onPress={onPress}
87
- />
88
98
  </View>
89
99
  );
90
100
  };
@@ -1,5 +1,7 @@
1
1
  import React, { useCallback, useMemo } from 'react';
2
- import { FlatList, StyleSheet } from 'react-native';
2
+ import { StyleSheet } from 'react-native';
3
+
4
+ import { FlatList } from 'react-native-gesture-handler';
3
5
 
4
6
  import Animated, { LinearTransition, ZoomIn, ZoomOut } from 'react-native-reanimated';
5
7
 
@@ -141,7 +141,7 @@ const useStyles = () => {
141
141
  flexDirection: 'row',
142
142
  padding: primitives.spacingSm,
143
143
  gap: primitives.spacingSm,
144
- backgroundColor: semantics.backgroundCoreElevation1,
144
+ backgroundColor: 'transparent',
145
145
  ...header.container,
146
146
  },
147
147
  headerMeta: {
@@ -104,7 +104,9 @@ export const ChannelPreviewMessage = (props: ChannelPreviewMessageProps) => {
104
104
  return (
105
105
  <View style={styles.container}>
106
106
  <PollIcon height={16} width={16} stroke={semantics.textSecondary} />
107
- <Text style={styles.subtitle}>{pollLabel}</Text>
107
+ <Text ellipsizeMode='tail' numberOfLines={1} style={styles.subtitle}>
108
+ {pollLabel}
109
+ </Text>
108
110
  </View>
109
111
  );
110
112
  }
@@ -12,6 +12,7 @@ import type {
12
12
  ImageGalleryAsset,
13
13
  ImageGalleryState,
14
14
  } from '../../../state-store/image-gallery-state-store';
15
+ import { primitives } from '../../../theme';
15
16
  import { FileTypes } from '../../../types/types';
16
17
  import { StreamBottomSheetModalFlatList } from '../../UIComponents/StreamBottomSheetModalFlatList';
17
18
 
@@ -108,8 +109,9 @@ const useStyles = () => {
108
109
  return StyleSheet.create({
109
110
  contentContainer: {
110
111
  flexGrow: 1,
111
- ...contentContainer,
112
112
  backgroundColor: semantics.backgroundCoreApp,
113
+ marginTop: primitives.spacingSm,
114
+ ...contentContainer,
113
115
  },
114
116
  image: { margin: 1, ...gridImage },
115
117
  });
@@ -6,7 +6,7 @@ import { useTranslationContext } from '../../contexts/translationContext/Transla
6
6
  import { primitives } from '../../theme';
7
7
  import { Spinner } from '../UIComponents/Spinner';
8
8
 
9
- type LoadingIndicatorWrapperProps = { text: string };
9
+ type LoadingIndicatorWrapperProps = { text: string | undefined };
10
10
 
11
11
  const LoadingIndicatorWrapper = ({ text }: LoadingIndicatorWrapperProps) => {
12
12
  const styles = useStyles();
@@ -14,9 +14,11 @@ const LoadingIndicatorWrapper = ({ text }: LoadingIndicatorWrapperProps) => {
14
14
  return (
15
15
  <View style={styles.container}>
16
16
  <Spinner height={20} width={20} />
17
- <Text style={styles.loadingText} testID='loading'>
18
- {text}
19
- </Text>
17
+ {text ? (
18
+ <Text style={styles.loadingText} testID='loading'>
19
+ {text}
20
+ </Text>
21
+ ) : null}
20
22
  </View>
21
23
  );
22
24
  };
@@ -44,7 +46,7 @@ export const LoadingIndicator = (props: LoadingProps) => {
44
46
  case 'message':
45
47
  return <LoadingIndicatorWrapper text={t('Loading messages...')} />;
46
48
  case 'threads':
47
- return <LoadingIndicatorWrapper text={t('Loading threads...')} />;
49
+ return <LoadingIndicatorWrapper text={undefined} />;
48
50
  default:
49
51
  return <LoadingIndicatorWrapper text={t('Loading...')} />;
50
52
  }
@@ -381,21 +381,12 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
381
381
  }
382
382
  };
383
383
 
384
- const onPressQuotedMessage = (quotedMessage: LocalMessage) => {
385
- if (!goToMessage) {
386
- return;
387
- }
388
-
389
- goToMessage(quotedMessage.id);
390
- };
391
-
392
384
  const errorOrFailed = message.type === 'error' || message.status === MessageStatusTypes.FAILED;
393
385
 
394
386
  const onPress = (error = errorOrFailed) => {
395
387
  if (dismissKeyboardOnMessageTouch) {
396
388
  dismissKeyboard();
397
389
  }
398
- const quotedMessage = message.quoted_message;
399
390
  if (error) {
400
391
  /**
401
392
  * If its a Blocked message, we don't do anything as per specs.
@@ -411,8 +402,6 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
411
402
  return;
412
403
  }
413
404
  showMessageOverlay();
414
- } else if (quotedMessage) {
415
- onPressQuotedMessage(quotedMessage);
416
405
  }
417
406
  };
418
407
 
@@ -121,6 +121,7 @@ const MessageContentWithContext = (props: MessageContentPropsWithContext) => {
121
121
  FileAttachmentGroup,
122
122
  Gallery,
123
123
  groupStyles,
124
+ goToMessage,
124
125
  isMessageAIGenerated,
125
126
  isMyMessage,
126
127
  isVeryLastMessage,
@@ -221,7 +222,6 @@ const MessageContentWithContext = (props: MessageContentPropsWithContext) => {
221
222
 
222
223
  const { setNativeScrollability } = useMessageListItemContext();
223
224
  const hasContentSideViews = !!(MessageContentLeadingView || MessageContentTrailingView);
224
-
225
225
  const contentBody = (
226
226
  <>
227
227
  <View
@@ -240,12 +240,45 @@ const MessageContentWithContext = (props: MessageContentPropsWithContext) => {
240
240
  case 'quoted_reply':
241
241
  return (
242
242
  message.quoted_message && (
243
- <View
243
+ <Pressable
244
+ disabled={!goToMessage}
244
245
  key={`quoted_reply_${messageContentOrderIndex}`}
246
+ onLongPress={(event) => {
247
+ if (onLongPress) {
248
+ onLongPress({
249
+ emitter: 'messageContent',
250
+ event,
251
+ });
252
+ }
253
+ }}
254
+ onPress={(event) => {
255
+ if (!message.quoted_message || !goToMessage) {
256
+ return;
257
+ }
258
+
259
+ if (onPress) {
260
+ onPress({
261
+ defaultHandler: () => goToMessage(message.quoted_message!.id),
262
+ emitter: 'messageContent',
263
+ event,
264
+ });
265
+ return;
266
+ }
267
+
268
+ goToMessage(message.quoted_message.id);
269
+ }}
270
+ onPressIn={(event) => {
271
+ if (onPressIn) {
272
+ onPressIn({
273
+ emitter: 'messageContent',
274
+ event,
275
+ });
276
+ }
277
+ }}
245
278
  style={[styles.replyContainer, replyContainer]}
246
279
  >
247
280
  <Reply mode='reply' styles={replyStyles} />
248
- </View>
281
+ </Pressable>
249
282
  )
250
283
  );
251
284
  case 'attachments':
@@ -584,7 +617,8 @@ export const MessageContent = (props: MessageContentProps) => {
584
617
  const messageHasSingleFile =
585
618
  messageContentOrder.length === 1 && messageContentOrder[0] === 'files' && isSingleFile;
586
619
  const messageHasOnlyText = messageContentOrder.length === 1 && messageContentOrder[0] === 'text';
587
- const messageHasGiphyOrImgur =
620
+ const messageHasStandaloneGiphyOrImgur =
621
+ !message.quoted_message &&
588
622
  otherAttachments.filter(
589
623
  (file) => file.type === FileTypes.Giphy || file.type === FileTypes.Imgur,
590
624
  ).length > 0;
@@ -594,17 +628,20 @@ export const MessageContent = (props: MessageContentProps) => {
594
628
  messageHasSingleMedia ||
595
629
  messageHasSingleFile ||
596
630
  messageHasOnlyText ||
597
- messageHasGiphyOrImgur;
631
+ messageHasStandaloneGiphyOrImgur;
598
632
 
599
633
  const hidePaddingHorizontal =
600
- messageHasPoll || messageHasSingleMedia || messageHasSingleFile || messageHasGiphyOrImgur;
634
+ messageHasPoll ||
635
+ messageHasSingleMedia ||
636
+ messageHasSingleFile ||
637
+ messageHasStandaloneGiphyOrImgur;
601
638
 
602
639
  const hidePaddingBottom =
603
640
  messageHasPoll ||
604
641
  messageHasSingleMedia ||
605
642
  messageHasSingleFile ||
606
643
  messageHasOnlyText ||
607
- messageHasGiphyOrImgur ||
644
+ messageHasStandaloneGiphyOrImgur ||
608
645
  (messageContentOrder.length > 1 &&
609
646
  messageContentOrder[messageContentOrder.length - 1] === 'text');
610
647
 
@@ -17,6 +17,7 @@ import { useTheme } from '../../../contexts/themeContext/ThemeContext';
17
17
  import { useStableCallback } from '../../../hooks/useStableCallback';
18
18
 
19
19
  import { primitives } from '../../../theme';
20
+ import { FileTypes } from '../../../types/types';
20
21
  import { checkMessageEquality, checkQuotedMessageEquality } from '../../../utils/utils';
21
22
  import { useMessageData } from '../hooks/useMessageData';
22
23
 
@@ -293,10 +294,14 @@ const MessageItemViewWithContext = (props: MessageItemViewPropsWithContext) => {
293
294
  });
294
295
 
295
296
  const groupStyle = `${alignment}_${groupStyles?.[0]?.toLowerCase?.()}`;
297
+ const hasStandaloneGiphyOrImgur =
298
+ !message.quoted_message &&
299
+ otherAttachments.length > 0 &&
300
+ (otherAttachments[0].type === FileTypes.Giphy || otherAttachments[0].type === FileTypes.Imgur);
296
301
 
297
302
  let noBorder = onlyEmojis && !message.quoted_message;
298
303
  if (otherAttachments.length) {
299
- if (otherAttachments[0].type === 'giphy' && !isMyMessage) {
304
+ if (hasStandaloneGiphyOrImgur && !isMyMessage) {
300
305
  noBorder = false;
301
306
  } else {
302
307
  noBorder = true;
@@ -306,10 +311,8 @@ const MessageItemViewWithContext = (props: MessageItemViewPropsWithContext) => {
306
311
  let backgroundColor = semantics.chatBgOutgoing;
307
312
  if (onlyEmojis && !message.quoted_message) {
308
313
  backgroundColor = 'transparent';
309
- } else if (otherAttachments.length) {
310
- if (otherAttachments[0].type === 'giphy') {
311
- backgroundColor = 'transparent';
312
- }
314
+ } else if (hasStandaloneGiphyOrImgur) {
315
+ backgroundColor = 'transparent';
313
316
  } else if (isMessageReceivedOrErrorType) {
314
317
  backgroundColor = semantics.chatBgIncoming;
315
318
  }
@@ -235,7 +235,7 @@ const useStyles = () => {
235
235
  gap: primitives.spacingXs,
236
236
  },
237
237
  messageRepliesText: {
238
- color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textPrimary,
238
+ color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.textLink,
239
239
  fontSize: primitives.typographyFontSizeSm,
240
240
  fontWeight: primitives.typographyFontWeightSemiBold,
241
241
  lineHeight: primitives.typographyLineHeightTight,
@@ -29,7 +29,6 @@ const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => {
29
29
  messageItemView: {
30
30
  status: { checkAllIcon, checkIcon, container, timeIcon },
31
31
  },
32
- semantics,
33
32
  },
34
33
  } = useTheme();
35
34
 
@@ -54,14 +53,14 @@ const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => {
54
53
  {read ? (
55
54
  <CheckAll
56
55
  height={16}
57
- stroke={semantics.accentPrimary}
56
+ stroke={styles.readCheck.color}
58
57
  width={16}
59
58
  accessibilityLabel='Read'
60
59
  {...checkAllIcon}
61
60
  />
62
61
  ) : delivered ? (
63
62
  <CheckAll
64
- stroke={semantics.chatTextTimestamp}
63
+ stroke={styles.deliveredCheck.color}
65
64
  height={16}
66
65
  width={16}
67
66
  accessibilityLabel='Delivered'
@@ -69,7 +68,7 @@ const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => {
69
68
  />
70
69
  ) : sending ? (
71
70
  <Time
72
- stroke={semantics.chatTextTimestamp}
71
+ stroke={styles.sendingCheck.color}
73
72
  height={16}
74
73
  width={16}
75
74
  accessibilityLabel='Sending'
@@ -77,7 +76,7 @@ const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => {
77
76
  />
78
77
  ) : sent ? (
79
78
  <Check
80
- stroke={semantics.chatTextTimestamp}
79
+ stroke={styles.sentCheck.color}
81
80
  height={16}
82
81
  width={16}
83
82
  accessibilityLabel='Sent'
@@ -162,6 +161,18 @@ const useStyles = () => {
162
161
  flexDirection: 'row',
163
162
  gap: primitives.spacingXxs,
164
163
  },
164
+ readCheck: {
165
+ color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.accentPrimary,
166
+ },
167
+ deliveredCheck: {
168
+ color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
169
+ },
170
+ sendingCheck: {
171
+ color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
172
+ },
173
+ sentCheck: {
174
+ color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
175
+ },
165
176
  });
166
177
  }, [shouldUseOverlayStyles, semantics]);
167
178
  };
@@ -7,7 +7,10 @@ import { ChannelsStateProvider } from '../../../../contexts/channelsStateContext
7
7
 
8
8
  import { getOrCreateChannelApi } from '../../../../mock-builders/api/getOrCreateChannel';
9
9
  import { useMockedApis } from '../../../../mock-builders/api/useMockedApis';
10
- import { generateVideoAttachment } from '../../../../mock-builders/generator/attachment';
10
+ import {
11
+ generateGiphyAttachment,
12
+ generateVideoAttachment,
13
+ } from '../../../../mock-builders/generator/attachment';
11
14
  import { generateChannelResponse } from '../../../../mock-builders/generator/channel';
12
15
  import { generateMember } from '../../../../mock-builders/generator/member';
13
16
  import { generateMessage } from '../../../../mock-builders/generator/message';
@@ -326,6 +329,46 @@ describe('MessageContent', () => {
326
329
  expect(contentContainerStyle.paddingBottom).toBe(0);
327
330
  });
328
331
 
332
+ it('keeps content padding for a quoted reply with a giphy attachment', async () => {
333
+ const user = generateUser();
334
+ const message = generateMessage({
335
+ attachments: [generateGiphyAttachment()],
336
+ quoted_message: generateMessage({ text: 'quoted message', user }),
337
+ text: '',
338
+ user,
339
+ });
340
+
341
+ renderMessage({ message });
342
+
343
+ await waitFor(() => {
344
+ expect(screen.getByTestId('message-content-wrapper')).toBeTruthy();
345
+ expect(screen.getByTestId('giphy-attachment')).toBeTruthy();
346
+ });
347
+
348
+ const giphyAttachment = screen.getByTestId('giphy-attachment');
349
+ let ancestor = giphyAttachment.parent;
350
+ let contentContainerStyle;
351
+
352
+ while (ancestor && !contentContainerStyle) {
353
+ const flattenedStyle = StyleSheet.flatten(ancestor.props.style);
354
+ if (
355
+ flattenedStyle &&
356
+ 'paddingTop' in flattenedStyle &&
357
+ 'paddingHorizontal' in flattenedStyle &&
358
+ 'paddingBottom' in flattenedStyle
359
+ ) {
360
+ contentContainerStyle = flattenedStyle;
361
+ break;
362
+ }
363
+ ancestor = ancestor.parent;
364
+ }
365
+
366
+ expect(contentContainerStyle).toBeTruthy();
367
+ expect(contentContainerStyle.paddingTop).toBeGreaterThan(0);
368
+ expect(contentContainerStyle.paddingHorizontal).toBeGreaterThan(0);
369
+ expect(contentContainerStyle.paddingBottom).toBeGreaterThan(0);
370
+ });
371
+
329
372
  it('renders the FileAttachment component when a file attachment exists', async () => {
330
373
  const user = generateUser();
331
374
  const message = generateMessage({
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- import { Text } from 'react-native';
3
+ import { StyleSheet, Text } from 'react-native';
4
4
  import { GestureDetector } from 'react-native-gesture-handler';
5
5
 
6
6
  import { cleanup, render, screen, waitFor } from '@testing-library/react-native';
@@ -10,6 +10,7 @@ import { useMessageContext } from '../../../../contexts/messageContext/MessageCo
10
10
 
11
11
  import { getOrCreateChannelApi } from '../../../../mock-builders/api/getOrCreateChannel';
12
12
  import { useMockedApis } from '../../../../mock-builders/api/useMockedApis';
13
+ import { generateGiphyAttachment } from '../../../../mock-builders/generator/attachment';
13
14
  import { generateChannelResponse } from '../../../../mock-builders/generator/channel';
14
15
  import { generateMember } from '../../../../mock-builders/generator/member';
15
16
  import { generateMessage } from '../../../../mock-builders/generator/message';
@@ -256,4 +257,23 @@ describe('MessageItemView', () => {
256
257
  });
257
258
  });
258
259
  });
260
+
261
+ it('keeps the message shell background for a quoted reply with a giphy attachment', async () => {
262
+ const user = generateUser();
263
+ const message = generateMessage({
264
+ attachments: [generateGiphyAttachment()],
265
+ quoted_message: generateMessage({ text: 'quoted message', user }),
266
+ text: '',
267
+ user,
268
+ });
269
+
270
+ renderMessage({ message });
271
+
272
+ await waitFor(() => {
273
+ const wrapperStyle = StyleSheet.flatten(
274
+ screen.getByTestId('message-content-wrapper').props.style,
275
+ );
276
+ expect(wrapperStyle.backgroundColor).not.toBe('transparent');
277
+ });
278
+ });
259
279
  });
@@ -4,6 +4,9 @@ describe('generateMarkdownText', () => {
4
4
  it.each([
5
5
  ['', null],
6
6
  [' test message ', 'test message'],
7
+ ['\uFFFC', ''],
8
+ [' \uFFFC ', ''],
9
+ ['hello\uFFFCworld', 'hello world'],
7
10
  ['https://www.getstream.io', '[https://www.getstream.io](https://www.getstream.io)'],
8
11
  [
9
12
  'https://getstream-production.s3-accelerate.amazonaws.com/N336903591601695/33e78ef89e64642862a75c5cca2541eaf6b1c924/trimmedVideos/alert/2_270_881/outputVideo.mp4?AWSAccessKeyId=AKIAVJAW2AD2SQVQCBXV&Expires=1699998768&Signature=zdEMCGzf4Pq++16YkPprvN5NAds=',