aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-07-22 16:08:45 -0400
committerIvan Chen <ivan@tagg.id>2021-07-22 16:08:45 -0400
commit848204d684f6dfb8ada0856a50487d00ad2c77df (patch)
tree6d554b75cfbe2fbee1e03477aaa0c3f94927e935
parentbc82aaf481949d690af814b9dd4a0e9cab387011 (diff)
Add action for handling all video uploads
-rw-r--r--src/screens/profile/CaptionScreen.tsx39
-rw-r--r--src/store/actions/user.ts98
-rw-r--r--src/store/initialStates.ts1
-rw-r--r--src/types/types.ts3
4 files changed, 120 insertions, 21 deletions
diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx
index 7f77bdca..88ff0ecc 100644
--- a/src/screens/profile/CaptionScreen.tsx
+++ b/src/screens/profile/CaptionScreen.tsx
@@ -42,6 +42,7 @@ import {
postMomentTags,
} from '../../services';
import {
+ handleVideoMomentUpload,
loadUserMoments,
updateProfileCompletionStage,
} from '../../store/actions';
@@ -76,6 +77,8 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
const [tags, setTags] = useState<MomentTagType[]>([]);
const [taggedUsersText, setTaggedUsersText] = useState('');
const [momentCategory, setMomentCategory] = useState<string | undefined>();
+ // only used for upload purposes, undefined for editing is fine
+ const videoDuration = moment ? undefined : route.params.media!.videoDuration;
const mediaUri = moment ? moment.moment_url : route.params.media!.uri;
// TODO: change this once moment refactor is done
const isMediaAVideo = moment
@@ -166,18 +169,17 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
return;
}
let profileCompletionStage;
- let momentId;
// separate upload logic for image/video
if (isMediaAVideo) {
- const presignedURLResponse = await handlePresignedURL(momentCategory);
- if (!presignedURLResponse) {
- handleFailed();
- return;
- }
- momentId = presignedURLResponse.moment_id;
- const fileHash = presignedURLResponse.response_url.fields.key;
- if (fileHash !== null && fileHash !== '' && fileHash !== undefined) {
- await handleVideoUpload(mediaUri, presignedURLResponse);
+ if (videoDuration) {
+ dispatch(
+ handleVideoMomentUpload(
+ mediaUri,
+ videoDuration,
+ momentCategory,
+ formattedTags(),
+ ),
+ );
} else {
handleFailed();
}
@@ -193,13 +195,16 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
return;
}
profileCompletionStage = momentResponse.profile_completion_stage;
- momentId = momentResponse.moment_id;
- }
- if (momentId) {
- const momentTagResponse = await postMomentTags(momentId, formattedTags());
- if (!momentTagResponse) {
- handleFailed();
- return;
+ const momentId = momentResponse.moment_id;
+ if (momentId) {
+ const momentTagResponse = await postMomentTags(
+ momentId,
+ formattedTags(),
+ );
+ if (!momentTagResponse) {
+ handleFailed();
+ return;
+ }
}
}
if (!isMediaAVideo) {
diff --git a/src/store/actions/user.ts b/src/store/actions/user.ts
index b1cb8719..1acbb519 100644
--- a/src/store/actions/user.ts
+++ b/src/store/actions/user.ts
@@ -1,13 +1,21 @@
import AsyncStorage from '@react-native-community/async-storage';
-import {StreamChat} from 'stream-chat';
import {Action, ThunkAction} from '@reduxjs/toolkit';
+import {StreamChat} from 'stream-chat';
import {
getProfilePic,
+ handlePresignedURL,
+ handleVideoUpload,
loadProfileInfo,
+ postMomentTags,
removeBadgesService,
sendSuggestedPeopleLinked,
} from '../../services';
-import {UniversityBadge, UserType} from '../../types/types';
+import {
+ MomentUploadProgressBarType,
+ MomentUploadStatusType,
+ UniversityBadge,
+ UserType,
+} from '../../types/types';
import {getTokenOrLogout} from '../../utils';
import {
clearHeaderAndProfileImages,
@@ -15,6 +23,7 @@ import {
profileBadgesUpdated,
profileCompletionStageUpdated,
setIsOnboardedUser,
+ setMomentUploadProgressBar,
setNewNotificationReceived,
setNewVersionAvailable,
setReplyPosted,
@@ -275,3 +284,88 @@ export const suggestedPeopleAnimatedTutorialFinished =
);
}
};
+
+/**
+ * state is now UploadingToS3:
+ * - get presigned url (backend creates the moment object)
+ * - upload moment tags
+ * - upload video to s3
+ * state is now WaitingForDoneProcessing
+ */
+export const handleVideoMomentUpload =
+ (
+ videoUri: string,
+ videoLength: number,
+ momentCategory: string,
+ formattedTags: {
+ x: number;
+ y: number;
+ z: number;
+ user_id: string;
+ }[],
+ ): ThunkAction<Promise<void>, RootState, unknown, Action<string>> =>
+ async (dispatch) => {
+ try {
+ const handleError = (reason: string) => {
+ console.error('Moment video upload failed,', reason);
+ dispatch({
+ type: setMomentUploadProgressBar.type,
+ payload: {
+ momentUploadProgressBar: {
+ ...momentUploadProgressBar,
+ status: MomentUploadStatusType.Error,
+ },
+ },
+ });
+ };
+ let momentUploadProgressBar: MomentUploadProgressBarType = {
+ status: MomentUploadStatusType.UploadingToS3,
+ momentId: '',
+ originalVideoDuration: videoLength,
+ };
+ // set progress bar as loading
+ dispatch({
+ type: setMomentUploadProgressBar.type,
+ payload: {momentUploadProgressBar},
+ });
+ // get a presigned url for the video
+ const presignedURLResponse = await handlePresignedURL(momentCategory);
+ if (!presignedURLResponse) {
+ handleError('Presigned URL failed');
+ return;
+ }
+ const momentId = presignedURLResponse.moment_id;
+ const fileHash = presignedURLResponse.response_url.fields.key;
+ // upload moment tags, now that we have a moment id
+ const momentTagResponse = await postMomentTags(momentId, formattedTags);
+ if (!momentTagResponse) {
+ handleError('Upload moment tags failed');
+ return;
+ }
+ if (!fileHash) {
+ handleError('Unable to parse file hash from presigned response');
+ return;
+ }
+ // upload video to s3
+ const videoUploadResponse = await handleVideoUpload(
+ videoUri,
+ presignedURLResponse,
+ );
+ if (!videoUploadResponse) {
+ handleError('Video upload failed');
+ return;
+ }
+ dispatch({
+ type: setMomentUploadProgressBar.type,
+ payload: {
+ momentUploadProgressBar: {
+ ...momentUploadProgressBar,
+ status: MomentUploadStatusType.WaitingForDoneProcessing,
+ momentId,
+ },
+ },
+ });
+ } catch (error) {
+ console.log(error);
+ }
+ };
diff --git a/src/store/initialStates.ts b/src/store/initialStates.ts
index ddfdf5d2..7d8cf439 100644
--- a/src/store/initialStates.ts
+++ b/src/store/initialStates.ts
@@ -11,7 +11,6 @@ import {
CommentThreadType,
MomentPostType,
MomentUploadProgressBarType,
- MomentUploadStatusType,
UniversityType,
} from './../types/types';
diff --git a/src/types/types.ts b/src/types/types.ts
index 34bf73ac..685e3784 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -68,7 +68,8 @@ export interface MomentUploadProgressBarType {
}
export enum MomentUploadStatusType {
- Uploading = 'Uploading',
+ UploadingToS3 = 'UploadingToS3',
+ WaitingForDoneProcessing = 'WaitingForDoneProcessing',
Done = 'Done',
Error = 'Error',
}