diff options
| author | Ivan Chen <ivan@tagg.id> | 2021-07-23 18:55:27 -0400 |
|---|---|---|
| committer | Ivan Chen <ivan@tagg.id> | 2021-07-23 18:55:27 -0400 |
| commit | c3febe151a34456cecbe84ffaac6eeea56254005 (patch) | |
| tree | 3e1465a0e195c3b9676513606089a3dd141b0176 /src/components/moments/MomentUploadProgressBar.tsx | |
| parent | 811426f6a4d2e3495d45c0ed1b209f2ea539e26f (diff) | |
| parent | e39fcbd9e35f6a5e36afe248e24bea0dd3859202 (diff) | |
Merge branch 'master' into tma994-bugfix-camera-screen-preview
# Conflicts:
# src/components/moments/TrimmerPlayer.tsx
# src/screens/upload/EditMedia.tsx
Diffstat (limited to 'src/components/moments/MomentUploadProgressBar.tsx')
| -rw-r--r-- | src/components/moments/MomentUploadProgressBar.tsx | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/components/moments/MomentUploadProgressBar.tsx b/src/components/moments/MomentUploadProgressBar.tsx new file mode 100644 index 00000000..d56a8337 --- /dev/null +++ b/src/components/moments/MomentUploadProgressBar.tsx @@ -0,0 +1,221 @@ +import React, {useEffect} from 'react'; +import {Image, StyleSheet, Text} from 'react-native'; +import {View} from 'react-native-animatable'; +import { + cancelAnimation, + Easing, + useSharedValue, + withTiming, +} from 'react-native-reanimated'; +import {useDispatch, useSelector} from 'react-redux'; +import {checkMomentDoneProcessing} from '../../services'; +import {loadUserMoments} from '../../store/actions'; +import {setMomentUploadProgressBar} from '../../store/reducers'; +import {RootState} from '../../store/rootReducer'; +import {MomentUploadStatusType} from '../../types'; +import {normalize, SCREEN_WIDTH, StatusBarHeight} from '../../utils'; +import {GradientProgressBar} from '../common'; + +interface MomentUploadProgressBarProps {} + +const MomentUploadProgressBar: React.FC<MomentUploadProgressBarProps> = + ({}) => { + const dispatch = useDispatch(); + const {userId: loggedInUserId} = useSelector( + (state: RootState) => state.user.user, + ); + 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 = async () => { + if ( + momentUploadProgressBar && + (await checkMomentDoneProcessing(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(loadUserMoments(loggedInUserId)); + dispatch({ + type: setMomentUploadProgressBar.type, + payload: { + momentUploadProgressBar: { + ...momentUploadProgressBar, + status: MomentUploadStatusType.Done, + }, + }, + }); + }, finishProgressBarDuration); + } + }; + if ( + momentUploadProgressBar?.status === + MomentUploadStatusType.WaitingForDoneProcessing + ) { + checkDone(); + const timer = setInterval(async () => { + if (!doneProcessing) { + checkDone(); + } + }, 5 * 1000); + // timeout if takes longer than 1 minute to process + setTimeout(() => { + clearInterval(timer); + if (!doneProcessing) { + console.error('Check for done processing timed out'); + dispatch({ + type: setMomentUploadProgressBar.type, + payload: { + momentUploadProgressBar: { + ...momentUploadProgressBar, + status: MomentUploadStatusType.Error, + }, + }, + }); + } + }, 60 * 1000); + return () => clearInterval(timer); + } + }, [momentUploadProgressBar?.status]); + + useEffect(() => { + if ( + momentUploadProgressBar?.status === MomentUploadStatusType.UploadingToS3 + ) { + // e.g. 30s video => 30 * 3 = 60s + const videoDuration = + momentUploadProgressBar.originalVideoDuration ?? 30; + const durationInSeconds = videoDuration * 3; + progress.value = withTiming(1, { + duration: durationInSeconds * 1000, + easing: Easing.out(Easing.quad), + }); + } + }, [momentUploadProgressBar?.status]); + + useEffect(() => { + if ( + momentUploadProgressBar?.status === MomentUploadStatusType.Done || + momentUploadProgressBar?.status === MomentUploadStatusType.Error + ) { + progress.value = 0; + // clear this component after a duration + setTimeout(() => { + dispatch({ + type: setMomentUploadProgressBar.type, + payload: { + momentUploadProgressBar: undefined, + }, + }); + }, 5000); + } + }, [momentUploadProgressBar?.status]); + + if (!momentUploadProgressBar) { + return null; + } + + return ( + <View + style={[ + styles.background, + momentUploadProgressBar?.status === MomentUploadStatusType.Error + ? styles.redBackground + : {}, + ]}> + <View style={styles.container}> + {showLoading && ( + <> + <Text style={styles.text}>Uploading Moment...</Text> + <GradientProgressBar style={styles.bar} progress={progress} /> + </> + )} + {momentUploadProgressBar.status === MomentUploadStatusType.Done && ( + <View style={styles.row}> + <Image + source={require('../../assets/images/green-check.png')} + style={styles.x} + /> + <Text style={styles.text}> + Beautiful, the Moment was uploaded successfully! + </Text> + </View> + )} + {momentUploadProgressBar.status === MomentUploadStatusType.Error && ( + <View style={styles.row}> + <Image + source={require('../../assets/images/white-x.png')} + style={styles.x} + /> + <Text style={styles.whiteText}> + Unable to upload Moment. Please retry + </Text> + </View> + )} + </View> + </View> + ); + }; + +const styles = StyleSheet.create({ + background: { + position: 'absolute', + zIndex: 999, + height: StatusBarHeight + normalize(84), + backgroundColor: 'white', + width: '100%', + alignItems: 'center', + }, + container: { + justifyContent: 'center', + marginTop: StatusBarHeight, + height: normalize(84), + }, + text: { + fontSize: normalize(14), + fontWeight: 'bold', + lineHeight: 17, + marginVertical: 12, + width: '80%', + }, + bar: { + width: SCREEN_WIDTH * 0.9, + }, + redBackground: { + backgroundColor: '#EA574C', + }, + row: { + flexDirection: 'row', + alignItems: 'center', + }, + whiteText: { + color: 'white', + fontSize: normalize(14), + fontWeight: 'bold', + lineHeight: 17, + marginVertical: 12, + }, + x: { + width: normalize(26), + height: normalize(26), + marginRight: 10, + }, +}); + +export default MomentUploadProgressBar; |
