1- import React , { useEffect , useState } from 'react' ;
1+ import React , { useEffect , useMemo , useState } from 'react' ;
22import { I18nManager , Pressable , StyleSheet , Text , View } from 'react-native' ;
33
44import dayjs from 'dayjs' ;
@@ -38,6 +38,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
3838 const [ width , setWidth ] = useState ( 0 ) ;
3939 const [ progressControlTextWidth , setProgressControlTextWidth ] = useState ( 0 ) ;
4040 const [ currentSpeed , setCurrentSpeed ] = useState < number > ( 1.0 ) ;
41+ const [ audioFinished , setAudioFinished ] = useState ( false ) ;
4142 const soundRef = React . useRef < SoundReturnType | null > ( null ) ;
4243 const {
4344 hideProgressBar = false ,
@@ -56,50 +57,54 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
5657
5758 /** This is for Native CLI Apps */
5859 const handleProgress = ( data : VideoProgressData ) => {
59- if ( data . currentTime <= data . seekableDuration ) {
60- onProgress ( item . id , data . currentTime ) ;
60+ const { currentTime, seekableDuration } = data ;
61+ if ( currentTime < seekableDuration && ! audioFinished ) {
62+ onProgress ( item . id , currentTime ) ;
63+ } else {
64+ setAudioFinished ( true ) ;
6165 }
6266 } ;
6367
6468 /** This is for Native CLI Apps */
65- const handleEnd = ( ) => {
69+ const handleEnd = async ( ) => {
70+ if ( soundRef . current ) {
71+ // For native CLI
72+ if ( soundRef . current . seek ) soundRef . current . seek ( 0 , 0 ) ;
73+ // For expo CLI
74+ if ( soundRef . current . setPositionAsync ) await soundRef . current . setPositionAsync ( 0 ) ;
75+ }
76+ setAudioFinished ( false ) ;
6677 onPlayPause ( item . id , true ) ;
6778 onProgress ( item . id , item . duration , true ) ;
6879 } ;
6980
7081 const handlePlayPause = async ( isPausedStatusAvailable ?: boolean ) => {
71- if ( soundRef . current ) {
72- if ( isPausedStatusAvailable === undefined ) {
73- if ( item . progress === 1 ) {
74- // For native CLI
75- if ( soundRef . current . seek ) soundRef . current . seek ( 0 ) ;
76- // For expo CLI
77- if ( soundRef . current . setPositionAsync ) soundRef . current . setPositionAsync ( 0 ) ;
78- }
79- if ( item . paused ) {
80- // For expo CLI
81- if ( soundRef . current . playAsync ) await soundRef . current . playAsync ( ) ;
82- if ( soundRef . current . setProgressUpdateIntervalAsync )
83- await soundRef . current . setProgressUpdateIntervalAsync ( 60 ) ;
84- onPlayPause ( item . id , false ) ;
85- } else {
86- // For expo CLI
87- if ( soundRef . current . pauseAsync ) await soundRef . current . pauseAsync ( ) ;
88- onPlayPause ( item . id , true ) ;
89- }
82+ if ( ! soundRef . current ) return ;
83+ if ( isPausedStatusAvailable === undefined ) {
84+ if ( item . paused ) {
85+ // For expo CLI
86+ if ( soundRef . current . playAsync ) await soundRef . current . playAsync ( ) ;
87+ if ( soundRef . current . setProgressUpdateIntervalAsync )
88+ await soundRef . current . setProgressUpdateIntervalAsync ( 60 ) ;
89+ onPlayPause ( item . id , false ) ;
9090 } else {
91- onPlayPause ( item . id , isPausedStatusAvailable ) ;
91+ // For expo CLI
92+ if ( soundRef . current . pauseAsync ) await soundRef . current . pauseAsync ( ) ;
93+ onPlayPause ( item . id , true ) ;
9294 }
95+ } else {
96+ onPlayPause ( item . id , isPausedStatusAvailable ) ;
9397 }
9498 } ;
9599
96- const handleProgressDrag = async ( position : number ) => {
97- onProgress ( item . id , position ) ;
100+ const handleProgressDrag = async ( currentTime : number ) => {
101+ setAudioFinished ( false ) ;
102+ onProgress ( item . id , currentTime ) ;
98103 // For native CLI
99- if ( soundRef . current ?. seek ) soundRef . current . seek ( position ) ;
104+ if ( soundRef . current ?. seek ) soundRef . current . seek ( currentTime ) ;
100105 // For expo CLI
101106 if ( soundRef . current ?. setPositionAsync ) {
102- await soundRef . current . setPositionAsync ( position * 1000 ) ;
107+ await soundRef . current . setPositionAsync ( currentTime * 1000 ) ;
103108 }
104109 } ;
105110
@@ -181,17 +186,20 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
181186 const onSpeedChangeHandler = async ( ) => {
182187 if ( currentSpeed === 2.0 ) {
183188 setCurrentSpeed ( 1.0 ) ;
189+ // For expo CLI
184190 if ( soundRef . current && soundRef . current . setRateAsync ) {
185191 await soundRef . current . setRateAsync ( 1.0 ) ;
186192 }
187193 } else {
188194 if ( currentSpeed === 1.0 ) {
189195 setCurrentSpeed ( 1.5 ) ;
196+ // For expo CLI
190197 if ( soundRef . current && soundRef . current . setRateAsync ) {
191198 await soundRef . current . setRateAsync ( 1.5 ) ;
192199 }
193200 } else if ( currentSpeed === 1.5 ) {
194201 setCurrentSpeed ( 2.0 ) ;
202+ // For expo CLI
195203 if ( soundRef . current && soundRef . current . setRateAsync ) {
196204 await soundRef . current . setRateAsync ( 2.0 ) ;
197205 }
@@ -218,13 +226,20 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
218226 } ,
219227 } = useTheme ( ) ;
220228
221- const progressValueInSeconds = ( item . duration as number ) * ( item . progress as number ) ;
229+ const progressValueInSeconds = useMemo (
230+ ( ) => ( item . duration as number ) * ( item . progress as number ) ,
231+ [ item . duration , item . progress ] ,
232+ ) ;
222233
223- const progressDuration = progressValueInSeconds
224- ? progressValueInSeconds / 3600 >= 1
225- ? dayjs . duration ( progressValueInSeconds , 'second' ) . format ( 'HH:mm:ss' )
226- : dayjs . duration ( progressValueInSeconds , 'second' ) . format ( 'mm:ss' )
227- : dayjs . duration ( item . duration ?? 0 , 'second' ) . format ( 'mm:ss' ) ;
234+ const progressDuration = useMemo (
235+ ( ) =>
236+ progressValueInSeconds
237+ ? progressValueInSeconds / 3600 >= 1
238+ ? dayjs . duration ( progressValueInSeconds , 'second' ) . format ( 'HH:mm:ss' )
239+ : dayjs . duration ( progressValueInSeconds , 'second' ) . format ( 'mm:ss' )
240+ : dayjs . duration ( item . duration ?? 0 , 'second' ) . format ( 'mm:ss' ) ,
241+ [ progressValueInSeconds , item . duration ] ,
242+ ) ;
228243
229244 return (
230245 < View
@@ -326,9 +341,9 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
326341 ) }
327342 </ View >
328343 </ View >
329- { showSpeedSettings && (
344+ { showSpeedSettings ? (
330345 < View style = { [ styles . rightContainer , rightContainer ] } >
331- { item . progress === 0 || item . progress === 1 ? (
346+ { item . paused ? (
332347 < Audio fill = { '#ffffff' } />
333348 ) : (
334349 < Pressable
@@ -345,7 +360,7 @@ export const AudioAttachment = (props: AudioAttachmentProps) => {
345360 </ Pressable >
346361 ) }
347362 </ View >
348- ) }
363+ ) : null }
349364 </ View >
350365 ) ;
351366} ;
0 commit comments