diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/assets/images/avatar-placeholder.png | bin | 2982 -> 0 bytes | |||
-rw-r--r-- | src/assets/images/cover-placeholder.png | bin | 4117 -> 0 bytes | |||
-rw-r--r-- | src/components/profile/Avatar.tsx | 7 | ||||
-rw-r--r-- | src/components/profile/Cover.tsx | 11 | ||||
-rw-r--r-- | src/components/search/SearchCategories.tsx | 18 | ||||
-rw-r--r-- | src/constants/api.ts | 1 | ||||
-rw-r--r-- | src/services/UserFriendsService.ts | 3 | ||||
-rw-r--r-- | src/services/UserProfileService.ts | 114 | ||||
-rw-r--r-- | src/store/actions/user.ts | 7 | ||||
-rw-r--r-- | src/store/actions/userX.ts | 83 | ||||
-rw-r--r-- | src/store/initialStates.ts | 15 | ||||
-rw-r--r-- | src/types/types.ts | 17 | ||||
-rw-r--r-- | src/utils/friends.ts | 4 | ||||
-rw-r--r-- | src/utils/users.ts | 24 |
14 files changed, 139 insertions, 165 deletions
diff --git a/src/assets/images/avatar-placeholder.png b/src/assets/images/avatar-placeholder.png Binary files differdeleted file mode 100644 index 313f384e..00000000 --- a/src/assets/images/avatar-placeholder.png +++ /dev/null diff --git a/src/assets/images/cover-placeholder.png b/src/assets/images/cover-placeholder.png Binary files differdeleted file mode 100644 index 141167d1..00000000 --- a/src/assets/images/cover-placeholder.png +++ /dev/null diff --git a/src/components/profile/Avatar.tsx b/src/components/profile/Avatar.tsx index ba4ec36c..5d677983 100644 --- a/src/components/profile/Avatar.tsx +++ b/src/components/profile/Avatar.tsx @@ -19,11 +19,8 @@ const Avatar: React.FC<AvatarProps> = ({style, screenType, userXId}) => { return ( <Image style={[styles.image, style]} - source={ - avatar - ? {uri: avatar} - : require('../../assets/images/avatar-placeholder.png') - } + defaultSource={require('../../assets/images/avatar-placeholder.png')} + source={{uri: avatar}} /> ); }; diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index a03ef123..b7502cff 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {Image, StyleSheet, View} from 'react-native'; -import {IMAGE_WIDTH, COVER_HEIGHT, IMAGE_HEIGHT} from '../../constants'; import {useSelector} from 'react-redux'; +import {COVER_HEIGHT, IMAGE_WIDTH} from '../../constants'; import {RootState} from '../../store/rootreducer'; import {ScreenType} from '../../types'; @@ -10,7 +10,7 @@ interface CoverProps { screenType: ScreenType; } const Cover: React.FC<CoverProps> = ({userXId, screenType}) => { - const {cover = ''} = userXId + const {cover} = userXId ? useSelector((state: RootState) => state.userX[screenType][userXId]) : useSelector((state: RootState) => state.user); @@ -18,11 +18,8 @@ const Cover: React.FC<CoverProps> = ({userXId, screenType}) => { <View style={[styles.container]}> <Image style={styles.image} - source={ - cover - ? {uri: cover} - : require('../../assets/images/cover-placeholder.png') - } + defaultSource={require('../../assets/images/cover-placeholder.png')} + source={{uri: cover}} /> </View> ); diff --git a/src/components/search/SearchCategories.tsx b/src/components/search/SearchCategories.tsx index 4bae27c2..c747b34f 100644 --- a/src/components/search/SearchCategories.tsx +++ b/src/components/search/SearchCategories.tsx @@ -73,23 +73,5 @@ const styles = StyleSheet.create({ flexWrap: 'wrap', justifyContent: 'space-evenly', }, - buttonContainer: { - backgroundColor: 'transparent', - width: 158, - height: 37, - borderRadius: 20, - borderColor: 'transparent', - borderWidth: 1, - flexDirection: 'row', - alignContent: 'center', - justifyContent: 'center', - }, - buttonText: { - fontWeight: '400', - fontSize: 15, - lineHeight: 17.9, - alignSelf: 'center', - color: 'white', - }, }); export default SearchCategories; diff --git a/src/constants/api.ts b/src/constants/api.ts index 1e2e887a..6afdf384 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -9,6 +9,7 @@ export const REGISTER_ENDPOINT: string = API_URL + 'register/'; export const EDIT_PROFILE_ENDPOINT: string = API_URL + 'edit-profile/'; export const SEND_OTP_ENDPOINT: string = API_URL + 'send-otp/'; export const VERIFY_OTP_ENDPOINT: string = API_URL + 'verify-otp/'; +export const USER_PROFILE_ENDPOINT: string = API_URL + 'profile/'; export const PROFILE_INFO_ENDPOINT: string = API_URL + 'user-profile-info/'; export const HEADER_PHOTO_ENDPOINT: string = API_URL + 'header-pic/'; export const PROFILE_PHOTO_ENDPOINT: string = API_URL + 'profile-pic/'; diff --git a/src/services/UserFriendsService.ts b/src/services/UserFriendsService.ts index c36cdaa7..da39380f 100644 --- a/src/services/UserFriendsService.ts +++ b/src/services/UserFriendsService.ts @@ -24,12 +24,11 @@ export const loadFriends = async (userId: string, token: string) => { if (response.status === 200) { const body = await response.json(); return body; - } else { - throw new Error(await response.json()); } } catch (error) { console.log(error); } + return []; }; export const friendOrUnfriendUser = async ( diff --git a/src/services/UserProfileService.ts b/src/services/UserProfileService.ts index dd77db9f..e00c0530 100644 --- a/src/services/UserProfileService.ts +++ b/src/services/UserProfileService.ts @@ -1,7 +1,6 @@ import AsyncStorage from '@react-native-community/async-storage'; import moment from 'moment'; import {Alert} from 'react-native'; -import RNFetchBlob from 'rn-fetch-blob'; import { GET_FB_POSTS_ENDPOINT, GET_IG_POSTS_ENDPOINT, @@ -10,10 +9,10 @@ import { PASSWORD_RESET_ENDPOINT, PROFILE_INFO_ENDPOINT, PROFILE_PHOTO_ENDPOINT, - PROFILE_PHOTO_THUMBNAIL_ENDPOINT, REGISTER_ENDPOINT, SEND_OTP_ENDPOINT, TAGG_CUSTOMER_SUPPORT, + USER_PROFILE_ENDPOINT, VERIFY_OTP_ENDPOINT, } from '../constants'; import { @@ -27,7 +26,7 @@ import { SUCCESS_PWD_RESET, SUCCESS_VERIFICATION_CODE_SENT, } from '../constants/strings'; -import {SocialAccountType} from '../types'; +import {ProfileInfoType, ProfileType, SocialAccountType} from '../types'; export const loadProfileInfo = async (token: string, userId: string) => { try { @@ -39,35 +38,11 @@ export const loadProfileInfo = async (token: string, userId: string) => { }); const status = response.status; if (status === 200) { - const info = await response.json(); - let { - name, - biography, - website, - birthday, - gender, - snapchat, - tiktok, - university_class, - profile_completion_stage, - suggested_people_linked, - friendship_status, - friendship_requester_id, - } = info; - birthday = birthday && moment(birthday).format('YYYY-MM-DD'); + const data: ProfileInfoType = await response.json(); + const birthday = data.birthday; return { - name, - biography, - website, - birthday, - gender, - snapchat, - tiktok, - university_class, - profile_completion_stage, - suggested_people_linked, - friendship_status, - friendship_requester_id, + ...data, + birthday: birthday && moment(birthday).format('YYYY-MM-DD'), }; } else { throw 'Unable to load profile data'; @@ -77,43 +52,22 @@ export const loadProfileInfo = async (token: string, userId: string) => { } }; -export const loadAvatar = async (userId: string, thumbnail: boolean) => { - try { - const token = await AsyncStorage.getItem('token'); - const url = thumbnail - ? PROFILE_PHOTO_THUMBNAIL_ENDPOINT - : PROFILE_PHOTO_ENDPOINT; - const response = await RNFetchBlob.config({ - fileCache: true, - appendExt: 'jpg', - }).fetch('GET', url + `${userId}/`, { - Authorization: 'Token ' + token, - }); - const status = response.info().status; - if (status === 200) { - return response.path(); - } else { - return ''; - } - } catch (error) { - console.log(error); - return ''; - } -}; - -export const loadCover = async (token: string, userId: string) => { +export const getProfilePic = async ( + token: string, + userId: string, + type: 'profile' | 'header', +) => { try { - let response = await RNFetchBlob.config({ - fileCache: true, - appendExt: 'jpg', - }).fetch('GET', HEADER_PHOTO_ENDPOINT + `${userId}/`, { - Authorization: 'Token ' + token, + const url = + type === 'profile' ? PROFILE_PHOTO_ENDPOINT : HEADER_PHOTO_ENDPOINT; + const response = await fetch(url + `${userId}/`, { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, }); - const status = response.info().status; - if (status === 200) { - return response.path(); - } else { - return ''; + if (response.status === 200) { + return (await response.json()).url; } } catch (error) { console.log(error); @@ -129,8 +83,11 @@ const integratedSocialPostsEndpoints: {[social: string]: string} = { export const loadSocialPosts: ( userId: string, socialType: string, -) => Promise<SocialAccountType> = async (userId, socialType) => { - const token = await AsyncStorage.getItem('token'); + token?: string, +) => Promise<SocialAccountType> = async (userId, socialType, token) => { + if (!token) { + token = (await AsyncStorage.getItem('token')) ?? ''; + } const endpoint = integratedSocialPostsEndpoints[socialType]; const accountData: SocialAccountType = {}; accountData.posts = []; @@ -356,3 +313,24 @@ export const sendRegister = async ( return undefined; } }; + +export const fetchUserProfile = async (userId: string, token?: string) => { + try { + if (!token) { + token = (await AsyncStorage.getItem('token')) ?? ''; + } + const response = await fetch(USER_PROFILE_ENDPOINT + userId + '/', { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, + }); + if (response.status === 200) { + const data: ProfileType = await response.json(); + return data; + } + } catch (error) { + console.log(error); + return undefined; + } +}; diff --git a/src/store/actions/user.ts b/src/store/actions/user.ts index 4f1da47c..46f96d9a 100644 --- a/src/store/actions/user.ts +++ b/src/store/actions/user.ts @@ -1,7 +1,6 @@ import {Action, ThunkAction} from '@reduxjs/toolkit'; import { - loadAvatar, - loadCover, + getProfilePic, loadProfileInfo, sendSuggestedPeopleLinked, } from '../../services'; @@ -43,8 +42,8 @@ export const loadUserData = ( const token = await getTokenOrLogout(dispatch); const [profile, avatar, cover] = await Promise.all([ loadProfileInfo(token, user.userId), - loadAvatar(user.userId, false), - loadCover(token, user.userId), + getProfilePic(token, user.userId, 'profile'), + getProfilePic(token, user.userId, 'header'), ]); dispatch({ type: userDetailsFetched.type, diff --git a/src/store/actions/userX.ts b/src/store/actions/userX.ts index 07bea678..f32a4d8f 100644 --- a/src/store/actions/userX.ts +++ b/src/store/actions/userX.ts @@ -1,28 +1,27 @@ -import {userXInStore} from './../../utils/'; -import {getTokenOrLogout, loadAllSocialsForUser} from './../../utils'; -import {UserType, ScreenType} from '../../types/types'; -import {RootState} from '../rootReducer'; import {Action, ThunkAction} from '@reduxjs/toolkit'; +import moment from 'moment'; import { - userXRequested, + fetchUserProfile, + loadFriends, + loadMoments, + loadProfileInfo, +} from '../../services'; +import {ScreenType, UserType} from '../../types/types'; +import { + resetScreen, userXAvatarFetched, - userXFriendsFetched, userXCoverFetched, + userXFriendsFetched, + userXMomentCategoriesFetched, userXMomentsFetched, userXProfileFetched, + userXRequested, userXSocialsFetched, userXUserFetched, - userXMomentCategoriesFetched, - resetScreen, } from '../reducers'; -import { - loadProfileInfo, - loadAvatar, - loadCover, - loadFriends, - loadMomentCategories, - loadMoments, -} from '../../services'; +import {RootState} from '../rootReducer'; +import {getTokenOrLogout, loadAllSocialsForUser} from './../../utils'; +import {userXInStore} from './../../utils/'; export const loadUserX = ( user: UserType, @@ -38,30 +37,40 @@ export const loadUserX = ( payload: {screenType, userId, user}, }); const token = await getTokenOrLogout(dispatch); - loadProfileInfo(token, userId).then((data) => { - dispatch({ - type: userXProfileFetched.type, - payload: {screenType, userId, data}, - }); + fetchUserProfile(userId, token).then((profile) => { + if (profile) { + const birthday = profile.profile_info.birthday; + dispatch({ + type: userXProfileFetched.type, + payload: { + screenType, + userId, + data: { + ...profile.profile_info, + birthday: birthday && moment(birthday).format('YYYY-MM-DD'), + }, + }, + }); + dispatch({ + type: userXAvatarFetched.type, + payload: {screenType, userId, data: profile.profile_pic}, + }); + dispatch({ + type: userXCoverFetched.type, + payload: {screenType, userId, data: profile.header_pic}, + }); + dispatch({ + type: userXMomentCategoriesFetched.type, + payload: {screenType, userId, data: profile.moment_categories}, + }); + } }); - loadAllSocialsForUser(userId).then((data) => + loadAllSocialsForUser(userId, token).then((data) => dispatch({ type: userXSocialsFetched.type, payload: {screenType, userId, data}, }), ); - loadAvatar(userId, false).then((data) => - dispatch({ - type: userXAvatarFetched.type, - payload: {screenType, userId, data}, - }), - ); - loadCover(token, userId).then((data) => - dispatch({ - type: userXCoverFetched.type, - payload: {screenType, userId, data}, - }), - ); loadFriends(userId, token).then((data) => dispatch({ type: userXFriendsFetched.type, @@ -74,12 +83,6 @@ export const loadUserX = ( payload: {screenType, userId, data}, }), ); - loadMomentCategories(userId, token).then((data) => { - dispatch({ - type: userXMomentCategoriesFetched.type, - payload: {screenType, userId, data}, - }); - }); } catch (error) { console.log(error); } diff --git a/src/store/initialStates.ts b/src/store/initialStates.ts index 28a4d10a..47ab8f39 100644 --- a/src/store/initialStates.ts +++ b/src/store/initialStates.ts @@ -3,14 +3,14 @@ import { MomentType, NotificationType, ProfilePreviewType, - ProfileType, + ProfileInfoType, ScreenType, SocialAccountType, UserType, UserXType, } from '../types'; -export const NO_PROFILE: ProfileType = { +export const NO_PROFILE: ProfileInfoType = { biography: '', website: '', name: '', @@ -25,6 +25,7 @@ export const NO_PROFILE: ProfileType = { tiktok: '', friendship_status: 'no_record', friendship_requester_id: '', + is_private: true, }; export const EMPTY_MOMENTS_LIST = <MomentType[]>[]; @@ -40,9 +41,9 @@ export const EMPTY_PROFILE_PREVIEW_LIST = <ProfilePreviewType[]>[]; export const NO_USER_DATA = { user: <UserType>NO_USER, - profile: <ProfileType>NO_PROFILE, - avatar: <string | null>'', - cover: <string | null>'', + profile: <ProfileInfoType>NO_PROFILE, + avatar: <string | undefined>undefined, + cover: <string | undefined>undefined, isOnboardedUser: false, newVersionAvailable: false, newNotificationReceived: false, @@ -97,8 +98,8 @@ export const EMPTY_USER_X = <UserXType>{ socialAccounts: NO_SOCIAL_ACCOUNTS, user: NO_USER, profile: NO_PROFILE, - avatar: '', - cover: '', + avatar: undefined, + cover: undefined, }; /** diff --git a/src/types/types.ts b/src/types/types.ts index fc77ba4b..9a40e4c0 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -21,7 +21,15 @@ export interface CategoryPreviewType { export type FriendshipStatusType = 'friends' | 'requested' | 'no_record'; -export interface ProfileType { +export type ProfileType = { + profile_pic: string; + header_pic: string; + profile_info: ProfileInfoType; + moment_categories: string[]; + linked_socials: string[]; +}; + +export interface ProfileInfoType { name: string; biography: string; website: string; @@ -34,6 +42,7 @@ export interface ProfileType { tiktok: string; friendship_status: FriendshipStatusType; friendship_requester_id: string; + is_private: boolean; } export interface SocialAccountType { @@ -138,9 +147,9 @@ export interface UserXType { socialAccounts: Record<string, SocialAccountType>; momentCategories: string[]; user: UserType; - profile: ProfileType; - avatar: string; - cover: string; + profile: ProfileInfoType; + avatar: string | undefined; + cover: string | undefined; } /** diff --git a/src/utils/friends.ts b/src/utils/friends.ts index 55d65170..5b0ded8f 100644 --- a/src/utils/friends.ts +++ b/src/utils/friends.ts @@ -1,7 +1,7 @@ // Handles click on friend/requested/unfriend button import {RootState} from '../store/rootReducer'; -import {ProfilePreviewType, ProfileType, ScreenType, UserType} from '../types'; +import {ProfilePreviewType, ProfileInfoType, ScreenType, UserType} from '../types'; import {AppDispatch} from '../store/configureStore'; import { addFriend, @@ -25,7 +25,7 @@ import {getUserAsProfilePreviewType} from './users'; export const handleFriendUnfriend = async ( screenType: ScreenType, user: UserType, - profile: ProfileType, + profile: ProfileInfoType, dispatch: AppDispatch, state: RootState, loggedInUser: UserType, diff --git a/src/utils/users.ts b/src/utils/users.ts index 82bcb309..d5e44b36 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -20,7 +20,7 @@ import {RootState} from './../store/rootReducer'; import { ProfilePreviewType, CategoryPreviewType, - ProfileType, + ProfileInfoType, ScreenType, UserType, } from './../types/types'; @@ -103,13 +103,22 @@ export const userXInStore = ( * Abstracted the code to laod all socials out. * @param userId userId for whom socials should be fetched */ -export const loadAllSocialsForUser = async (userId: string) => { +export const loadAllSocialsForUser = async (userId: string, token?: string) => { + if (!token) { + token = (await AsyncStorage.getItem('token')) ?? ''; + } let socials = NO_SOCIAL_ACCOUNTS; try { - let socialNeedsUpdate = INTEGRATED_SOCIAL_LIST; - for (let socialType of socialNeedsUpdate) { - const social = await loadSocialPosts(userId, socialType); - socials = {...socials, [socialType]: social}; + const fetchedSocials = await Promise.all( + INTEGRATED_SOCIAL_LIST.map((socialType) => + loadSocialPosts(userId, socialType, token).then((data) => ({ + key: socialType, + data, + })), + ), + ); + for (const fetchedSocial of fetchedSocials) { + socials = {...socials, [fetchedSocial.key]: fetchedSocial.data}; } return socials; } catch (error) { @@ -137,7 +146,7 @@ export const getTokenOrLogout = async (dispatch: Function): Promise<string> => { */ export const getUserAsProfilePreviewType = ( passedInUser: UserType, - passedInProfile: ProfileType, + passedInProfile: ProfileInfoType, ): ProfilePreviewType => { const fullName = passedInProfile.name.split(' '); return { @@ -165,4 +174,3 @@ export const defaultUserProfile = () => { const defaultImage = require('../assets/images/avatar-placeholder.png'); return defaultImage; }; - |