@@ -25,6 +25,8 @@ import {
2525 isLocalVoiceRecordingAttachment ,
2626 isVideoAttachment ,
2727 LocalAttachment ,
28+ LocalAudioAttachment ,
29+ LocalVoiceRecordingAttachment ,
2830} from 'stream-chat' ;
2931
3032import { useMessageComposer } from '../../../../contexts' ;
@@ -69,6 +71,14 @@ const ItemSeparatorComponent = () => {
6971 return < View style = { [ styles . itemSeparator , itemSeparator ] } /> ;
7072} ;
7173
74+ const getIsAudioAttachmentPreview =
75+ ( soundPackageAvailable : boolean ) =>
76+ (
77+ attachment : LocalAttachment ,
78+ ) : attachment is LocalAudioAttachment | LocalVoiceRecordingAttachment =>
79+ isLocalVoiceRecordingAttachment ( attachment ) ||
80+ ( soundPackageAvailable && isLocalAudioAttachment ( attachment ) ) ;
81+
7282/**
7383 * AttachmentUploadPreviewList
7484 * UI Component to preview the files set for upload
@@ -85,11 +95,17 @@ const UnMemoizedAttachmentUploadPreviewList = (
8595 const { attachmentManager } = useMessageComposer ( ) ;
8696 const { attachments } = useAttachmentManagerState ( ) ;
8797 const attachmentListRef = useRef < FlatList < LocalAttachment > > ( null ) ;
88- const previousAttachmentsLengthRef = useRef ( attachments . length ) ;
98+ const soundPackageAvailable = isSoundPackageAvailable ( ) ;
99+ const isAudioAttachmentPreview = getIsAudioAttachmentPreview ( soundPackageAvailable ) ;
100+ const previousNonAudioAttachmentsLengthRef = useRef ( 0 ) ;
89101 const contentWidthRef = useRef ( 0 ) ;
90102 const viewportWidthRef = useRef ( 0 ) ;
91103 const scrollOffsetXRef = useRef ( 0 ) ;
92104 const endShrinkCompensationX = useSharedValue ( 0 ) ;
105+ const audioAttachments = attachments . filter ( isAudioAttachmentPreview ) ;
106+ const nonAudioAttachments = attachments . filter (
107+ ( attachment ) => ! isAudioAttachmentPreview ( attachment ) ,
108+ ) ;
93109
94110 const {
95111 theme : {
@@ -224,10 +240,10 @@ const UnMemoizedAttachmentUploadPreviewList = (
224240 ) ;
225241
226242 useEffect ( ( ) => {
227- const previousLength = previousAttachmentsLengthRef . current ;
228- const nextLength = attachments . length ;
243+ const previousLength = previousNonAudioAttachmentsLengthRef . current ;
244+ const nextLength = nonAudioAttachments . length ;
229245 const didAddAttachment = nextLength > previousLength ;
230- previousAttachmentsLengthRef . current = nextLength ;
246+ previousNonAudioAttachmentsLengthRef . current = nextLength ;
231247
232248 if ( ! didAddAttachment ) {
233249 return ;
@@ -238,7 +254,7 @@ const UnMemoizedAttachmentUploadPreviewList = (
238254 requestAnimationFrame ( ( ) => {
239255 attachmentListRef . current ?. scrollToEnd ( { animated : true } ) ;
240256 } ) ;
241- } , [ attachments . length , endShrinkCompensationX ] ) ;
257+ } , [ endShrinkCompensationX , nonAudioAttachments . length ] ) ;
242258
243259 const animatedListWrapperStyle = useAnimatedStyle ( ( ) => ( {
244260 transform : [ { translateX : endShrinkCompensationX . value } ] ,
@@ -249,24 +265,47 @@ const UnMemoizedAttachmentUploadPreviewList = (
249265 }
250266
251267 return (
252- < Animated . View style = { animatedListWrapperStyle } >
253- < FlatList
254- data = { attachments }
255- horizontal
256- ItemSeparatorComponent = { ItemSeparatorComponent }
257- keyExtractor = { ( item ) => item . localMetadata . id }
258- onContentSizeChange = { onContentSizeChangeHandler }
259- onLayout = { onLayoutHandler }
260- onScroll = { onScrollHandler }
261- removeClippedSubviews = { false }
262- ref = { attachmentListRef }
263- renderItem = { renderItem }
264- scrollEventThrottle = { 16 }
265- showsHorizontalScrollIndicator = { false }
266- style = { [ styles . flatList , flatList ] }
267- testID = { 'attachment-upload-preview-list' }
268- />
269- </ Animated . View >
268+ < >
269+ { audioAttachments . length ? (
270+ < Animated . View
271+ entering = { ZoomIn . duration ( 200 ) }
272+ exiting = { ZoomOut . duration ( 200 ) }
273+ layout = { LinearTransition . duration ( 200 ) }
274+ style = { styles . audioAttachmentsContainer }
275+ >
276+ { audioAttachments . map ( ( attachment ) => (
277+ < AttachmentPreviewCell key = { attachment . localMetadata . id } >
278+ < AudioAttachmentUploadPreview
279+ attachment = { attachment }
280+ handleRetry = { attachmentManager . uploadAttachment }
281+ removeAttachments = { attachmentManager . removeAttachments }
282+ />
283+ </ AttachmentPreviewCell >
284+ ) ) }
285+ </ Animated . View >
286+ ) : null }
287+
288+ { nonAudioAttachments . length ? (
289+ < Animated . View style = { animatedListWrapperStyle } >
290+ < FlatList
291+ data = { nonAudioAttachments }
292+ horizontal
293+ ItemSeparatorComponent = { ItemSeparatorComponent }
294+ keyExtractor = { ( item ) => item . localMetadata . id }
295+ onContentSizeChange = { onContentSizeChangeHandler }
296+ onLayout = { onLayoutHandler }
297+ onScroll = { onScrollHandler }
298+ removeClippedSubviews = { false }
299+ ref = { attachmentListRef }
300+ renderItem = { renderItem }
301+ scrollEventThrottle = { 16 }
302+ showsHorizontalScrollIndicator = { false }
303+ style = { [ styles . flatList , flatList ] }
304+ testID = { 'attachment-upload-preview-list' }
305+ />
306+ </ Animated . View >
307+ ) : null }
308+ </ >
270309 ) ;
271310} ;
272311
@@ -301,6 +340,9 @@ export const AttachmentUploadPreviewList = (props: AttachmentUploadPreviewListPr
301340} ;
302341
303342const styles = StyleSheet . create ( {
343+ audioAttachmentsContainer : {
344+ width : '100%' ,
345+ } ,
304346 flatList : {
305347 overflow : 'visible' ,
306348 } ,
0 commit comments