stream-chat-react-native-core 4.12.0-beta.2 → 4.12.0-beta.5

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 (98) hide show
  1. package/lib/commonjs/components/{MessageInput/AudioAttachmentUploadPreview.js → Attachment/AudioAttachment.js} +38 -64
  2. package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -0
  3. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js +132 -12
  4. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js.map +1 -1
  5. package/lib/commonjs/components/Attachment/Gallery.js +22 -18
  6. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  7. package/lib/commonjs/components/Attachment/VideoThumbnail.js +12 -6
  8. package/lib/commonjs/components/Attachment/VideoThumbnail.js.map +1 -1
  9. package/lib/commonjs/components/Channel/Channel.js +18 -18
  10. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  11. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js +0 -2
  12. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  13. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +2 -0
  14. package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  15. package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js +11 -10
  16. package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
  17. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +38 -44
  18. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  19. package/lib/commonjs/components/MessageOverlay/MessageOverlay.js +14 -13
  20. package/lib/commonjs/components/MessageOverlay/MessageOverlay.js.map +1 -1
  21. package/lib/commonjs/components/index.js +13 -13
  22. package/lib/commonjs/components/index.js.map +1 -1
  23. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +2 -2
  24. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  25. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +0 -2
  26. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  27. package/lib/commonjs/contexts/messagesContext/MessagesContext.js +2 -2
  28. package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
  29. package/lib/commonjs/contexts/themeContext/utils/theme.js +2 -2
  30. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  31. package/lib/commonjs/version.json +1 -1
  32. package/lib/module/components/{MessageInput/AudioAttachmentUploadPreview.js → Attachment/AudioAttachment.js} +38 -64
  33. package/lib/module/components/Attachment/AudioAttachment.js.map +1 -0
  34. package/lib/module/components/Attachment/FileAttachmentGroup.js +132 -12
  35. package/lib/module/components/Attachment/FileAttachmentGroup.js.map +1 -1
  36. package/lib/module/components/Attachment/Gallery.js +22 -18
  37. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  38. package/lib/module/components/Attachment/VideoThumbnail.js +12 -6
  39. package/lib/module/components/Attachment/VideoThumbnail.js.map +1 -1
  40. package/lib/module/components/Channel/Channel.js +18 -18
  41. package/lib/module/components/Channel/Channel.js.map +1 -1
  42. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js +0 -2
  43. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  44. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +2 -0
  45. package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
  46. package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js +11 -10
  47. package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
  48. package/lib/module/components/MessageInput/FileUploadPreview.js +38 -44
  49. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  50. package/lib/module/components/MessageOverlay/MessageOverlay.js +14 -13
  51. package/lib/module/components/MessageOverlay/MessageOverlay.js.map +1 -1
  52. package/lib/module/components/index.js +13 -13
  53. package/lib/module/components/index.js.map +1 -1
  54. package/lib/module/contexts/messageInputContext/MessageInputContext.js +2 -2
  55. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  56. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +0 -2
  57. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  58. package/lib/module/contexts/messagesContext/MessagesContext.js +2 -2
  59. package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
  60. package/lib/module/contexts/themeContext/utils/theme.js +2 -2
  61. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  62. package/lib/module/version.json +1 -1
  63. package/lib/typescript/components/Attachment/AudioAttachment.d.ts +23 -0
  64. package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts +1 -1
  65. package/lib/typescript/components/Channel/Channel.d.ts +1 -1
  66. package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +1 -1
  67. package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +1 -1
  68. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts +1 -1
  69. package/lib/typescript/components/index.d.ts +1 -1
  70. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +1 -1
  71. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +1 -4
  72. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
  73. package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +3 -0
  74. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +2 -2
  75. package/package.json +1 -1
  76. package/src/components/{MessageInput/AudioAttachmentUploadPreview.tsx → Attachment/AudioAttachment.tsx} +82 -131
  77. package/src/components/Attachment/FileAttachmentGroup.tsx +119 -9
  78. package/src/components/Attachment/Gallery.tsx +7 -1
  79. package/src/components/Attachment/VideoThumbnail.tsx +3 -2
  80. package/src/components/Channel/Channel.tsx +4 -3
  81. package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +0 -2
  82. package/src/components/Channel/hooks/useCreateMessagesContext.ts +2 -0
  83. package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx +12 -7
  84. package/src/components/Message/MessageSimple/__tests__/MessageContent.test.js +4 -2
  85. package/src/components/MessageInput/FileUploadPreview.tsx +34 -26
  86. package/src/components/MessageInput/__tests__/AudioAttachmentUploadPreviewExpo.test.tsx +15 -8
  87. package/src/components/MessageInput/__tests__/AudioAttachmentUploadPreviewNative.test.tsx +15 -8
  88. package/src/components/MessageInput/__tests__/FileUploadPreview.test.js +5 -5
  89. package/src/components/MessageOverlay/MessageOverlay.tsx +1 -0
  90. package/src/components/index.ts +1 -1
  91. package/src/contexts/messageInputContext/MessageInputContext.tsx +0 -6
  92. package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +0 -2
  93. package/src/contexts/messagesContext/MessagesContext.tsx +3 -0
  94. package/src/contexts/themeContext/utils/theme.ts +4 -4
  95. package/src/version.json +1 -1
  96. package/lib/commonjs/components/MessageInput/AudioAttachmentUploadPreview.js.map +0 -1
  97. package/lib/module/components/MessageInput/AudioAttachmentUploadPreview.js.map +0 -1
  98. package/lib/typescript/components/MessageInput/AudioAttachmentUploadPreview.d.ts +0 -26
