Skip to content

Commit 0cfba31

Browse files
committed
fix: improve audio attachment and progress bars
1 parent c384f92 commit 0cfba31

File tree

10 files changed

+305
-315
lines changed

10 files changed

+305
-315
lines changed

package/native-package/src/optionalDependencies/Sound.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export const Sound = {
3535
paused={paused}
3636
rate={rate}
3737
ref={soundRef}
38-
progressUpdateInterval={500}
38+
progressUpdateInterval={100}
3939
source={{
4040
uri,
4141
}}

package/src/components/Attachment/AudioAttachment.tsx

Lines changed: 91 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export type AudioAttachmentProps = {
2727
item: Omit<FileUpload, 'state'>;
2828
onLoad: (index: string, duration: number) => void;
2929
onPlayPause: (index: string, pausedStatus?: boolean) => void;
30-
onProgress: (index: string, currentTime?: number, hasEnd?: boolean) => void;
30+
onProgress: (index: string, progress: number) => void;
3131
hideProgressBar?: boolean;
3232
showSpeedSettings?: boolean;
3333
testID?: string;
@@ -38,8 +38,6 @@ export type AudioAttachmentProps = {
3838
* UI Component to preview the audio files
3939
*/
4040
export const AudioAttachment = (props: AudioAttachmentProps) => {
41-
const [width, setWidth] = useState(0);
42-
const [progressControlTextWidth, setProgressControlTextWidth] = useState(0);
4341
const [currentSpeed, setCurrentSpeed] = useState<number>(1.0);
4442
const [audioFinished, setAudioFinished] = useState(false);
4543
const soundRef = React.useRef<SoundReturnType | null>(null);
@@ -57,56 +55,71 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
5755

5856
/** This is for Native CLI Apps */
5957
const handleLoad = (payload: VideoPayloadData) => {
60-
if (isExpoCLI) return;
61-
pauseAudio();
6258
onLoad(item.id, item.duration || payload.duration);
6359
};
6460

6561
/** This is for Native CLI Apps */
6662
const handleProgress = (data: VideoProgressData) => {
6763
const { currentTime, seekableDuration } = data;
6864
if (currentTime < seekableDuration && !audioFinished) {
69-
onProgress(item.id, currentTime);
65+
onProgress(item.id, currentTime / seekableDuration);
7066
} else {
7167
setAudioFinished(true);
7268
}
7369
};
7470

75-
const onPlaybackStateChanged = (playbackState: PlaybackStatus) => {
76-
if (playbackState.isPlaying === false) {
77-
onPlayPause(item.id, true);
78-
} else {
79-
onPlayPause(item.id, false);
80-
}
81-
};
82-
71+
/** This is for Native CLI Apps */
8372
const onSeek = (seekResponse: VideoSeekResponse) => {
8473
setAudioFinished(false);
85-
onProgress(item.id, seekResponse.currentTime);
74+
onProgress(item.id, seekResponse.currentTime / (item.duration as number));
8675
};
8776

8877
const handlePlayPause = async () => {
89-
if (item.paused) {
90-
await playAudio();
78+
if (isExpoCLI) {
79+
if (item.paused) {
80+
await playAudio();
81+
} else {
82+
await pauseAudio();
83+
}
9184
} else {
92-
await pauseAudio();
85+
if (item.paused) {
86+
onPlayPause(item.id, false);
87+
} else {
88+
onPlayPause(item.id, true);
89+
}
9390
}
9491
};
9592

96-
/** This is for Native CLI Apps */
9793
const handleEnd = async () => {
9894
setAudioFinished(false);
95+
// The order is important here. We need to seek to 0 before pausing the audio.
9996
await seekAudio(0);
100-
await pauseAudio();
97+
if (isExpoCLI) {
98+
await pauseAudio();
99+
} else {
100+
onPlayPause(item.id, true);
101+
}
101102
};
102103

103104
const dragStart = async () => {
104-
await pauseAudio();
105+
if (isExpoCLI) {
106+
await pauseAudio();
107+
} else {
108+
onPlayPause(item.id, true);
109+
}
105110
};
106111

107-
const dragEnd = async (currentTime: number) => {
108-
await seekAudio(currentTime);
109-
await playAudio();
112+
const dragProgress = (progress: number) => {
113+
onProgress(item.id, progress);
114+
};
115+
116+
const dragEnd = async (progress: number) => {
117+
await seekAudio(progress * (item.duration as number));
118+
if (isExpoCLI) {
119+
await playAudio();
120+
} else {
121+
onPlayPause(item.id, false);
122+
}
110123
};
111124

112125
/** For Expo CLI */
@@ -125,7 +138,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
125138
// Update your UI for the loaded state
126139
if (playbackStatus.isPlaying) {
127140
onPlayPause(item.id, false);
128-
onProgress(item.id, positionMillis / 1000);
141+
onProgress(item.id, positionMillis / durationMillis);
129142
} else {
130143
onPlayPause(item.id, true);
131144
}
@@ -228,27 +241,24 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
228241
]}
229242
testID={testID}
230243
>
231-
<Pressable
232-
accessibilityLabel='Play Pause Button'
233-
onPress={handlePlayPause}
234-
style={[
235-
styles.playPauseButton,
236-
{ backgroundColor: static_white, shadowColor: black },
237-
playPauseButton,
238-
]}
239-
>
240-
{item.paused ? (
241-
<Play fill={static_black} height={32} width={32} />
242-
) : (
243-
<Pause fill={static_black} height={32} width={32} />
244-
)}
245-
</Pressable>
246-
<View
247-
onLayout={({ nativeEvent }) => {
248-
setWidth(nativeEvent.layout.width);
249-
}}
250-
style={[styles.leftContainer, leftContainer]}
251-
>
244+
<View style={[styles.leftContainer, leftContainer]}>
245+
<Pressable
246+
accessibilityLabel='Play Pause Button'
247+
onPress={handlePlayPause}
248+
style={[
249+
styles.playPauseButton,
250+
{ backgroundColor: static_white, shadowColor: black },
251+
playPauseButton,
252+
]}
253+
>
254+
{item.paused ? (
255+
<Play fill={static_black} height={32} width={32} />
256+
) : (
257+
<Pause fill={static_black} height={32} width={32} />
258+
)}
259+
</Pressable>
260+
</View>
261+
<View style={[styles.centerContainer]}>
252262
<Text
253263
accessibilityLabel='File Name'
254264
numberOfLines={1}
@@ -264,39 +274,16 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
264274
{getTrimmedAttachmentTitle(item.file.name)}
265275
</Text>
266276
<View style={styles.audioInfo}>
267-
{/* <ExpoSoundPlayer filePaused={!!item.paused} soundRef={soundRef} /> */}
268-
{Sound.Player && (
269-
<Sound.Player
270-
onEnd={handleEnd}
271-
onLoad={handleLoad}
272-
onPlaybackStateChanged={onPlaybackStateChanged}
273-
onProgress={handleProgress}
274-
onSeek={onSeek}
275-
rate={currentSpeed}
276-
soundRef={soundRef}
277-
testID='sound-player'
278-
uri={item.file.uri}
279-
/>
280-
)}
281-
<Text
282-
onLayout={({ nativeEvent }) => {
283-
setProgressControlTextWidth(nativeEvent.layout.width);
284-
}}
285-
style={[styles.progressDurationText, { color: grey_dark }, progressDurationText]}
286-
>
277+
<Text style={[styles.progressDurationText, { color: grey_dark }, progressDurationText]}>
287278
{progressDuration}
288279
</Text>
289280
{!hideProgressBar && (
290281
<View style={[styles.progressControlContainer, progressControlContainer]}>
291282
{item.file.waveform_data ? (
292283
<WaveProgressBar
293-
amplitudesCount={35}
294-
onEndDrag={(position) => {
295-
if (item.file.waveform_data) {
296-
const progress = (position / 30) * (item.duration as number);
297-
dragEnd(progress);
298-
}
299-
}}
284+
amplitudesCount={30}
285+
onEndDrag={dragEnd}
286+
onProgressDrag={dragProgress}
300287
onStartDrag={dragStart}
301288
progress={item.progress as number}
302289
waveformData={item.file.waveform_data}
@@ -306,15 +293,28 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
306293
duration={item.duration as number}
307294
filledColor={accent_blue}
308295
onEndDrag={dragEnd}
296+
onProgressDrag={dragProgress}
309297
onStartDrag={dragStart}
310298
progress={item.progress as number}
311299
testID='progress-control'
312-
width={width - progressControlTextWidth}
313300
/>
314301
)}
315302
</View>
316303
)}
317304
</View>
305+
{Sound.Player && (
306+
<Sound.Player
307+
onEnd={handleEnd}
308+
onLoad={handleLoad}
309+
onProgress={handleProgress}
310+
onSeek={onSeek}
311+
paused={item.paused}
312+
rate={currentSpeed}
313+
soundRef={soundRef}
314+
testID='sound-player'
315+
uri={item.file.uri}
316+
/>
317+
)}
318318
</View>
319319
{showSpeedSettings ? (
320320
<View style={[styles.rightContainer, rightContainer]}>
@@ -331,7 +331,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
331331
>
332332
<Text
333333
style={[styles.speedChangeButtonText, speedChangeButtonText]}
334-
>{`x${currentSpeed}`}</Text>
334+
>{`x${currentSpeed.toFixed(1)}`}</Text>
335335
</Pressable>
336336
)}
337337
</View>
@@ -342,58 +342,61 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
342342

343343
const styles = StyleSheet.create({
344344
audioInfo: {
345-
alignItems: 'center',
346-
display: 'flex',
347345
flexDirection: 'row',
348346
},
347+
centerContainer: {
348+
flexGrow: 1,
349+
},
349350
container: {
350351
alignItems: 'center',
351352
borderRadius: 12,
352353
borderWidth: 1,
354+
flex: 1,
353355
flexDirection: 'row',
354356
paddingHorizontal: 8,
355357
paddingVertical: 12,
356358
},
357359
filenameText: {
358360
fontSize: 14,
359361
fontWeight: 'bold',
360-
paddingBottom: 12,
362+
marginBottom: 8,
361363
},
362364
leftContainer: {
363-
justifyContent: 'space-around',
364-
marginHorizontal: 16,
365-
width: '60%',
365+
marginRight: 8,
366366
},
367367
playPauseButton: {
368368
alignItems: 'center',
369-
alignSelf: 'center',
370369
borderRadius: 50,
371370
elevation: 4,
372371
justifyContent: 'center',
373-
padding: 2,
372+
marginRight: 8,
373+
padding: 4,
374374
shadowOffset: {
375375
height: 2,
376376
width: 0,
377377
},
378378
shadowOpacity: 0.23,
379379
shadowRadius: 2.62,
380380
},
381-
progressControlContainer: {},
381+
progressControlContainer: {
382+
flexGrow: 1,
383+
justifyContent: 'center',
384+
},
382385
progressDurationText: {
383386
fontSize: 12,
384-
marginRight: 4,
387+
marginRight: 8,
385388
},
386389
rightContainer: {
387-
marginLeft: 'auto',
390+
marginLeft: 8,
388391
},
389392
speedChangeButton: {
390393
alignItems: 'center',
391394
alignSelf: 'center',
392395
borderRadius: 50,
393396
elevation: 4,
394397
justifyContent: 'center',
395-
paddingHorizontal: 10,
396-
paddingVertical: 5,
398+
paddingHorizontal: 8,
399+
paddingVertical: 4,
397400
shadowOffset: {
398401
height: 2,
399402
width: 0,
@@ -403,7 +406,6 @@ const styles = StyleSheet.create({
403406
},
404407
speedChangeButtonText: {
405408
fontSize: 12,
406-
fontWeight: '500',
407409
},
408410
});
409411

package/src/components/Attachment/FileAttachmentGroup.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,11 @@ const FileAttachmentGroupWithContext = <
6666
};
6767

6868
// The handler which is triggered when the audio progresses/ the thumb is dragged in the progress control. The progressed duration is set here.
69-
const onProgress = (index: string, currentTime?: number, hasEnd?: boolean) => {
69+
const onProgress = (index: string, progress: number) => {
7070
setFilesToDisplay((prevFilesToDisplay) =>
7171
prevFilesToDisplay.map((filesToDisplay, id) => ({
7272
...filesToDisplay,
73-
progress:
74-
id.toString() === index
75-
? hasEnd
76-
? 0
77-
: currentTime
78-
? +(currentTime / (filesToDisplay.duration as number)).toFixed(2)
79-
: 0
80-
: filesToDisplay.progress,
73+
progress: id.toString() === index ? progress : filesToDisplay.progress,
8174
})),
8275
);
8376
};
@@ -86,17 +79,17 @@ const FileAttachmentGroupWithContext = <
8679
const onPlayPause = (index: string, pausedStatus?: boolean) => {
8780
if (pausedStatus === false) {
8881
// If the status is false we set the audio with the index as playing and the others as paused.
89-
setFilesToDisplay((prevFileUploads) =>
90-
prevFileUploads.map((fileUpload, id) => ({
91-
...fileUpload,
82+
setFilesToDisplay((prevFilesToDisplay) =>
83+
prevFilesToDisplay.map((fileToDisplay, id) => ({
84+
...fileToDisplay,
9285
paused: id.toString() !== index,
9386
})),
9487
);
9588
} else {
9689
// If the status is true we simply set all the audio's paused state as true.
97-
setFilesToDisplay((prevFileUploads) =>
98-
prevFileUploads.map((fileUpload) => ({
99-
...fileUpload,
90+
setFilesToDisplay((prevFilesToDisplay) =>
91+
prevFilesToDisplay.map((fileToDisplay) => ({
92+
...fileToDisplay,
10093
paused: true,
10194
})),
10295
);

0 commit comments

Comments
 (0)