aboutsummaryrefslogtreecommitdiff
path: root/src/components/moments/MomentUploadProgressBar.tsx
diff options
context:
space:
mode:
authorShravya Ramesh <37447613+shravyaramesh@users.noreply.github.com>2021-07-23 16:01:16 -0700
committerGitHub <noreply@github.com>2021-07-23 16:01:16 -0700
commit93b0bdb6d5d3070ece012626f9d9d6634f0eb0d8 (patch)
treede1aab12445184023db6b7f1e5dce94e8416d233 /src/components/moments/MomentUploadProgressBar.tsx
parent6fcfb36b37dd51d3e9d5baf025b896cc6f6045ee (diff)
parent2f64db843b80229d08f8f0ae7e1d80b24ac38c12 (diff)
Merge branch 'master' into tma936-pause-video
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;