@@ -243,12 +243,12 @@ export declare type Theme = {
243
243
  editingBoxHeaderTitle: TextStyle;
244
244
  };
245
245
  fileUploadPreview: {
246
- audioAttachmentFileContainer: ViewStyle;
247
- audioAttachmentUploadPreview: {
246
+ audioAttachment: {
248
247
  progressControlView: ViewStyle;
249
248
  progressDurationText: TextStyle;
250
249
  roundedView: ViewStyle;
251
250
  };
251
+ audioAttachmentFileContainer: ViewStyle;
252
252
  dismiss: ViewStyle;
253
253
  fileContainer: ViewStyle;
254
254
  fileContentContainer: ViewStyle;
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.12.0-beta.2",
4
+ "version": "4.12.0-beta.5",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -4,12 +4,7 @@ import { I18nManager, StyleSheet, Text, TouchableOpacity, View } from 'react-nat
4
4
  import dayjs from 'dayjs';
5
5
  import duration from 'dayjs/plugin/duration';
6
6
 
7
- import {
8
- FileUpload,
9
- MessageInputContextValue,
10
- useMessageInputContext,
11
- useTheme,
12
- } from '../../contexts';
7
+ import { FileUpload, useTheme } from '../../contexts';
13
8
  import { Pause, Play } from '../../icons';
14
9
  import {
15
10
  PlaybackStatus,
@@ -18,7 +13,6 @@ import {
18
13
  VideoPayloadData,
19
14
  VideoProgressData,
20
15
  } from '../../native';
21
- import type { DefaultStreamChatGenerics } from '../../types/types';
22
16
  import { ProgressControl } from '../ProgressControl/ProgressControl';
23
17
 
24
18
  dayjs.extend(duration);
@@ -34,7 +28,7 @@ const styles = StyleSheet.create({
34
28
  paddingLeft: 8,
35
29
  paddingRight: 8,
36
30
  },
37
- fileContentContainer: { flexDirection: 'row' },
31
+ fileContentContainer: { flexDirection: 'row', paddingRight: 40 },
38
32
  filenameText: {
39
33
  fontSize: 14,
40
34
  fontWeight: 'bold',
@@ -76,27 +70,17 @@ const styles = StyleSheet.create({
76
70
  },
77
71
  });
78
72
 
79
- export type AudioAttachmentUploadPreviewPropsWithContext<
80
- StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
81
- > = Pick<
82
- MessageInputContextValue<StreamChatGenerics>,
83
- 'fileUploads' | 'removeFile' | 'uploadFile'
84
- > & {
85
- index: number;
86
- item: FileUpload;
73
+ export type AudioAttachmentPropsWithContext = {
74
+ item: Omit<FileUpload, 'state'>;
87
75
  onLoad: (index: string, duration: number) => void;
88
- onPlayPause: (index: string, status?: boolean) => void;
76
+ onPlayPause: (index: string, pausedStatus?: boolean) => void;
89
77
  onProgress: (index: string, currentTime?: number, hasEnd?: boolean) => void;
90
- testID: string;
78
+ testID?: string;
91
79
  };
92
80
 
93
- const AudioAttachmentUploadPreviewWithContext = <
94
- StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
95
- >(
96
- props: AudioAttachmentUploadPreviewPropsWithContext<StreamChatGenerics>,
97
- ) => {
81
+ const AudioAttachmentWithContext = (props: AudioAttachmentPropsWithContext) => {
98
82
  const soundRef = React.useRef<SoundReturnType | null>(null);
99
- const { fileUploads, index, item, onLoad, onPlayPause, onProgress } = props;
83
+ const { item, onLoad, onPlayPause, onProgress } = props;
100
84
 
101
85
  const handleLoad = (payload: VideoPayloadData) => {
102
86
  onLoad(item.id, payload.duration);
@@ -212,11 +196,10 @@ const AudioAttachmentUploadPreviewWithContext = <
212
196
 
213
197
  const {
214
198
  theme: {
215
- colors: { accent_blue, black, grey_dark, grey_whisper, static_black, static_white },
199
+ colors: { accent_blue, black, grey_dark, static_black, static_white },
216
200
  messageInput: {
217
201
  fileUploadPreview: {
218
- audioAttachmentUploadPreview: { progressControlView, progressDurationText, roundedView },
219
- fileContainer,
202
+ audioAttachment: { progressControlView, progressDurationText, roundedView },
220
203
  fileContentContainer,
221
204
  filenameText,
222
205
  fileTextContainer,
@@ -236,91 +219,74 @@ const AudioAttachmentUploadPreviewWithContext = <
236
219
  const lastIndexOfDot = item.file.name.lastIndexOf('.');
237
220
 
238
221
  return (
239
- <View
240
- style={[
241
- styles.fileContainer,
242
- index === fileUploads.length - 1
243
- ? {
244
- marginBottom: 0,
245
- }
246
- : {},
247
- {
248
- borderColor: grey_whisper,
249
- width: -16,
250
- },
251
- fileContainer,
252
- ]}
253
- testID='audio-attachment-upload-preview'
254
- >
255
- <View style={[styles.fileContentContainer, fileContentContainer]}>
256
- <TouchableOpacity
257
- accessibilityLabel='Play Pause Button'
258
- onPress={() => handlePlayPause()}
222
+ <View style={[styles.fileContentContainer, fileContentContainer]}>
223
+ <TouchableOpacity
224
+ accessibilityLabel='Play Pause Button'
225
+ onPress={() => handlePlayPause()}
226
+ style={[
227
+ styles.roundedView,
228
+ roundedView,
229
+ { backgroundColor: static_white, shadowColor: black },
230
+ ]}
231
+ >
232
+ {item.paused ? (
233
+ <Play height={24} pathFill={static_black} width={24} />
234
+ ) : (
235
+ <Pause height={24} pathFill={static_black} width={24} />
236
+ )}
237
+ </TouchableOpacity>
238
+ <View style={[styles.fileTextContainer, fileTextContainer]}>
239
+ <Text
240
+ accessibilityLabel='File Name'
241
+ numberOfLines={1}
259
242
  style={[
260
- styles.roundedView,
261
- roundedView,
262
- { backgroundColor: static_white, shadowColor: black },
243
+ styles.filenameText,
244
+ {
245
+ color: black,
246
+ width:
247
+ 16 - // 16 = horizontal padding
248
+ 40 - // 40 = file icon size
249
+ 24 - // 24 = close icon size
250
+ 24, // 24 = internal padding
251
+ },
252
+ I18nManager.isRTL ? { writingDirection: 'rtl' } : { writingDirection: 'ltr' },
253
+ filenameText,
263
254
  ]}
264
255
  >
265
- {item.paused ? (
266
- <Play height={24} pathFill={static_black} width={24} />
267
- ) : (
268
- <Pause height={24} pathFill={static_black} width={24} />
256
+ {item.file.name.slice(0, 12) + '...' + item.file.name.slice(lastIndexOfDot)}
257
+ </Text>
258
+ <View
259
+ style={{
260
+ alignItems: 'center',
261
+ display: 'flex',
262
+ flexDirection: 'row',
263
+ }}
264
+ >
265
+ {/* <ExpoSoundPlayer filePaused={!!item.paused} soundRef={soundRef} /> */}
266
+ {Sound.Player && (
267
+ <Sound.Player
268
+ onEnd={handleEnd}
269
+ onLoad={handleLoad}
270
+ onProgress={handleProgress}
271
+ paused={item.paused as boolean}
272
+ soundRef={soundRef}
273
+ testID='sound-player'
274
+ uri={item.file.uri}
275
+ />
269
276
  )}
270
- </TouchableOpacity>
271
- <View style={[styles.fileTextContainer, fileTextContainer]}>
272
- <Text
273
- accessibilityLabel='File Name'
274
- numberOfLines={1}
275
- style={[
276
- styles.filenameText,
277
- {
278
- color: black,
279
- width:
280
- 16 - // 16 = horizontal padding
281
- 40 - // 40 = file icon size
282
- 24 - // 24 = close icon size
283
- 24, // 24 = internal padding
284
- },
285
- I18nManager.isRTL ? { writingDirection: 'rtl' } : { writingDirection: 'ltr' },
286
- filenameText,
287
- ]}
288
- >
289
- {item.file.name.slice(0, 12) + '...' + item.file.name.slice(lastIndexOfDot)}
277
+ <Text style={[styles.progressDurationText, { color: grey_dark }, progressDurationText]}>
278
+ {progressDuration}
290
279
  </Text>
291
- <View
292
- style={{
293
- alignItems: 'center',
294
- display: 'flex',
295
- flexDirection: 'row',
296
- }}
297
- >
298
- {/* <ExpoSoundPlayer filePaused={!!item.paused} soundRef={soundRef} /> */}
299
- {Sound.Player && (
300
- <Sound.Player
301
- onEnd={handleEnd}
302
- onLoad={handleLoad}
303
- onProgress={handleProgress}
304
- paused={item.paused as boolean}
305
- soundRef={soundRef}
306
- testID='sound-player'
307
- uri={item.file.uri}
308
- />
309
- )}
310
- <Text style={[styles.progressDurationText, { color: grey_dark }, progressDurationText]}>
311
- {progressDuration}
312
- </Text>
313
- <View style={[styles.progressControlView, progressControlView]}>
314
- <ProgressControl
315
- duration={item.duration as number}
316
- filledColor={accent_blue}
317
- onPlayPause={handlePlayPause}
318
- onProgressDrag={handleProgressDrag}
319
- progress={item.progress as number}
320
- testID='progress-control'
321
- width={110}
322
- />
323
- </View>
280
+ <View style={[styles.progressControlView, progressControlView]}>
281
+ <ProgressControl
282
+ duration={item.duration as number}
283
+ filledColor={accent_blue}
284
+ onPlayPause={handlePlayPause}
285
+ onProgressDrag={handleProgressDrag}
286
+ progress={item.progress as number}
287
+ testID='progress-control'
288
+ width={120}
289
+ />
324
290
  </View>
325
291
  </View>
326
292
  </View>
@@ -328,35 +294,20 @@ const AudioAttachmentUploadPreviewWithContext = <
328
294
  );
329
295
  };
330
296
 
331
- export type AudioAttachmentUploadPreviewProps<
332
- StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
333
- > = Partial<AudioAttachmentUploadPreviewPropsWithContext<StreamChatGenerics>> & {
334
- index: number;
335
- item: FileUpload;
297
+ export type AudioAttachmentProps = Partial<AudioAttachmentPropsWithContext> & {
298
+ item: Omit<FileUpload, 'state'>;
336
299
  onLoad: (index: string, duration: number) => void;
337
- onPlayPause: (index: string, status?: boolean) => void;
300
+ onPlayPause: (index: string, pausedStatus?: boolean) => void;
338
301
  onProgress: (index: string, currentTime?: number, hasEnd?: boolean) => void;
339
302
  testID: string;
340
303
  };
341
304
 
342
305
  /**
343
- * AudioAttachmentUploadPreview
344
- * UI Component to preview the audio files set for upload
306
+ * AudioAttachment
307
+ * UI Component to preview the audio files
345
308
  */
346
- export const AudioAttachmentUploadPreview = <
347
- StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
348
- >(
349
- props: AudioAttachmentUploadPreviewProps<StreamChatGenerics>,
350
- ) => {
351
- const { fileUploads, removeFile, uploadFile } = useMessageInputContext<StreamChatGenerics>();
352
-
353
- return (
354
- <AudioAttachmentUploadPreviewWithContext
355
- {...{ fileUploads, removeFile, uploadFile }}
356
- {...props}
357
- />
358
- );
359
- };
309
+ export const AudioAttachment = (props: AudioAttachmentProps) => (
310
+ <AudioAttachmentWithContext {...props} />
311
+ );
360
312
 
361
- AudioAttachmentUploadPreview.displayName =
362
- 'AudioAttachmentUploadPreview{messageInput{autoAttachmentUploadPreview}}';
313
+ AudioAttachment.displayName = 'AudioAttachment{messageInput{autoAttachment}}';
@@ -1,30 +1,45 @@
1
- import React from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3
3
 
4
+ import type { Attachment } from 'stream-chat';
5
+
4
6
  import { Attachment as AttachmentDefault } from './Attachment';
5
7
 
6
8
  import {
7
9
  MessageContextValue,
8
10
  useMessageContext,
9
11
  } from '../../contexts/messageContext/MessageContext';
12
+
10
13
  import {
11
14
  MessagesContextValue,
12
15
  useMessagesContext,
13
16
  } from '../../contexts/messagesContext/MessagesContext';
14
17
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
18
+ import { isAudioPackageAvailable } from '../../native';
15
19
 
16
20
  import type { DefaultStreamChatGenerics } from '../../types/types';
17
21
 
22
+ const FILE_PREVIEW_HEIGHT = 60;
23
+
18
24
  const styles = StyleSheet.create({
19
25
  container: {
20
26
  padding: 4,
21
27
  },
28
+ fileContainer: {
29
+ borderRadius: 12,
30
+ borderWidth: 1,
31
+ flexDirection: 'row',
32
+ height: FILE_PREVIEW_HEIGHT,
33
+ justifyContent: 'space-between',
34
+ paddingLeft: 8,
35
+ paddingRight: 8,
36
+ },
22
37
  });
23
38
 
24
39
  export type FileAttachmentGroupPropsWithContext<
25
40
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
26
41
  > = Pick<MessageContextValue<StreamChatGenerics>, 'files'> &
27
- Pick<MessagesContextValue<StreamChatGenerics>, 'Attachment'> & {
42
+ Pick<MessagesContextValue<StreamChatGenerics>, 'Attachment' | 'AudioAttachment'> & {
28
43
  /**
29
44
  * The unique id for the message with file attachments
30
45
  */
@@ -35,15 +50,77 @@ export type FileAttachmentGroupPropsWithContext<
35
50
  }>;
36
51
  };
37
52
 
53
+ type FilesToDisplayType<
54
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
55
+ > = Attachment<StreamChatGenerics> & {
56
+ duration: number;
57
+ paused: boolean;
58
+ progress: number;
59
+ };
60
+
38
61
  const FileAttachmentGroupWithContext = <
39
62
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
40
63
  >(
41
64
  props: FileAttachmentGroupPropsWithContext<StreamChatGenerics>,
42
65
  ) => {
43
- const { Attachment, files, messageId, styles: stylesProp = {} } = props;
66
+ const { Attachment, AudioAttachment, files, messageId, styles: stylesProp = {} } = props;
67
+ const [filesToDisplay, setFilesToDisplay] = useState<FilesToDisplayType[]>([]);
68
+
69
+ useEffect(() => {
70
+ setFilesToDisplay(files.map((file) => ({ ...file, duration: 0, paused: true, progress: 0 })));
71
+ }, [files]);
72
+
73
+ // Handler triggered when an audio is loaded in the message input. The initial state is defined for the audio here and the duration is set.
74
+ const onLoad = (index: string, duration: number) => {
75
+ setFilesToDisplay((prevFilesToDisplay) =>
76
+ prevFilesToDisplay.map((fileToDisplay, id) => ({
77
+ ...fileToDisplay,
78
+ duration: id.toString() === index ? duration : fileToDisplay.duration,
79
+ })),
80
+ );
81
+ };
82
+
83
+ // The handler which is triggered when the audio progresses/ the thumb is dragged in the progress control. The progressed duration is set here.
84
+ const onProgress = (index: string, currentTime?: number, hasEnd?: boolean) => {
85
+ setFilesToDisplay((prevFileUploads) =>
86
+ prevFileUploads.map((fileUpload, id) => ({
87
+ ...fileUpload,
88
+ progress:
89
+ id.toString() === index
90
+ ? hasEnd
91
+ ? 1
92
+ : currentTime
93
+ ? currentTime / (fileUpload.duration as number)
94
+ : 0
95
+ : fileUpload.progress,
96
+ })),
97
+ );
98
+ };
99
+
100
+ // The handler which controls or sets the paused/played state of the audio.
101
+ const onPlayPause = (index: string, pausedStatus?: boolean) => {
102
+ if (pausedStatus === false) {
103
+ // If the status is false we set the audio with the index as playing and the others as paused.
104
+ setFilesToDisplay((prevFileUploads) =>
105
+ prevFileUploads.map((fileUpload, id) => ({
106
+ ...fileUpload,
107
+ paused: id.toString() === index ? false : true,
108
+ })),
109
+ );
110
+ } else {
111
+ // If the status is true we simply set all the audio's paused state as true.
112
+ setFilesToDisplay((prevFileUploads) =>
113
+ prevFileUploads.map((fileUpload) => ({
114
+ ...fileUpload,
115
+ paused: true,
116
+ })),
117
+ );
118
+ }
119
+ };
44
120
 
45
121
  const {
46
122
  theme: {
123
+ colors: { grey_whisper, white },
47
124
  messageSimple: {
48
125
  fileAttachmentGroup: { container },
49
126
  },
@@ -52,7 +129,7 @@ const FileAttachmentGroupWithContext = <
52
129
 
53
130
  return (
54
131
  <View style={[styles.container, container, stylesProp.container]}>
55
- {files.map((file, index) => (
132
+ {filesToDisplay.map((file, index) => (
56
133
  <View
57
134
  key={`${messageId}-${index}`}
58
135
  style={[
@@ -60,7 +137,40 @@ const FileAttachmentGroupWithContext = <
60
137
  stylesProp.attachmentContainer,
61
138
  ]}
62
139
  >
63
- <Attachment attachment={file} />
140
+ {file.type === 'audio' && isAudioPackageAvailable() ? (
141
+ <View
142
+ accessibilityLabel='audio-attachment-preview'
143
+ style={[
144
+ styles.fileContainer,
145
+ index === filesToDisplay.length - 1
146
+ ? {
147
+ marginBottom: 0,
148
+ }
149
+ : {},
150
+ {
151
+ backgroundColor: white,
152
+ borderColor: grey_whisper,
153
+ width: -16,
154
+ },
155
+ ]}
156
+ >
157
+ <AudioAttachment
158
+ item={{
159
+ duration: file.duration,
160
+ file: { name: file.title as string, uri: file.asset_url },
161
+ id: index.toString(),
162
+ paused: file.paused,
163
+ progress: file.progress,
164
+ }}
165
+ onLoad={onLoad}
166
+ onPlayPause={onPlayPause}
167
+ onProgress={onProgress}
168
+ testID='audio-attachment-preview'
169
+ />
170
+ </View>
171
+ ) : (
172
+ <Attachment attachment={file} />
173
+ )}
64
174
  </View>
65
175
  ))}
66
176
  </View>
@@ -74,9 +184,7 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
74
184
  const { files: prevFiles } = prevProps;
75
185
  const { files: nextFiles } = nextProps;
76
186
 
77
- const filesEqual = prevFiles.length === nextFiles.length;
78
-
79
- return filesEqual;
187
+ return prevFiles.length === nextFiles.length;
80
188
  };
81
189
 
82
190
  const MemoizedFileAttachmentGroup = React.memo(
@@ -98,7 +206,8 @@ export const FileAttachmentGroup = <
98
206
 
99
207
  const { files: contextFiles } = useMessageContext<StreamChatGenerics>();
100
208
 
101
- const { Attachment = AttachmentDefault } = useMessagesContext<StreamChatGenerics>();
209
+ const { Attachment = AttachmentDefault, AudioAttachment } =
210
+ useMessagesContext<StreamChatGenerics>();
102
211
 
103
212
  const files = propFiles || contextFiles;
104
213
 
@@ -108,6 +217,7 @@ export const FileAttachmentGroup = <
108
217
  <MemoizedFileAttachmentGroup
109
218
  {...{
110
219
  Attachment,
220
+ AudioAttachment,
111
221
  files,
112
222
  messageId,
113
223
  }}
@@ -62,6 +62,12 @@ const styles = StyleSheet.create({
62
62
  left: 4,
63
63
  position: 'absolute',
64
64
  },
65
+ imageLoadingIndicatorContainer: {
66
+ height: '100%',
67
+ justifyContent: 'center',
68
+ position: 'absolute',
69
+ width: '100%',
70
+ },
65
71
  imageLoadingIndicatorStyle: {
66
72
  alignItems: 'center',
67
73
  justifyContent: 'center',
@@ -490,7 +496,7 @@ const GalleryImageThumbnail = <
490
496
  uri={thumbnail.url}
491
497
  />
492
498
  {isLoadingImage && (
493
- <View style={{ position: 'absolute' }}>
499
+ <View style={[styles.imageLoadingIndicatorContainer]}>
494
500
  <ImageLoadingIndicator style={styles.imageLoadingIndicatorStyle} />
495
501
  </View>
496
502
  )}
@@ -40,6 +40,7 @@ export type VideoThumbnailProps = {
40
40
  export const VideoThumbnail: React.FC<VideoThumbnailProps> = (props) => {
41
41
  const {
42
42
  theme: {
43
+ colors: { static_black, static_white },
43
44
  messageSimple: {
44
45
  videoThumbnail: { container, roundedView },
45
46
  },
@@ -53,8 +54,8 @@ export const VideoThumbnail: React.FC<VideoThumbnailProps> = (props) => {
53
54
  source={{ uri: thumb_url }}
54
55
  style={[styles.container, container, style]}
55
56
  >
56
- <View style={[styles.roundedView, roundedView]}>
57
- <Play height={24} pathFill={'#000'} width={24} />
57
+ <View style={[styles.roundedView, roundedView, { backgroundColor: static_white }]}>
58
+ <Play height={24} pathFill={static_black} width={24} />
58
59
  </View>
59
60
  </ImageBackground>
60
61
  );
@@ -76,6 +76,7 @@ import type { DefaultStreamChatGenerics } from '../../types/types';
76
76
  import { generateRandomId, MessageStatusTypes, ReactionData } from '../../utils/utils';
77
77
  import { Attachment as AttachmentDefault } from '../Attachment/Attachment';
78
78
  import { AttachmentActions as AttachmentActionsDefault } from '../Attachment/AttachmentActions';
79
+ import { AudioAttachment as AudioAttachmentDefault } from '../Attachment/AudioAttachment';
79
80
  import { Card as CardDefault } from '../Attachment/Card';
80
81
  import { FileAttachment as FileAttachmentDefault } from '../Attachment/FileAttachment';
81
82
  import { FileAttachmentGroup as FileAttachmentGroupDefault } from '../Attachment/FileAttachmentGroup';
@@ -107,7 +108,6 @@ import { MessageSimple as MessageSimpleDefault } from '../Message/MessageSimple/
107
108
  import { MessageStatus as MessageStatusDefault } from '../Message/MessageSimple/MessageStatus';
108
109
  import { ReactionList as ReactionListDefault } from '../Message/MessageSimple/ReactionList';
109
110
  import { AttachButton as AttachButtonDefault } from '../MessageInput/AttachButton';
110
- import { AudioAttachmentUploadPreview as AudioAttachmentUploadPreviewDefault } from '../MessageInput/AudioAttachmentUploadPreview';
111
111
  import { CommandsButton as CommandsButtonDefault } from '../MessageInput/CommandsButton';
112
112
  import { InputEditingStateHeader as InputEditingStateHeaderDefault } from '../MessageInput/components/InputEditingStateHeader';
113
113
  import { InputGiphySearch as InputGiphyCommandInputDefault } from '../MessageInput/components/InputGiphySearch';
@@ -229,6 +229,7 @@ export type ChannelPropsWithContext<
229
229
  | 'additionalTouchableProps'
230
230
  | 'Attachment'
231
231
  | 'AttachmentActions'
232
+ | 'AudioAttachment'
232
233
  | 'Card'
233
234
  | 'CardCover'
234
235
  | 'CardFooter'
@@ -399,7 +400,7 @@ const ChannelWithContext = <
399
400
  AttachButton = AttachButtonDefault,
400
401
  Attachment = AttachmentDefault,
401
402
  AttachmentActions = AttachmentActionsDefault,
402
- AudioAttachmentUploadPreview = AudioAttachmentUploadPreviewDefault,
403
+ AudioAttachment = AudioAttachmentDefault,
403
404
  AutoCompleteSuggestionHeader = AutoCompleteSuggestionHeaderDefault,
404
405
  AutoCompleteSuggestionItem = AutoCompleteSuggestionItemDefault,
405
406
  AutoCompleteSuggestionList = AutoCompleteSuggestionListDefault,
@@ -1620,7 +1621,6 @@ const ChannelWithContext = <
1620
1621
  const inputMessageInputContext = useCreateInputMessageInputContext<StreamChatGenerics>({
1621
1622
  additionalTextInputProps,
1622
1623
  AttachButton,
1623
- AudioAttachmentUploadPreview,
1624
1624
  autoCompleteSuggestionsLimit,
1625
1625
  autoCompleteTriggerSettings,
1626
1626
  channelId,
@@ -1679,6 +1679,7 @@ const ChannelWithContext = <
1679
1679
  additionalTouchableProps,
1680
1680
  Attachment,
1681
1681
  AttachmentActions,
1682
+ AudioAttachment,
1682
1683
  Card,
1683
1684
  CardCover,
1684
1685
  CardFooter,
@@ -8,7 +8,6 @@ export const useCreateInputMessageInputContext = <
8
8
  >({
9
9
  additionalTextInputProps,
10
10
  AttachButton,
11
- AudioAttachmentUploadPreview,
12
11
  autoCompleteSuggestionsLimit,
13
12
  autoCompleteTriggerSettings,
14
13
  channelId,
@@ -65,7 +64,6 @@ export const useCreateInputMessageInputContext = <
65
64
  () => ({
66
65
  additionalTextInputProps,
67
66
  AttachButton,
68
- AudioAttachmentUploadPreview,
69
67
  autoCompleteSuggestionsLimit,
70
68
  autoCompleteTriggerSettings,
71
69
  clearEditingState,
@@ -9,6 +9,7 @@ export const useCreateMessagesContext = <
9
9
  additionalTouchableProps,
10
10
  Attachment,
11
11
  AttachmentActions,
12
+ AudioAttachment,
12
13
  Card,
13
14
  CardCover,
14
15
  CardFooter,
@@ -99,6 +100,7 @@ export const useCreateMessagesContext = <
99
100
  additionalTouchableProps,
100
101
  Attachment,
101
102
  AttachmentActions,
103
+ AudioAttachment,
102
104
  Card,
103
105
  CardCover,
104
106
  CardFooter,