Skip to content

Commit adf457d

Browse files
authored
fix: audio recording designs (#3498)
## 🎯 Goal <!-- Describe why we are making this change --> ## πŸ›  Implementation details <!-- Provide a description of the implementation --> ## 🎨 UI Changes <!-- Add relevant screenshots --> <details> <summary>iOS</summary> <table> <thead> <tr> <td>Before</td> <td>After</td> </tr> </thead> <tbody> <tr> <td> <!--<img src="" /> --> </td> <td> <!--<img src="" /> --> </td> </tr> </tbody> </table> </details> <details> <summary>Android</summary> <table> <thead> <tr> <td>Before</td> <td>After</td> </tr> </thead> <tbody> <tr> <td> <!--<img src="" /> --> </td> <td> <!--<img src="" /> --> </td> </tr> </tbody> </table> </details> ## πŸ§ͺ Testing <!-- Explain how this change can be tested (or why it can't be tested) --> ## β˜‘οΈ Checklist - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [ ] PR targets the `develop` branch - [ ] Documentation is updated - [ ] New code is tested in main example apps, including all possible scenarios - [ ] SampleApp iOS and Android - [ ] Expo iOS and Android
1 parent cfce800 commit adf457d

3 files changed

Lines changed: 78 additions & 25 deletions

File tree

β€Žpackage/src/components/MessageInput/components/AttachmentPreview/AttachmentUploadPreviewList.tsxβ€Ž

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import {
2525
isLocalVoiceRecordingAttachment,
2626
isVideoAttachment,
2727
LocalAttachment,
28+
LocalAudioAttachment,
29+
LocalVoiceRecordingAttachment,
2830
} from 'stream-chat';
2931

3032
import { useMessageComposer } from '../../../../contexts';
@@ -39,6 +41,7 @@ import { primitives } from '../../../../theme';
3941

4042
const END_ANCHOR_THRESHOLD = 16;
4143
const END_SHRINK_COMPENSATION_DURATION = 200;
44+
const MAX_AUDIO_ATTACHMENTS_CONTAINER_WIDTH = 560;
4245

4346
export type AttachmentUploadListPreviewPropsWithContext = Pick<
4447
MessageInputContextValue,
@@ -69,6 +72,14 @@ const ItemSeparatorComponent = () => {
6972
return <View style={[styles.itemSeparator, itemSeparator]} />;
7073
};
7174

75+
const getIsAudioAttachmentPreview =
76+
(soundPackageAvailable: boolean) =>
77+
(
78+
attachment: LocalAttachment,
79+
): attachment is LocalAudioAttachment | LocalVoiceRecordingAttachment =>
80+
isLocalVoiceRecordingAttachment(attachment) ||
81+
(soundPackageAvailable && isLocalAudioAttachment(attachment));
82+
7283
/**
7384
* AttachmentUploadPreviewList
7485
* UI Component to preview the files set for upload
@@ -85,16 +96,22 @@ const UnMemoizedAttachmentUploadPreviewList = (
8596
const { attachmentManager } = useMessageComposer();
8697
const { attachments } = useAttachmentManagerState();
8798
const attachmentListRef = useRef<FlatList<LocalAttachment>>(null);
88-
const previousAttachmentsLengthRef = useRef(attachments.length);
99+
const soundPackageAvailable = isSoundPackageAvailable();
100+
const isAudioAttachmentPreview = getIsAudioAttachmentPreview(soundPackageAvailable);
101+
const previousNonAudioAttachmentsLengthRef = useRef(0);
89102
const contentWidthRef = useRef(0);
90103
const viewportWidthRef = useRef(0);
91104
const scrollOffsetXRef = useRef(0);
92105
const endShrinkCompensationX = useSharedValue(0);
106+
const audioAttachments = attachments.filter(isAudioAttachmentPreview);
107+
const nonAudioAttachments = attachments.filter(
108+
(attachment) => !isAudioAttachmentPreview(attachment),
109+
);
93110

94111
const {
95112
theme: {
96113
messageInput: {
97-
attachmentUploadPreviewList: { flatList },
114+
attachmentUploadPreviewList: { audioAttachmentsContainer, flatList },
98115
},
99116
},
100117
} = useTheme();
@@ -224,10 +241,10 @@ const UnMemoizedAttachmentUploadPreviewList = (
224241
);
225242

226243
useEffect(() => {
227-
const previousLength = previousAttachmentsLengthRef.current;
228-
const nextLength = attachments.length;
244+
const previousLength = previousNonAudioAttachmentsLengthRef.current;
245+
const nextLength = nonAudioAttachments.length;
229246
const didAddAttachment = nextLength > previousLength;
230-
previousAttachmentsLengthRef.current = nextLength;
247+
previousNonAudioAttachmentsLengthRef.current = nextLength;
231248

232249
if (!didAddAttachment) {
233250
return;
@@ -238,7 +255,7 @@ const UnMemoizedAttachmentUploadPreviewList = (
238255
requestAnimationFrame(() => {
239256
attachmentListRef.current?.scrollToEnd({ animated: true });
240257
});
241-
}, [attachments.length, endShrinkCompensationX]);
258+
}, [endShrinkCompensationX, nonAudioAttachments.length]);
242259

243260
const animatedListWrapperStyle = useAnimatedStyle(() => ({
244261
transform: [{ translateX: endShrinkCompensationX.value }],
@@ -249,24 +266,53 @@ const UnMemoizedAttachmentUploadPreviewList = (
249266
}
250267

251268
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>
269+
<>
270+
{audioAttachments.length ? (
271+
<Animated.View
272+
entering={ZoomIn.duration(200)}
273+
exiting={ZoomOut.duration(200)}
274+
layout={LinearTransition.duration(200)}
275+
style={[styles.audioAttachmentsContainer, audioAttachmentsContainer]}
276+
>
277+
{audioAttachments.map((attachment) => (
278+
<AttachmentPreviewCell key={attachment.localMetadata.id}>
279+
<AudioAttachmentUploadPreview
280+
attachment={attachment}
281+
handleRetry={attachmentManager.uploadAttachment}
282+
removeAttachments={attachmentManager.removeAttachments}
283+
/>
284+
</AttachmentPreviewCell>
285+
))}
286+
</Animated.View>
287+
) : null}
288+
289+
{nonAudioAttachments.length ? (
290+
<Animated.View
291+
entering={ZoomIn.duration(200)}
292+
exiting={ZoomOut.duration(200)}
293+
layout={LinearTransition.duration(200)}
294+
>
295+
<Animated.View style={animatedListWrapperStyle}>
296+
<FlatList
297+
data={nonAudioAttachments}
298+
horizontal
299+
ItemSeparatorComponent={ItemSeparatorComponent}
300+
keyExtractor={(item) => item.localMetadata.id}
301+
onContentSizeChange={onContentSizeChangeHandler}
302+
onLayout={onLayoutHandler}
303+
onScroll={onScrollHandler}
304+
removeClippedSubviews={false}
305+
ref={attachmentListRef}
306+
renderItem={renderItem}
307+
scrollEventThrottle={16}
308+
showsHorizontalScrollIndicator={false}
309+
style={[styles.flatList, flatList]}
310+
testID={'attachment-upload-preview-list'}
311+
/>
312+
</Animated.View>
313+
</Animated.View>
314+
) : null}
315+
</>
270316
);
271317
};
272318

@@ -301,6 +347,10 @@ export const AttachmentUploadPreviewList = (props: AttachmentUploadPreviewListPr
301347
};
302348

303349
const styles = StyleSheet.create({
350+
audioAttachmentsContainer: {
351+
maxWidth: MAX_AUDIO_ATTACHMENTS_CONTAINER_WIDTH,
352+
width: '100%',
353+
},
304354
flatList: {
305355
overflow: 'visible',
306356
},

β€Žpackage/src/components/MessageInput/components/AttachmentPreview/AudioAttachmentUploadPreview.tsxβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@ const useStyles = () => {
104104
},
105105
wrapper: {
106106
padding: primitives.spacingXxs,
107+
width: '100%',
107108
},
108109
audioAttachmentContainer: {
109110
borderRadius: primitives.radiusLg,
110111
borderColor: semantics.borderCoreDefault,
111112
borderWidth: 1,
112-
width: 274, // TODO: Fix this
113+
width: '100%',
113114
},
114115
}),
115116
[semantics.borderCoreDefault],

β€Žpackage/src/contexts/themeContext/utils/theme.tsβ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ export type Theme = {
325325
attachButtonContainer: ViewStyle;
326326
attachmentSelectionBar: ViewStyle;
327327
attachmentUploadPreviewList: {
328+
audioAttachmentsContainer: ViewStyle;
328329
flatList: ViewStyle;
329330
itemSeparator: ViewStyle;
330331
};
@@ -1253,6 +1254,7 @@ export const defaultTheme: Theme = {
12531254
attachButtonContainer: {},
12541255
attachmentSelectionBar: {},
12551256
attachmentUploadPreviewList: {
1257+
audioAttachmentsContainer: {},
12561258
flatList: {},
12571259
itemSeparator: {},
12581260
},

0 commit comments

Comments
Β (0)