From 0e1f57be13b282b516f1bf690f2890b9eabf3188 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Wed, 12 May 2021 11:42:14 -0700 Subject: Plus sign for profile and header in profile, ability to add on the screen, reloads screen, saved to database --- src/assets/icons/grey-purple-plus.svg | 5 + src/assets/icons/purple-plus.svg | 15 +++ src/components/profile/Cover.tsx | 196 +++++++++++++++++++++++++++++++--- src/components/profile/TaggAvatar.tsx | 155 ++++++++++++++++++++++++++- src/screens/profile/EditProfile.tsx | 6 +- 5 files changed, 357 insertions(+), 20 deletions(-) create mode 100644 src/assets/icons/grey-purple-plus.svg create mode 100644 src/assets/icons/purple-plus.svg (limited to 'src') diff --git a/src/assets/icons/grey-purple-plus.svg b/src/assets/icons/grey-purple-plus.svg new file mode 100644 index 00000000..2053d4a7 --- /dev/null +++ b/src/assets/icons/grey-purple-plus.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/icons/purple-plus.svg b/src/assets/icons/purple-plus.svg new file mode 100644 index 00000000..20949b6d --- /dev/null +++ b/src/assets/icons/purple-plus.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index 27777b64..8aa6b0d3 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -1,28 +1,181 @@ -import React from 'react'; -import {Image, StyleSheet, View} from 'react-native'; -import {useSelector} from 'react-redux'; +import React, {useState, useEffect} from 'react'; +import { + Alert, + Image, + StyleSheet, + View, + TouchableOpacity, + Text, + ImageBackground, +} from 'react-native'; import {COVER_HEIGHT, IMAGE_WIDTH} from '../../constants'; -import {RootState} from '../../store/rootreducer'; import {ScreenType} from '../../types'; +import GreyPurplePlus from '../../assets/icons/grey-purple-plus.svg'; +import ImagePicker from 'react-native-image-crop-picker'; +import { + ERROR_UPLOAD_LARGE_PROFILE_PIC, + ERROR_UPLOAD_SMALL_PROFILE_PIC, +} from '../../constants/strings'; +import {patchEditProfile} from '../../services'; +import {useDispatch, useSelector} from 'react-redux'; +import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; +import {RootState} from '../../store/rootreducer'; interface CoverProps { userXId: string | undefined; screenType: ScreenType; } const Cover: React.FC = ({userXId, screenType}) => { - const {cover} = useSelector((state: RootState) => + const dispatch = useDispatch(); + const {cover, user} = useSelector((state: RootState) => userXId ? state.userX[screenType][userXId] : state.user, ); - return ( - - - - ); + const [needsUpdate, setNeedsUpdate] = useState(false); + const [loading, setLoading] = useState(false); + const [validImage, setValidImage] = useState(true); + + const { + profile: {website, biography, gender, snapchat, tiktok, university_class}, + avatar, + } = useSelector((state: RootState) => state.user); + + const isCustomGender = + gender !== '' && gender !== 'female' && gender !== 'male'; + + const [form, setForm] = React.useState({ + largePic: cover ? cover : '', + smallPic: avatar ? avatar : '', + website: website ? website : '', + bio: biography ? biography : '', + gender: isCustomGender ? 'custom' : gender, + customGenderText: isCustomGender ? gender : '', + snapchat: snapchat, + tiktok: tiktok, + isValidWebsite: true, + isValidBio: true, + isValidGender: true, + isValidSnapchat: true, + isValidTiktok: true, + attemptedSubmit: false, + classYear: university_class, + }); + + useEffect(() => { + checkAvatar(cover); + }, []); + + useEffect(() => { + if (needsUpdate) { + const userId = user.userId; + const username = user.username; + dispatch(resetHeaderAndProfileImage()); + dispatch(loadUserData({userId, username})); + } + }, [dispatch, needsUpdate]); + + const goToGalleryLargePic = () => { + ImagePicker.openPicker({ + smartAlbums: [ + 'Favorites', + 'RecentlyAdded', + 'SelfPortraits', + 'Screenshots', + 'UserLibrary', + ], + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Select Header', + mediaType: 'photo', + }).then((picture) => { + if ('path' in picture) { + setForm({ + ...form, + largePic: picture.path, + }); + handleSubmit(); + } + }); + }; + + const handleSubmit = () => { + if (!form.largePic) { + Alert.alert(ERROR_UPLOAD_LARGE_PROFILE_PIC); + return; + } + if (!form.smallPic) { + Alert.alert(ERROR_UPLOAD_SMALL_PROFILE_PIC); + return; + } + + const request = new FormData(); + request.append('largeProfilePicture', { + uri: form.largePic, + name: 'large_profile_pic.jpg', + type: 'image/jpg', + }); + + setLoading(true); + patchEditProfile(request, user.userId) + .then((_) => { + setNeedsUpdate(true); + setValidImage(true); + // navigation.pop(); + }) + .catch((error) => { + Alert.alert(error); + }); + setLoading(false); + }; + + const checkAvatar = (url: string | undefined) => { + if (!url) { + setValidImage(false); + } + fetch(url) + .then((res) => { + if (res.status === 200) { + setValidImage(true); + } else { + setValidImage(false); + } + }) + .catch((err) => { + setValidImage(false); + }); + }; + + if (!validImage && userXId === undefined && !loading) { + return ( + <> + + + goToGalleryLargePic()}> + + Add Picture + + + + + ); + } else { + return ( + + + + ); + } }; const styles = StyleSheet.create({ @@ -33,5 +186,20 @@ const styles = StyleSheet.create({ width: IMAGE_WIDTH, height: COVER_HEIGHT, }, + plus: { + position: 'absolute', + top: 75, + right: 125, + }, + text: { + color: 'white', + position: 'absolute', + fontSize: 18, + top: 80, + right: 20, + }, + touch: { + flex: 1, + }, }); export default Cover; diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index ea0bdb65..33650a04 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -1,9 +1,17 @@ -import React from 'react'; -import {StyleSheet} from 'react-native'; -import {useSelector} from 'react-redux'; +import React, {useState, useEffect} from 'react'; +import {Alert, StyleSheet, TouchableOpacity} from 'react-native'; import {RootState} from '../../store/rootreducer'; import {ScreenType} from '../../types'; import {Avatar} from '../common'; +import {useDispatch, useSelector} from 'react-redux'; +import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; +import PurplePlus from '../../assets/icons/purple-plus.svg'; +import ImagePicker from 'react-native-image-crop-picker'; +import { + ERROR_UPLOAD_LARGE_PROFILE_PIC, + ERROR_UPLOAD_SMALL_PROFILE_PIC, +} from '../../constants/strings'; +import {patchEditProfile} from '../../services'; const PROFILE_DIM = 100; @@ -20,8 +28,142 @@ const TaggAvatar: React.FC = ({ const {avatar} = useSelector((state: RootState) => userXId ? state.userX[screenType][userXId] : state.user, ); + const dispatch = useDispatch(); + const [needsUpdate, setNeedsUpdate] = useState(false); + const [loading, setLoading] = useState(false); + const [validImage, setValidImage] = useState(true); - return ; + const { + profile: {website, biography, gender, snapchat, tiktok, university_class}, + cover, + } = useSelector((state: RootState) => state.user); + const {user} = useSelector((state: RootState) => + userXId ? state.userX[screenType][userXId] : state.user, + ); + const isCustomGender = + gender !== '' && gender !== 'female' && gender !== 'male'; + + const [form, setForm] = React.useState({ + largePic: cover ? cover : '', + smallPic: avatar ? avatar : '', + website: website ? website : '', + bio: biography ? biography : '', + gender: isCustomGender ? 'custom' : gender, + customGenderText: isCustomGender ? gender : '', + snapchat: snapchat, + tiktok: tiktok, + isValidWebsite: true, + isValidBio: true, + isValidGender: true, + isValidSnapchat: true, + isValidTiktok: true, + attemptedSubmit: false, + classYear: university_class, + }); + + useEffect(() => { + checkAvatar(avatar); + }, []); + + useEffect(() => { + if (needsUpdate) { + const userId = user.userId; + const username = user.username; + dispatch(resetHeaderAndProfileImage()); + dispatch(loadUserData({userId, username})); + } + }, [dispatch, needsUpdate]); + + const goToGallerySmallPic = () => { + ImagePicker.openPicker({ + smartAlbums: [ + 'Favorites', + 'RecentlyAdded', + 'SelfPortraits', + 'Screenshots', + 'UserLibrary', + ], + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Select Profile Picture', + mediaType: 'photo', + cropperCircleOverlay: true, + }).then((picture) => { + if ('path' in picture) { + setForm({ + ...form, + smallPic: picture.path, + }); + handleSubmit(); + } + }); + }; + + const handleSubmit = async () => { + if (!form.largePic) { + Alert.alert(ERROR_UPLOAD_LARGE_PROFILE_PIC); + return; + } + if (!form.smallPic) { + Alert.alert(ERROR_UPLOAD_SMALL_PROFILE_PIC); + return; + } + + const request = new FormData(); + request.append('smallProfilePicture', { + uri: form.smallPic, + name: 'small_profile_pic.jpg', + type: 'image/jpg', + }); + + setLoading(true); + patchEditProfile(request, user.userId) + .then((_) => { + setNeedsUpdate(true); + setValidImage(true); + // navigation.pop(); + }) + .catch((error) => { + Alert.alert(error); + }); + setLoading(false); + }; + + const checkAvatar = (url: string | undefined) => { + if (!url) { + setValidImage(false); + } + fetch(url) + .then((res) => { + if (res.status === 200) { + setValidImage(true); + } else { + setValidImage(false); + } + }) + .catch((err) => { + setValidImage(false); + }); + }; + + console.log(avatar); + + if (!validImage && userXId === undefined && !loading) { + return ( + <> + + goToGallerySmallPic()}> + + + + ); + } else { + return ; + } }; const styles = StyleSheet.create({ @@ -30,6 +172,11 @@ const styles = StyleSheet.create({ width: PROFILE_DIM, borderRadius: PROFILE_DIM / 2, }, + plus: { + position: 'absolute', + bottom: 35, + right: 0, + }, }); export default TaggAvatar; diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx index 26802e45..dfb8ba1f 100644 --- a/src/screens/profile/EditProfile.tsx +++ b/src/screens/profile/EditProfile.tsx @@ -61,7 +61,7 @@ interface EditProfileProps { const EditProfile: React.FC = ({route, navigation}) => { const y: Animated.Value = Animated.useValue(0); - const {userId, username} = route.params; + const {userId} = route.params; const { profile: {website, biography, gender, snapchat, tiktok, university_class}, avatar, @@ -74,10 +74,12 @@ const EditProfile: React.FC = ({route, navigation}) => { useEffect(() => { if (needsUpdate) { + const userId = user.userId; + const username = user.username; dispatch(resetHeaderAndProfileImage()); dispatch(loadUserData({userId, username})); } - }, [dispatch, needsUpdate, userId, username]); + }, [dispatch, needsUpdate, user]); const [isCustomGender, setIsCustomGender] = React.useState( gender !== '' && gender !== 'female' && gender !== 'male', -- cgit v1.2.3-70-g09d2 From b4254a49ad74c4460889e7172ea3575eda8ef556 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Wed, 12 May 2021 11:45:03 -0700 Subject: Undid accidental changes to EditProfile.tsx --- src/screens/profile/EditProfile.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx index dfb8ba1f..dd491f81 100644 --- a/src/screens/profile/EditProfile.tsx +++ b/src/screens/profile/EditProfile.tsx @@ -61,7 +61,7 @@ interface EditProfileProps { const EditProfile: React.FC = ({route, navigation}) => { const y: Animated.Value = Animated.useValue(0); - const {userId} = route.params; + const {userId, username} = route.params; const { profile: {website, biography, gender, snapchat, tiktok, university_class}, avatar, @@ -74,12 +74,10 @@ const EditProfile: React.FC = ({route, navigation}) => { useEffect(() => { if (needsUpdate) { - const userId = user.userId; - const username = user.username; dispatch(resetHeaderAndProfileImage()); dispatch(loadUserData({userId, username})); } - }, [dispatch, needsUpdate, user]); + }, [dispatch, needsUpdate, userId, username]); const [isCustomGender, setIsCustomGender] = React.useState( gender !== '' && gender !== 'female' && gender !== 'male', @@ -116,7 +114,7 @@ const EditProfile: React.FC = ({route, navigation}) => { goToGalleryLargePic()} style={styles.largeProfileUploader}> {form.largePic ? ( = ({route, navigation}) => { goToGallerySmallPic()} style={styles.smallProfileUploader}> {form.smallPic ? ( Date: Wed, 12 May 2021 11:45:49 -0700 Subject: Undid accidental changes to EditProfile.tsx, round 2 electric bugaloo --- src/screens/profile/EditProfile.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/screens/profile/EditProfile.tsx b/src/screens/profile/EditProfile.tsx index dd491f81..26802e45 100644 --- a/src/screens/profile/EditProfile.tsx +++ b/src/screens/profile/EditProfile.tsx @@ -114,7 +114,7 @@ const EditProfile: React.FC = ({route, navigation}) => { goToGalleryLargePic()} + onPress={goToGalleryLargePic} style={styles.largeProfileUploader}> {form.largePic ? ( = ({route, navigation}) => { goToGallerySmallPic()} + onPress={goToGallerySmallPic} style={styles.smallProfileUploader}> {form.smallPic ? ( Date: Wed, 12 May 2021 11:51:46 -0700 Subject: lint fix --- src/components/profile/Cover.tsx | 2 +- src/components/profile/TaggAvatar.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index 8aa6b0d3..e0b1e7e8 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -141,7 +141,7 @@ const Cover: React.FC = ({userXId, screenType}) => { setValidImage(false); } }) - .catch((err) => { + .catch((_) => { setValidImage(false); }); }; diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index 33650a04..3b1e561e 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -142,7 +142,7 @@ const TaggAvatar: React.FC = ({ setValidImage(false); } }) - .catch((err) => { + .catch((_) => { setValidImage(false); }); }; -- cgit v1.2.3-70-g09d2 From 6437df335f7ee23c9e66cbf0d9a6857eb7cffff2 Mon Sep 17 00:00:00 2001 From: brian-tagg <83606050+brian-tagg@users.noreply.github.com> Date: Wed, 12 May 2021 14:23:32 -0700 Subject: Update src/components/profile/TaggAvatar.tsx Co-authored-by: Ivan Chen --- src/components/profile/TaggAvatar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index 3b1e561e..083a30fa 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -157,7 +157,7 @@ const TaggAvatar: React.FC = ({ accessible={true} accessibilityLabel="ADD PROFILE PICTURE" onPress={() => goToGallerySmallPic()}> - + ); -- cgit v1.2.3-70-g09d2 From d930b614bd79bcd7b55359be261f77fa6997f78e Mon Sep 17 00:00:00 2001 From: brian-tagg <83606050+brian-tagg@users.noreply.github.com> Date: Wed, 12 May 2021 14:23:44 -0700 Subject: Update src/components/profile/TaggAvatar.tsx Co-authored-by: Ivan Chen --- src/components/profile/TaggAvatar.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index 083a30fa..f74a202d 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -147,7 +147,6 @@ const TaggAvatar: React.FC = ({ }); }; - console.log(avatar); if (!validImage && userXId === undefined && !loading) { return ( -- cgit v1.2.3-70-g09d2 From 853bd0600e0da87af578c17ce9249e40888017b5 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Wed, 12 May 2021 17:42:47 -0700 Subject: Modularized as much as possible --- src/components/profile/Cover.tsx | 116 +++++----------------------------- src/components/profile/TaggAvatar.tsx | 115 ++++----------------------------- src/utils/common.ts | 17 +++++ src/utils/users.ts | 77 ++++++++++++++++++++++ 4 files changed, 123 insertions(+), 202 deletions(-) (limited to 'src') diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index e0b1e7e8..711eeb46 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -1,6 +1,5 @@ import React, {useState, useEffect} from 'react'; import { - Alert, Image, StyleSheet, View, @@ -11,15 +10,10 @@ import { import {COVER_HEIGHT, IMAGE_WIDTH} from '../../constants'; import {ScreenType} from '../../types'; import GreyPurplePlus from '../../assets/icons/grey-purple-plus.svg'; -import ImagePicker from 'react-native-image-crop-picker'; -import { - ERROR_UPLOAD_LARGE_PROFILE_PIC, - ERROR_UPLOAD_SMALL_PROFILE_PIC, -} from '../../constants/strings'; -import {patchEditProfile} from '../../services'; import {useDispatch, useSelector} from 'react-redux'; import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; import {RootState} from '../../store/rootreducer'; +import {patchProfile, validateImageLink} from '../../utils'; interface CoverProps { userXId: string | undefined; @@ -35,32 +29,6 @@ const Cover: React.FC = ({userXId, screenType}) => { const [loading, setLoading] = useState(false); const [validImage, setValidImage] = useState(true); - const { - profile: {website, biography, gender, snapchat, tiktok, university_class}, - avatar, - } = useSelector((state: RootState) => state.user); - - const isCustomGender = - gender !== '' && gender !== 'female' && gender !== 'male'; - - const [form, setForm] = React.useState({ - largePic: cover ? cover : '', - smallPic: avatar ? avatar : '', - website: website ? website : '', - bio: biography ? biography : '', - gender: isCustomGender ? 'custom' : gender, - customGenderText: isCustomGender ? gender : '', - snapchat: snapchat, - tiktok: tiktok, - isValidWebsite: true, - isValidBio: true, - isValidGender: true, - isValidSnapchat: true, - isValidTiktok: true, - attemptedSubmit: false, - classYear: university_class, - }); - useEffect(() => { checkAvatar(cover); }, []); @@ -74,76 +42,22 @@ const Cover: React.FC = ({userXId, screenType}) => { } }, [dispatch, needsUpdate]); - const goToGalleryLargePic = () => { - ImagePicker.openPicker({ - smartAlbums: [ - 'Favorites', - 'RecentlyAdded', - 'SelfPortraits', - 'Screenshots', - 'UserLibrary', - ], - width: 580, - height: 580, - cropping: true, - cropperToolbarTitle: 'Select Header', - mediaType: 'photo', - }).then((picture) => { - if ('path' in picture) { - setForm({ - ...form, - largePic: picture.path, - }); - handleSubmit(); - } - }); - }; - - const handleSubmit = () => { - if (!form.largePic) { - Alert.alert(ERROR_UPLOAD_LARGE_PROFILE_PIC); - return; - } - if (!form.smallPic) { - Alert.alert(ERROR_UPLOAD_SMALL_PROFILE_PIC); - return; - } - - const request = new FormData(); - request.append('largeProfilePicture', { - uri: form.largePic, - name: 'large_profile_pic.jpg', - type: 'image/jpg', - }); - + const handleNewImage = async () => { + setLoading(true); + const result = await patchProfile('Select Header Picture', user.userId); setLoading(true); - patchEditProfile(request, user.userId) - .then((_) => { - setNeedsUpdate(true); - setValidImage(true); - // navigation.pop(); - }) - .catch((error) => { - Alert.alert(error); - }); - setLoading(false); + if (result) { + setNeedsUpdate(true); + } else { + setLoading(false); + } }; - const checkAvatar = (url: string | undefined) => { - if (!url) { - setValidImage(false); + const checkAvatar = async (url: string | undefined) => { + const valid = await validateImageLink(url); + if (valid !== validImage) { + setValidImage(valid); } - fetch(url) - .then((res) => { - if (res.status === 200) { - setValidImage(true); - } else { - setValidImage(false); - } - }) - .catch((_) => { - setValidImage(false); - }); }; if (!validImage && userXId === undefined && !loading) { @@ -156,8 +70,8 @@ const Cover: React.FC = ({userXId, screenType}) => { source={{uri: cover, cache: 'reload'}}> goToGalleryLargePic()}> + accessibilityLabel="ADD HEADER PICTURE" + onPress={() => handleNewImage()}> Add Picture diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index f74a202d..1f6bbba6 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -1,17 +1,12 @@ import React, {useState, useEffect} from 'react'; -import {Alert, StyleSheet, TouchableOpacity} from 'react-native'; +import {StyleSheet, TouchableOpacity} from 'react-native'; import {RootState} from '../../store/rootreducer'; import {ScreenType} from '../../types'; import {Avatar} from '../common'; import {useDispatch, useSelector} from 'react-redux'; import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; import PurplePlus from '../../assets/icons/purple-plus.svg'; -import ImagePicker from 'react-native-image-crop-picker'; -import { - ERROR_UPLOAD_LARGE_PROFILE_PIC, - ERROR_UPLOAD_SMALL_PROFILE_PIC, -} from '../../constants/strings'; -import {patchEditProfile} from '../../services'; +import {patchProfile, validateImageLink} from '../../utils'; const PROFILE_DIM = 100; @@ -32,34 +27,9 @@ const TaggAvatar: React.FC = ({ const [needsUpdate, setNeedsUpdate] = useState(false); const [loading, setLoading] = useState(false); const [validImage, setValidImage] = useState(true); - - const { - profile: {website, biography, gender, snapchat, tiktok, university_class}, - cover, - } = useSelector((state: RootState) => state.user); const {user} = useSelector((state: RootState) => userXId ? state.userX[screenType][userXId] : state.user, ); - const isCustomGender = - gender !== '' && gender !== 'female' && gender !== 'male'; - - const [form, setForm] = React.useState({ - largePic: cover ? cover : '', - smallPic: avatar ? avatar : '', - website: website ? website : '', - bio: biography ? biography : '', - gender: isCustomGender ? 'custom' : gender, - customGenderText: isCustomGender ? gender : '', - snapchat: snapchat, - tiktok: tiktok, - isValidWebsite: true, - isValidBio: true, - isValidGender: true, - isValidSnapchat: true, - isValidTiktok: true, - attemptedSubmit: false, - classYear: university_class, - }); useEffect(() => { checkAvatar(avatar); @@ -74,80 +44,23 @@ const TaggAvatar: React.FC = ({ } }, [dispatch, needsUpdate]); - const goToGallerySmallPic = () => { - ImagePicker.openPicker({ - smartAlbums: [ - 'Favorites', - 'RecentlyAdded', - 'SelfPortraits', - 'Screenshots', - 'UserLibrary', - ], - width: 580, - height: 580, - cropping: true, - cropperToolbarTitle: 'Select Profile Picture', - mediaType: 'photo', - cropperCircleOverlay: true, - }).then((picture) => { - if ('path' in picture) { - setForm({ - ...form, - smallPic: picture.path, - }); - handleSubmit(); - } - }); - }; - - const handleSubmit = async () => { - if (!form.largePic) { - Alert.alert(ERROR_UPLOAD_LARGE_PROFILE_PIC); - return; - } - if (!form.smallPic) { - Alert.alert(ERROR_UPLOAD_SMALL_PROFILE_PIC); - return; - } - - const request = new FormData(); - request.append('smallProfilePicture', { - uri: form.smallPic, - name: 'small_profile_pic.jpg', - type: 'image/jpg', - }); - + const handleNewImage = async () => { setLoading(true); - patchEditProfile(request, user.userId) - .then((_) => { - setNeedsUpdate(true); - setValidImage(true); - // navigation.pop(); - }) - .catch((error) => { - Alert.alert(error); - }); - setLoading(false); + const result = await patchProfile('Select Profile Picture', user.userId); + if (result) { + setNeedsUpdate(true); + } else { + setLoading(false); + } }; - const checkAvatar = (url: string | undefined) => { - if (!url) { - setValidImage(false); + const checkAvatar = async (url: string | undefined) => { + const valid = await validateImageLink(url); + if (valid !== validImage) { + setValidImage(valid); } - fetch(url) - .then((res) => { - if (res.status === 200) { - setValidImage(true); - } else { - setValidImage(false); - } - }) - .catch((_) => { - setValidImage(false); - }); }; - if (!validImage && userXId === undefined && !loading) { return ( <> @@ -155,7 +68,7 @@ const TaggAvatar: React.FC = ({ goToGallerySmallPic()}> + onPress={() => handleNewImage()}> diff --git a/src/utils/common.ts b/src/utils/common.ts index ce4ab7d1..95e77f64 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -180,3 +180,20 @@ const _crestIcon = (university: UniversityType) => { return require('../assets/images/bwbadges.png'); } }; + +export const validateImageLink = async (url: string | undefined) => { + if (!url) { + return false; + } + return fetch(url) + .then((res) => { + if (res.status === 200) { + return true; + } else { + return false; + } + }) + .catch((_) => { + return false; + }); +}; diff --git a/src/utils/users.ts b/src/utils/users.ts index 334cb3c0..bc81bbc6 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -1,3 +1,4 @@ +import {Alert} from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import {INTEGRATED_SOCIAL_LIST} from '../constants'; import {isUserBlocked, loadSocialPosts, removeBadgesService} from '../services'; @@ -24,6 +25,8 @@ import { UserType, UniversityBadge, } from './../types/types'; +import ImagePicker from 'react-native-image-crop-picker'; +import {patchEditProfile} from '../services'; const loadData = async (dispatch: AppDispatch, user: UserType) => { await Promise.all([ @@ -240,3 +243,77 @@ export const navigateToProfile = async ( screenType, }); }; + +export const patchProfile = async (title: string, userId: string) => { + let imageSettings = {}; + switch (title) { + case 'Select Header Picture': + imageSettings = { + smartAlbums: [ + 'Favorites', + 'RecentlyAdded', + 'SelfPortraits', + 'Screenshots', + 'UserLibrary', + ], + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: title, + mediaType: 'photo', + }; + break; + case 'Select Profile Picture': + imageSettings = { + smartAlbums: [ + 'Favorites', + 'RecentlyAdded', + 'SelfPortraits', + 'Screenshots', + 'UserLibrary', + ], + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: title, + mediaType: 'photo', + cropperCircleOverlay: true, + }; + break; + } + + return await ImagePicker.openPicker(imageSettings) + .then((picture) => { + if ('path' in picture) { + const request = new FormData(); + switch (title) { + case 'Select Header Picture': + request.append('largeProfilePicture', { + uri: picture.path, + name: 'large_profile_pic.jpg', + type: 'image/jpg', + }); + break; + case 'Select Profile Picture': + request.append('smallProfilePicture', { + uri: picture.path, + name: 'small_profile_pic.jpg', + type: 'image/jpg', + }); + break; + } + + return patchEditProfile(request, userId) + .then((_) => { + return true; + }) + .catch((error) => { + Alert.alert(error); + return false; + }); + } + }) + .catch((_) => { + return false; + }); +}; -- cgit v1.2.3-70-g09d2 From c9a4810a873c6cccb94a1c7761486343258527ea Mon Sep 17 00:00:00 2001 From: brian-tagg <83606050+brian-tagg@users.noreply.github.com> Date: Wed, 12 May 2021 21:32:58 -0700 Subject: Update src/components/profile/Cover.tsx Co-authored-by: Ivan Chen --- src/components/profile/Cover.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index 711eeb46..82231417 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -81,7 +81,7 @@ const Cover: React.FC = ({userXId, screenType}) => { ); } else { return ( - + Date: Thu, 13 May 2021 12:16:49 -0700 Subject: Cleaned up code somewhat --- src/components/profile/Cover.tsx | 36 +++++++++++++-------------- src/components/profile/TaggAvatar.tsx | 2 +- src/utils/users.ts | 47 +++++++++++++++++++---------------- 3 files changed, 44 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx index 82231417..5d5b4234 100644 --- a/src/components/profile/Cover.tsx +++ b/src/components/profile/Cover.tsx @@ -13,7 +13,7 @@ import GreyPurplePlus from '../../assets/icons/grey-purple-plus.svg'; import {useDispatch, useSelector} from 'react-redux'; import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions'; import {RootState} from '../../store/rootreducer'; -import {patchProfile, validateImageLink} from '../../utils'; +import {normalize, patchProfile, validateImageLink} from '../../utils'; interface CoverProps { userXId: string | undefined; @@ -44,7 +44,7 @@ const Cover: React.FC = ({userXId, screenType}) => { const handleNewImage = async () => { setLoading(true); - const result = await patchProfile('Select Header Picture', user.userId); + const result = await patchProfile('header', user.userId); setLoading(true); if (result) { setNeedsUpdate(true); @@ -62,22 +62,20 @@ const Cover: React.FC = ({userXId, screenType}) => { if (!validImage && userXId === undefined && !loading) { return ( - <> - - - handleNewImage()}> - - Add Picture - - - - + + + handleNewImage()}> + + Add Picture + + + ); } else { return ( @@ -108,7 +106,7 @@ const styles = StyleSheet.create({ text: { color: 'white', position: 'absolute', - fontSize: 18, + fontSize: normalize(16), top: 80, right: 20, }, diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx index 1f6bbba6..304b9e3a 100644 --- a/src/components/profile/TaggAvatar.tsx +++ b/src/components/profile/TaggAvatar.tsx @@ -46,7 +46,7 @@ const TaggAvatar: React.FC = ({ const handleNewImage = async () => { setLoading(true); - const result = await patchProfile('Select Profile Picture', user.userId); + const result = await patchProfile('profile', user.userId); if (result) { setNeedsUpdate(true); } else { diff --git a/src/utils/users.ts b/src/utils/users.ts index bc81bbc6..430c843f 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -244,10 +244,19 @@ export const navigateToProfile = async ( }); }; -export const patchProfile = async (title: string, userId: string) => { +export const patchProfile = async ( + title: 'profile' | 'header', + userId: string, +) => { let imageSettings = {}; + let screenTitle: string; + let requestTitle: string; + let fileName: string; switch (title) { - case 'Select Header Picture': + case 'header': + screenTitle = 'Select Header Picture'; + requestTitle = 'largeProfilePicture'; + fileName = 'large_profile_pic.jpg'; imageSettings = { smartAlbums: [ 'Favorites', @@ -259,11 +268,14 @@ export const patchProfile = async (title: string, userId: string) => { width: 580, height: 580, cropping: true, - cropperToolbarTitle: title, + cropperToolbarTitle: screenTitle, mediaType: 'photo', }; break; - case 'Select Profile Picture': + case 'profile': + screenTitle = 'Select Profile Picture'; + requestTitle = 'smallProfilePicture'; + fileName = 'small_profile_pic.jpg'; imageSettings = { smartAlbums: [ 'Favorites', @@ -275,33 +287,26 @@ export const patchProfile = async (title: string, userId: string) => { width: 580, height: 580, cropping: true, - cropperToolbarTitle: title, + cropperToolbarTitle: screenTitle, mediaType: 'photo', cropperCircleOverlay: true, }; break; + default: + screenTitle = ''; + requestTitle = ''; + fileName = ''; } return await ImagePicker.openPicker(imageSettings) .then((picture) => { if ('path' in picture) { const request = new FormData(); - switch (title) { - case 'Select Header Picture': - request.append('largeProfilePicture', { - uri: picture.path, - name: 'large_profile_pic.jpg', - type: 'image/jpg', - }); - break; - case 'Select Profile Picture': - request.append('smallProfilePicture', { - uri: picture.path, - name: 'small_profile_pic.jpg', - type: 'image/jpg', - }); - break; - } + request.append(requestTitle, { + uri: picture.path, + name: fileName, + type: 'image/jpg', + }); return patchEditProfile(request, userId) .then((_) => { -- cgit v1.2.3-70-g09d2