diff options
-rw-r--r-- | src/components/moments/MomentUploadProgressBar.tsx | 106 |
1 files changed, 95 insertions, 11 deletions
diff --git a/src/components/moments/MomentUploadProgressBar.tsx b/src/components/moments/MomentUploadProgressBar.tsx index 0d84236d..742c403b 100644 --- a/src/components/moments/MomentUploadProgressBar.tsx +++ b/src/components/moments/MomentUploadProgressBar.tsx @@ -1,10 +1,16 @@ import React, {useEffect} from 'react'; import {StyleSheet, Text} from 'react-native'; import {View} from 'react-native-animatable'; -import {Easing, useSharedValue, withTiming} from 'react-native-reanimated'; +import { + cancelAnimation, + Easing, + useSharedValue, + withTiming, +} from 'react-native-reanimated'; import {SafeAreaView} from 'react-native-safe-area-context'; -import {useSelector} from 'react-redux'; +import {useDispatch, useSelector} from 'react-redux'; import {checkMomentUploadFinished} from '../../services'; +import {setMomentUploadProgressBar} from '../../store/reducers'; import {RootState} from '../../store/rootReducer'; import {MomentUploadStatusType} from '../../types'; import {normalize, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; @@ -14,37 +20,105 @@ interface MomentUploadProgressBarProps {} const MomentUploadProgressBar: React.FC<MomentUploadProgressBarProps> = ({}) => { + const dispatch = useDispatch(); const {momentUploadProgressBar} = useSelector( (state: RootState) => state.user, ); const progress = useSharedValue(0); + const showLoading = + momentUploadProgressBar?.status === + MomentUploadStatusType.UploadingToS3 || + momentUploadProgressBar?.status === + MomentUploadStatusType.WaitingForDoneProcessing; useEffect(() => { + let doneProcessing = false; + const checkDone = () => { + if ( + momentUploadProgressBar && + checkMomentUploadFinished(momentUploadProgressBar?.momentId) + ) { + doneProcessing = true; + cancelAnimation(progress); + // upload is done, but let's finish the progress bar animation in a velocity of 10%/s + const finishProgressBarDuration = (1 - progress.value) * 10 * 1000; + progress.value = withTiming(1, { + duration: finishProgressBarDuration, + easing: Easing.linear, + }); + // change status to Done 1s after the progress bar animation is done + setTimeout(() => { + dispatch({ + type: setMomentUploadProgressBar.type, + payload: { + momentUploadProgressBar: { + ...momentUploadProgressBar, + status: MomentUploadStatusType.Done, + }, + }, + }); + }, finishProgressBarDuration + 1000); + } + }; if ( - momentUploadProgressBar?.status === MomentUploadStatusType.Uploading + momentUploadProgressBar?.status === + MomentUploadStatusType.WaitingForDoneProcessing ) { + checkDone(); const timer = setInterval(async () => { - if (checkMomentUploadFinished(momentUploadProgressBar.momentId)) { - // call upload finished action + if (!doneProcessing) { + checkDone(); } }, 5 * 1000); + // timeout if takes longer than 1 minute to process setTimeout(() => { + console.error('Check for done processing timed out'); clearInterval(timer); - }, 5 * 60 * 1000); + dispatch({ + type: setMomentUploadProgressBar.type, + payload: { + momentUploadProgressBar: { + ...momentUploadProgressBar, + status: MomentUploadStatusType.Error, + }, + }, + }); + }, 60 * 1000); + return () => clearInterval(timer); } - }, []); + }, [momentUploadProgressBar?.status]); useEffect(() => { if ( - momentUploadProgressBar?.status === MomentUploadStatusType.Uploading + momentUploadProgressBar?.status === MomentUploadStatusType.UploadingToS3 ) { + // assume it takes video duration (upload) + 1/2 of the video (process) duration to upload + // e.g. 30s video => 30 + 30 * .5 = 37.5s + const videoDuration = + momentUploadProgressBar.originalVideoDuration ?? 30; + const durationInSeconds = videoDuration * 1.5; progress.value = withTiming(1, { - duration: momentUploadProgressBar.originalVideoDuration * 1000, + duration: durationInSeconds * 1000, easing: Easing.out(Easing.quad), }); } }, [momentUploadProgressBar?.status]); + useEffect(() => { + if (momentUploadProgressBar?.status === MomentUploadStatusType.Done) { + progress.value = 0; + // clear this component after a duration + setTimeout(() => { + dispatch({ + type: setMomentUploadProgressBar.type, + payload: { + momentUploadProgressBar: undefined, + }, + }); + }, 5000); + } + }, [momentUploadProgressBar?.status]); + if (!momentUploadProgressBar) { return null; } @@ -52,8 +126,18 @@ const MomentUploadProgressBar: React.FC<MomentUploadProgressBarProps> = return ( <View style={styles.background}> <SafeAreaView style={styles.container}> - <Text style={styles.text}>Uploading Moment...</Text> - <GradientProgressBar style={styles.bar} progress={progress} /> + {showLoading && ( + <> + <Text style={styles.text}>Uploading Moment...</Text> + <GradientProgressBar style={styles.bar} progress={progress} /> + </> + )} + {momentUploadProgressBar.status === MomentUploadStatusType.Done && ( + <Text style={styles.text}>Done</Text> + )} + {momentUploadProgressBar.status === MomentUploadStatusType.Error && ( + <Text style={styles.text}>Error</Text> + )} </SafeAreaView> </View> ); |