diff options
author | Ivan Chen <ivan@tagg.id> | 2021-02-12 19:31:32 -0500 |
---|---|---|
committer | Ivan Chen <ivan@tagg.id> | 2021-02-12 19:31:32 -0500 |
commit | 5cdde33f9c35c1d26f47d0a71ee75c635a94ee49 (patch) | |
tree | 8edbe5cce80696e7a3aaf98e463acca4c8ba7c21 | |
parent | dfff52bb9c7e8a284e465cd90a61ada94a8d6a4e (diff) |
now using suggested_people_linked, moved things around
-rw-r--r-- | src/screens/suggestedPeople/AnimatedTutorial.tsx | 16 | ||||
-rw-r--r-- | src/screens/suggestedPeople/SuggestedPeopleScreen.tsx | 21 | ||||
-rw-r--r-- | src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx | 36 | ||||
-rw-r--r-- | src/services/SuggestedPeopleService.ts | 39 | ||||
-rw-r--r-- | src/services/UserProfileService.ts | 47 | ||||
-rw-r--r-- | src/services/index.ts | 1 | ||||
-rw-r--r-- | src/store/actions/user.ts | 53 | ||||
-rw-r--r-- | src/store/initialStates.ts | 3 | ||||
-rw-r--r-- | src/store/reducers/userReducer.ts | 11 | ||||
-rw-r--r-- | src/types/types.ts | 3 |
10 files changed, 114 insertions, 116 deletions
diff --git a/src/screens/suggestedPeople/AnimatedTutorial.tsx b/src/screens/suggestedPeople/AnimatedTutorial.tsx index 8ebdaea6..bf34ba6e 100644 --- a/src/screens/suggestedPeople/AnimatedTutorial.tsx +++ b/src/screens/suggestedPeople/AnimatedTutorial.tsx @@ -1,13 +1,13 @@ -import * as React from 'react'; -import CloseIcon from '../../assets/ionicons/close-outline.svg'; +import {useNavigation} from '@react-navigation/native'; +import React from 'react'; import {StyleSheet, Text, View} from 'react-native'; import {Image} from 'react-native-animatable'; -import {isIPhoneX, SCREEN_WIDTH} from '../../utils'; import {SafeAreaView} from 'react-native-safe-area-context'; -import {useNavigation} from '@react-navigation/native'; import {useDispatch, useSelector} from 'react-redux'; +import CloseIcon from '../../assets/ionicons/close-outline.svg'; +import {suggestedPeopleAnimatedTutorialFinished} from '../../store/actions/user'; import {RootState} from '../../store/rootReducer'; -import {updateSPSwipeTutorial} from '../../store/actions/user'; +import {isIPhoneX, SCREEN_WIDTH} from '../../utils'; const AnimatedTutorial: React.FC = () => { const navigation = useNavigation(); @@ -15,11 +15,7 @@ const AnimatedTutorial: React.FC = () => { const {user} = useSelector((state: RootState) => state.user); const handleCloseAnimationTutorial = async () => { - /* In user's store, check if profile.sp_swipe_tutorial === 0 - * Make call to edit profile endpoint with suggested people === 1 - */ - const data = 1; - dispatch(updateSPSwipeTutorial(user, data)); + dispatch(suggestedPeopleAnimatedTutorialFinished(user.userId)); navigation.pop(); }; return ( diff --git a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx index a0c227d6..49806544 100644 --- a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx +++ b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx @@ -23,7 +23,7 @@ import {isIPhoneX, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; */ const SuggestedPeopleScreen: React.FC = () => { - const {onboarded_sugggested_people} = useSelector( + const {suggested_people_linked} = useSelector( (state: RootState) => state.user.profile, ); const y = Animated.useValue(0); @@ -34,22 +34,17 @@ const SuggestedPeopleScreen: React.FC = () => { // Adviced to maintain username as a variable here to append @ symbol for maintainability const username = '@' + 'sarahmiller'; const navigation = useNavigation(); - const { - profile: {sp_swipe_tutorial}, - } = useSelector((state: RootState) => state.user); useFocusEffect( useCallback(() => { const navigateToAnimatedTutorial = () => { - /* In user's store, check if profile.sp_swipe_tutorial === 0 - * If, true show tutorial. - */ - if (sp_swipe_tutorial === 0 && onboarded_sugggested_people) { + // if the user has finished the previous SP onboarding + if (suggested_people_linked === 1) { navigation.navigate('AnimatedTutorial'); } }; navigateToAnimatedTutorial(); - }, [sp_swipe_tutorial, navigation, onboarded_sugggested_people]), + }, [navigation, suggested_people_linked]), ); const mainContent = () => ( @@ -84,18 +79,16 @@ const SuggestedPeopleScreen: React.FC = () => { screenType={ScreenType.SuggestedPeople} /> {/* TODO: Add MutualFriends here */} - {/* TODO: Add TaggsBar here */} - {/* TODO: Add MutualFriends here */} </View> </View> <TabsGradient /> </SafeAreaView> ); - return onboarded_sugggested_people ? ( - mainContent() - ) : ( + return suggested_people_linked === 0 ? ( <SuggestedPeopleOnboardingStackScreen /> + ) : ( + mainContent() ); }; diff --git a/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx b/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx index 98986a70..a0ac27e6 100644 --- a/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx +++ b/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx @@ -1,19 +1,29 @@ import React, {useState} from 'react'; -import {Image, ImageBackground, StatusBar, StyleSheet} from 'react-native'; +import { + Alert, + Image, + ImageBackground, + StatusBar, + StyleSheet, +} from 'react-native'; import {Text} from 'react-native-animatable'; import {TouchableOpacity} from 'react-native-gesture-handler'; import ImagePicker from 'react-native-image-crop-picker'; import {SafeAreaView} from 'react-native-safe-area-context'; -import {useDispatch} from 'react-redux'; +import {useDispatch, useSelector} from 'react-redux'; import {TaggSquareButton} from '../../components'; import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator'; import {SP_HEIGHT, SP_WIDTH} from '../../constants'; -import {updateOnboardedSuggestedPeople} from '../../store/actions'; +import {ERROR_UPLOAD} from '../../constants/strings'; +import {sendSuggestedPeoplePhoto} from '../../services'; +import {uploadedSuggestedPeoplePhoto} from '../../store/actions'; +import {RootState} from '../../store/rootReducer'; import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; const SuggestedPeopleUploadPictureScreen: React.FC = () => { const [image, setImage] = useState<string | undefined>(undefined); const [loading, setLoading] = useState(false); + const {userId} = useSelector((state: RootState) => state.user.user); const dispatch = useDispatch(); const openImagePicker = () => { @@ -39,17 +49,17 @@ const SuggestedPeopleUploadPictureScreen: React.FC = () => { .catch((_) => {}); }; - const uploadImage = () => { - // TODO: hit endpoint + const uploadImage = async () => { setLoading(true); - setTimeout(() => { - setLoading(false); - dispatch( - updateOnboardedSuggestedPeople(true, () => { - console.log('updated'); - }), - ); - }, 1000); + if (image) { + const success = await sendSuggestedPeoplePhoto(userId, image); + if (success) { + dispatch(uploadedSuggestedPeoplePhoto()); + } else { + Alert.alert(ERROR_UPLOAD); + } + } + setLoading(false); }; return ( diff --git a/src/services/SuggestedPeopleService.ts b/src/services/SuggestedPeopleService.ts new file mode 100644 index 00000000..4be8c3a5 --- /dev/null +++ b/src/services/SuggestedPeopleService.ts @@ -0,0 +1,39 @@ +import AsyncStorage from '@react-native-community/async-storage'; +import {EDIT_PROFILE_ENDPOINT} from '../constants'; + +export const sendSuggestedPeopleLinked = async ( + userId: string, + stage: number, +) => { + try { + const request = new FormData(); + request.append('suggested_people_linked', stage); + const endpoint = EDIT_PROFILE_ENDPOINT + `${userId}/`; + const token = await AsyncStorage.getItem('token'); + let response = await fetch(endpoint, { + method: 'PATCH', + headers: { + 'Content-Type': 'multipart/form-data', + Authorization: 'Token ' + token, + }, + body: request, + }); + return response.status === 200; + } catch (error) { + console.log('Error updating animated tutorial close button press'); + return false; + } +}; + +export const sendSuggestedPeoplePhoto = async ( + useId: string, + photoUri: string, +) => { + try { + // TODO: hit endpoint here + return true; + } catch (error) { + console.log('Error uploading SP photo'); + return false; + } +}; diff --git a/src/services/UserProfileService.ts b/src/services/UserProfileService.ts index ce9bdda5..fff35370 100644 --- a/src/services/UserProfileService.ts +++ b/src/services/UserProfileService.ts @@ -2,20 +2,18 @@ import AsyncStorage from '@react-native-community/async-storage'; import moment from 'moment'; import {Alert} from 'react-native'; import RNFetchBlob from 'rn-fetch-blob'; -import {SocialAccountType, UserType} from '../types'; import { - PROFILE_PHOTO_ENDPOINT, - HEADER_PHOTO_ENDPOINT, GET_FB_POSTS_ENDPOINT, GET_IG_POSTS_ENDPOINT, GET_TWITTER_POSTS_ENDPOINT, - PROFILE_INFO_ENDPOINT, + HEADER_PHOTO_ENDPOINT, PASSWORD_RESET_ENDPOINT, + PROFILE_INFO_ENDPOINT, + PROFILE_PHOTO_ENDPOINT, + PROFILE_PHOTO_THUMBNAIL_ENDPOINT, + SEND_OTP_ENDPOINT, TAGG_CUSTOMER_SUPPORT, VERIFY_OTP_ENDPOINT, - SEND_OTP_ENDPOINT, - PROFILE_PHOTO_THUMBNAIL_ENDPOINT, - EDIT_PROFILE_ENDPOINT, } from '../constants'; import { ERROR_DOUBLE_CHECK_CONNECTION, @@ -28,6 +26,7 @@ import { SUCCESS_PWD_RESET, SUCCESS_VERIFICATION_CODE_SENT, } from '../constants/strings'; +import {SocialAccountType} from '../types'; export const loadProfileInfo = async (token: string, userId: string) => { try { @@ -50,16 +49,11 @@ export const loadProfileInfo = async (token: string, userId: string) => { tiktok, university_class, profile_completion_stage, - sp_swipe_tutorial, - // onboarded_sugggested_people, + suggested_people_linked, friendship_status, friendship_requester_id, } = info; birthday = birthday && moment(birthday).format('YYYY-MM-DD'); - console.log( - 'Suggested People loaded from backend for logged in user: ', - sp_swipe_tutorial, - ); return { name, biography, @@ -70,8 +64,7 @@ export const loadProfileInfo = async (token: string, userId: string) => { tiktok, university_class, profile_completion_stage, - sp_swipe_tutorial, - onboarded_sugggested_people: false, + suggested_people_linked, friendship_status, friendship_requester_id, }; @@ -322,27 +315,3 @@ export const sendOtp = async (phone: string) => { return false; } }; - -export const editSPSwipeTutorial = async (user: UserType) => { - try { - const request = new FormData(); - request.append('sp_swipe_tutorial', 1); - const endpoint = EDIT_PROFILE_ENDPOINT + `${user.userId}/`; - const token = await AsyncStorage.getItem('token'); - let response = await fetch(endpoint, { - method: 'PATCH', - headers: { - 'Content-Type': 'multipart/form-data', - Authorization: 'Token ' + token, - }, - body: request, - }); - if (response.status === 200) { - return true; - } else { - return false; - } - } catch (error) { - console.log('Error updating animated tutorial close button press'); - } -}; diff --git a/src/services/index.ts b/src/services/index.ts index 9c168d4f..ef71233a 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -11,3 +11,4 @@ export * from './FCMService'; export * from './WaitlistUserService'; export * from './CommonService'; export * from './CommentService'; +export * from './SuggestedPeopleService'; diff --git a/src/store/actions/user.ts b/src/store/actions/user.ts index 4229517d..ef134dc5 100644 --- a/src/store/actions/user.ts +++ b/src/store/actions/user.ts @@ -1,9 +1,9 @@ import {Action, ThunkAction} from '@reduxjs/toolkit'; import { - editSPSwipeTutorial, loadAvatar, loadCover, loadProfileInfo, + sendSuggestedPeopleLinked, } from '../../services'; import {UserType} from '../../types/types'; import {getTokenOrLogout} from '../../utils'; @@ -12,13 +12,12 @@ import { setIsOnboardedUser, setNewNotificationReceived, setNewVersionAvailable, - setOnboardedSuggestedPeople, setReplyPosted, + setSuggestedPeopleLinked, socialEdited, userDetailsFetched, userLoggedIn, } from '../reducers'; -import {spSwipeTutorialUpdated} from '../reducers/userReducer'; import {RootState} from '../rootReducer'; import {CommentThreadType} from './../../types/types'; @@ -91,24 +90,6 @@ export const updateProfileCompletionStage = ( } }; -// TODO: this should be called after a successful upload of a first SP image -export const updateOnboardedSuggestedPeople = ( - onboarded: boolean, - callback: () => void, -): ThunkAction<Promise<void>, RootState, unknown, Action<string>> => async ( - dispatch, -) => { - try { - dispatch({ - type: setOnboardedSuggestedPeople.type, - payload: {onboarded}, - }); - callback(); - } catch (error) { - console.log(error); - } -}; - export const updateIsOnboardedUser = ( isOnboardedUser: boolean, ): ThunkAction<Promise<void>, RootState, unknown, Action<string>> => async ( @@ -182,9 +163,24 @@ export const logout = (): ThunkAction< } }; -export const updateSPSwipeTutorial = ( - user: UserType, - data: number, +export const uploadedSuggestedPeoplePhoto = (): ThunkAction< + Promise<void>, + RootState, + unknown, + Action<string> +> => async (dispatch) => { + try { + dispatch({ + type: setSuggestedPeopleLinked.type, + payload: {stage: 1}, + }); + } catch (error) { + console.log(error); + } +}; + +export const suggestedPeopleAnimatedTutorialFinished = ( + userId: string, ): ThunkAction< Promise<boolean | undefined>, RootState, @@ -192,12 +188,13 @@ export const updateSPSwipeTutorial = ( Action<string> > => async (dispatch) => { try { - // update store first, assume success + // update store first, assume request is successful dispatch({ - type: spSwipeTutorialUpdated.type, - payload: {sp_swipe_tutorial: data}, + type: setSuggestedPeopleLinked.type, + payload: {stage: 2}, }); - return await editSPSwipeTutorial(user); + // need to tell the server that the stage is now 2 + return await sendSuggestedPeopleLinked(userId, 2); } catch (error) { console.log('Error while updating suggested people linked state: ', error); } diff --git a/src/store/initialStates.ts b/src/store/initialStates.ts index 31b39e82..10fdad25 100644 --- a/src/store/initialStates.ts +++ b/src/store/initialStates.ts @@ -21,8 +21,7 @@ export const NO_PROFILE: ProfileType = { //Default to an invalid value and ignore it gracefully while showing tutorials / popups. profile_completion_stage: -1, - sp_swipe_tutorial: 0, - onboarded_sugggested_people: false, + suggested_people_linked: -1, snapchat: '', tiktok: '', friendship_status: 'no_record', diff --git a/src/store/reducers/userReducer.ts b/src/store/reducers/userReducer.ts index ea14c9ab..5203fa3c 100644 --- a/src/store/reducers/userReducer.ts +++ b/src/store/reducers/userReducer.ts @@ -46,12 +46,8 @@ const userDataSlice = createSlice({ state.profile.profile_completion_stage = action.payload.stage; }, - spSwipeTutorialUpdated: (state, action) => { - state.profile.sp_swipe_tutorial = action.payload.sp_swipe_tutorial; - }, - - setOnboardedSuggestedPeople: (state, action) => { - state.profile.onboarded_sugggested_people = action.payload.onboarded; + setSuggestedPeopleLinked: (state, action) => { + state.profile.suggested_people_linked = action.payload.stage; }, setIsOnboardedUser: (state, action) => { @@ -77,11 +73,10 @@ export const { userDetailsFetched, socialEdited, profileCompletionStageUpdated, - setOnboardedSuggestedPeople, + setSuggestedPeopleLinked, setIsOnboardedUser, setNewVersionAvailable, setNewNotificationReceived, setReplyPosted, - spSwipeTutorialUpdated, } = userDataSlice.actions; export const userDataReducer = userDataSlice.reducer; diff --git a/src/types/types.ts b/src/types/types.ts index 19eaa8f0..bfa45a25 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -23,8 +23,7 @@ export interface ProfileType { gender: string; university_class: number; profile_completion_stage: number; - sp_swipe_tutorial: number; - onboarded_sugggested_people: boolean; + suggested_people_linked: number; birthday: Date | undefined; snapchat: string; tiktok: string; |