aboutsummaryrefslogtreecommitdiff
path: root/src/components/moments/MomentUploadProgressBar.tsx
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-07-23 18:55:27 -0400
committerIvan Chen <ivan@tagg.id>2021-07-23 18:55:27 -0400
commitc3febe151a34456cecbe84ffaac6eeea56254005 (patch)
tree3e1465a0e195c3b9676513606089a3dd141b0176 /src/components/moments/MomentUploadProgressBar.tsx
parent811426f6a4d2e3495d45c0ed1b209f2ea539e26f (diff)
parente39fcbd9e35f6a5e36afe248e24bea0dd3859202 (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.tsx221
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;