aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets/icons/grey-purple-plus.svg5
-rw-r--r--src/assets/icons/purple-plus.svg15
-rw-r--r--src/components/common/BasicButton.tsx12
-rw-r--r--src/components/messages/MessageButton.tsx73
-rw-r--r--src/components/messages/index.ts1
-rw-r--r--src/components/moments/MomentPostContent.tsx4
-rw-r--r--src/components/notifications/Notification.tsx41
-rw-r--r--src/components/profile/Cover.tsx108
-rw-r--r--src/components/profile/ProfileBody.tsx58
-rw-r--r--src/components/profile/TaggAvatar.tsx67
-rw-r--r--src/components/taggs/TaggsBar.tsx14
-rw-r--r--src/utils/common.ts17
-rw-r--r--src/utils/users.ts82
13 files changed, 414 insertions, 83 deletions
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 @@
+<svg width="31" height="31" viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="15.5" cy="15.5" r="15.5" fill="white"/>
+<rect width="2.38462" height="16.6923" rx="1.19231" transform="matrix(-1 0 0 1 16.6934 7.15381)" fill="#8F00FF"/>
+<rect width="2.38462" height="16.6923" rx="1.19231" transform="matrix(0.00550217 0.999985 0.999985 -0.00550217 7.1543 14.4004)" fill="#8F00FF"/>
+</svg>
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 @@
+<svg width="23" height="23" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="11.5" cy="11.5" r="11.25" fill="url(#paint0_linear)" stroke="url(#paint1_linear)" stroke-width="0.5"/>
+<rect width="1.76923" height="12.3846" rx="0.884615" transform="matrix(-1 0 0 1 12.3848 5.30762)" fill="white"/>
+<rect width="1.76923" height="12.3846" rx="0.884615" transform="matrix(0.00550217 0.999985 0.999985 -0.00550217 5.30859 10.6841)" fill="white"/>
+<defs>
+<linearGradient id="paint0_linear" x1="11.5" y1="0" x2="10.9524" y2="30.119" gradientUnits="userSpaceOnUse">
+<stop stop-color="#8F01FF"/>
+<stop offset="1" stop-color="#6EE7E7"/>
+</linearGradient>
+<linearGradient id="paint1_linear" x1="11.5" y1="0" x2="10.9524" y2="32.8571" gradientUnits="userSpaceOnUse">
+<stop stop-color="#8F01FF"/>
+<stop offset="1" stop-color="#6EE7E7"/>
+</linearGradient>
+</defs>
+</svg>
diff --git a/src/components/common/BasicButton.tsx b/src/components/common/BasicButton.tsx
index 1fe29cd9..e2274dbd 100644
--- a/src/components/common/BasicButton.tsx
+++ b/src/components/common/BasicButton.tsx
@@ -1,5 +1,12 @@
import React from 'react';
-import {StyleProp, StyleSheet, Text, View, ViewStyle} from 'react-native';
+import {
+ StyleProp,
+ StyleSheet,
+ Text,
+ TextStyle,
+ View,
+ ViewStyle,
+} from 'react-native';
import {TAGG_LIGHT_BLUE} from '../../constants';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {normalize} from '../../utils';
@@ -8,7 +15,7 @@ interface BasicButtonProps {
title: string;
onPress: () => void;
solid?: boolean;
- externalStyles?: Record<string, StyleProp<ViewStyle>>;
+ externalStyles?: Record<string, StyleProp<ViewStyle | TextStyle>>;
}
const BasicButton: React.FC<BasicButtonProps> = ({
title,
@@ -27,6 +34,7 @@ const BasicButton: React.FC<BasicButtonProps> = ({
<Text
style={[
styles.buttonTitle,
+ externalStyles?.buttonTitle,
solid
? styles.solidButtonTitleColor
: styles.outlineButtonTitleColor,
diff --git a/src/components/messages/MessageButton.tsx b/src/components/messages/MessageButton.tsx
new file mode 100644
index 00000000..5ac42c4c
--- /dev/null
+++ b/src/components/messages/MessageButton.tsx
@@ -0,0 +1,73 @@
+import React from 'react';
+import {Fragment, useContext} from 'react';
+import {useStore} from 'react-redux';
+import {ChatContext} from '../../App';
+import {RootState} from '../../store/rootReducer';
+import {FriendshipStatusType} from '../../types';
+import {createChannel} from '../../utils';
+import {Alert, StyleProp, TextStyle, ViewStyle} from 'react-native';
+import {BasicButton} from '../common';
+import {useNavigation} from '@react-navigation/native';
+import {ERROR_UNABLE_CONNECT_CHAT} from '../../constants/strings';
+
+interface MessageButtonProps {
+ userXId: string;
+ isBlocked: boolean;
+ friendship_status: FriendshipStatusType;
+ friendship_requester_id?: string;
+ solid?: boolean;
+ externalStyles?: Record<string, StyleProp<ViewStyle | TextStyle>>;
+}
+
+const MessageButton: React.FC<MessageButtonProps> = ({
+ userXId,
+ isBlocked,
+ friendship_status,
+ friendship_requester_id,
+ solid,
+ externalStyles,
+}) => {
+ const navigation = useNavigation();
+ const {chatClient, setChannel} = useContext(ChatContext);
+
+ const state: RootState = useStore().getState();
+ const loggedInUserId = state.user.user.userId;
+
+ const canMessage = () => {
+ if (
+ userXId &&
+ !isBlocked &&
+ (friendship_status === 'no_record' ||
+ friendship_status === 'friends' ||
+ (friendship_status === 'requested' &&
+ friendship_requester_id === loggedInUserId))
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ const onPressMessage = async () => {
+ if (chatClient.user && userXId) {
+ const channel = await createChannel(loggedInUserId, userXId, chatClient);
+ setChannel(channel);
+ navigation.navigate('Chat');
+ } else {
+ Alert.alert(ERROR_UNABLE_CONNECT_CHAT);
+ }
+ };
+
+ return canMessage() ? (
+ <BasicButton
+ title={'Message'}
+ onPress={onPressMessage}
+ externalStyles={externalStyles}
+ solid={solid ? solid : false}
+ />
+ ) : (
+ <Fragment />
+ );
+};
+
+export default MessageButton;
diff --git a/src/components/messages/index.ts b/src/components/messages/index.ts
index b19067ca..7270e2e2 100644
--- a/src/components/messages/index.ts
+++ b/src/components/messages/index.ts
@@ -7,3 +7,4 @@ export {default as MessageAvatar} from './MessageAvatar';
export {default as TypingIndicator} from './TypingIndicator';
export {default as MessageFooter} from './MessageFooter';
export {default as DateHeader} from './DateHeader';
+export {default as MessageButton} from './MessageButton';
diff --git a/src/components/moments/MomentPostContent.tsx b/src/components/moments/MomentPostContent.tsx
index 45186ba1..193bf40c 100644
--- a/src/components/moments/MomentPostContent.tsx
+++ b/src/components/moments/MomentPostContent.tsx
@@ -10,6 +10,7 @@ import {
navigateToProfile,
SCREEN_HEIGHT,
SCREEN_WIDTH,
+ normalize,
} from '../../utils';
import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
import {CommentsCount} from '../comments';
@@ -103,6 +104,9 @@ const styles = StyleSheet.create({
marginRight: '5%',
color: '#ffffff',
fontWeight: '500',
+ fontSize: normalize(13),
+ lineHeight: normalize(15.51),
+ letterSpacing: normalize(0.6),
},
});
export default MomentPostContent;
diff --git a/src/components/notifications/Notification.tsx b/src/components/notifications/Notification.tsx
index ae884b42..cb62047a 100644
--- a/src/components/notifications/Notification.tsx
+++ b/src/components/notifications/Notification.tsx
@@ -34,6 +34,7 @@ import {
} from '../../utils';
import {Avatar} from '../common';
import AcceptDeclineButtons from '../common/AcceptDeclineButtons';
+import {MessageButton} from '../messages';
interface NotificationProps {
item: NotificationType;
@@ -61,6 +62,10 @@ const Notification: React.FC<NotificationProps> = (props) => {
const [avatar, setAvatar] = useState<string | undefined>(undefined);
const [momentURI, setMomentURI] = useState<string | undefined>(undefined);
+ const notification_title =
+ notification_type === 'FRD_ACPT'
+ ? `Say Hi to ${first_name}!`
+ : `${first_name} ${last_name}`;
useEffect(() => {
(async () => {
@@ -246,9 +251,7 @@ const Notification: React.FC<NotificationProps> = (props) => {
{/* Text content: Actor name and verbage*/}
<View style={styles.contentContainer}>
<TouchableWithoutFeedback onPress={navigateToProfile}>
- <Text style={styles.actorName}>
- {first_name} {last_name}
- </Text>
+ <Text style={styles.actorName}>{notification_title}</Text>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
style={styles.textContainerStyles}
@@ -273,6 +276,30 @@ const Notification: React.FC<NotificationProps> = (props) => {
/>
</View>
)}
+ {notification_type === 'FRD_ACPT' && (
+ <View style={styles.buttonsContainer}>
+ <MessageButton
+ userXId={id}
+ isBlocked={false}
+ friendship_status={'friends'}
+ externalStyles={{
+ container: {
+ width: normalize(63),
+ height: normalize(21),
+ marginTop: '7%',
+ },
+ buttonTitle: {
+ fontSize: normalize(11),
+ lineHeight: normalize(13.13),
+ letterSpacing: normalize(0.5),
+ fontWeight: '700',
+ textAlign: 'center',
+ },
+ }}
+ solid
+ />
+ </View>
+ )}
{/* Moment Image Preview */}
{(notification_type === 'CMT' ||
notification_type === 'MOM_3+' ||
@@ -306,7 +333,7 @@ const styles = StyleSheet.create({
flex: 1,
alignSelf: 'center',
alignItems: 'center',
- paddingHorizontal: '8%',
+ paddingHorizontal: '6.3%',
},
avatarContainer: {
height: 42,
@@ -348,9 +375,9 @@ const styles = StyleSheet.create({
lineHeight: normalize(13.13),
},
timeStampStyles: {
- fontWeight: '700',
- fontSize: normalize(12),
- lineHeight: normalize(14.32),
+ fontWeight: '500',
+ fontSize: normalize(11),
+ lineHeight: normalize(13.13),
marginHorizontal: 2,
color: '#828282',
textAlignVertical: 'center',
diff --git a/src/components/profile/Cover.tsx b/src/components/profile/Cover.tsx
index 27777b64..5d5b4234 100644
--- a/src/components/profile/Cover.tsx
+++ b/src/components/profile/Cover.tsx
@@ -1,28 +1,93 @@
-import React from 'react';
-import {Image, StyleSheet, View} from 'react-native';
-import {useSelector} from 'react-redux';
+import React, {useState, useEffect} from 'react';
+import {
+ 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 {useDispatch, useSelector} from 'react-redux';
+import {loadUserData, resetHeaderAndProfileImage} from '../../store/actions';
+import {RootState} from '../../store/rootreducer';
+import {normalize, patchProfile, validateImageLink} from '../../utils';
interface CoverProps {
userXId: string | undefined;
screenType: ScreenType;
}
const Cover: React.FC<CoverProps> = ({userXId, screenType}) => {
- const {cover} = useSelector((state: RootState) =>
+ const dispatch = useDispatch();
+ const {cover, user} = useSelector((state: RootState) =>
userXId ? state.userX[screenType][userXId] : state.user,
);
- return (
- <View style={[styles.container]}>
- <Image
- style={styles.image}
- defaultSource={require('../../assets/images/cover-placeholder.png')}
- source={{uri: cover, cache: 'reload'}}
- />
- </View>
- );
+ const [needsUpdate, setNeedsUpdate] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [validImage, setValidImage] = useState<boolean>(true);
+
+ useEffect(() => {
+ checkAvatar(cover);
+ }, []);
+
+ useEffect(() => {
+ if (needsUpdate) {
+ const userId = user.userId;
+ const username = user.username;
+ dispatch(resetHeaderAndProfileImage());
+ dispatch(loadUserData({userId, username}));
+ }
+ }, [dispatch, needsUpdate]);
+
+ const handleNewImage = async () => {
+ setLoading(true);
+ const result = await patchProfile('header', user.userId);
+ setLoading(true);
+ if (result) {
+ setNeedsUpdate(true);
+ } else {
+ setLoading(false);
+ }
+ };
+
+ const checkAvatar = async (url: string | undefined) => {
+ const valid = await validateImageLink(url);
+ if (valid !== validImage) {
+ setValidImage(valid);
+ }
+ };
+
+ if (!validImage && userXId === undefined && !loading) {
+ return (
+ <View style={[styles.container]}>
+ <ImageBackground
+ style={styles.image}
+ defaultSource={require('../../assets/images/cover-placeholder.png')}
+ source={{uri: cover, cache: 'reload'}}>
+ <TouchableOpacity
+ accessible={true}
+ accessibilityLabel="ADD HEADER PICTURE"
+ onPress={() => handleNewImage()}>
+ <GreyPurplePlus style={styles.plus} />
+ <Text style={styles.text}>Add Picture</Text>
+ </TouchableOpacity>
+ </ImageBackground>
+ </View>
+ );
+ } else {
+ return (
+ <View style={styles.container}>
+ <Image
+ style={styles.image}
+ defaultSource={require('../../assets/images/cover-placeholder.png')}
+ source={{uri: cover, cache: 'reload'}}
+ />
+ </View>
+ );
+ }
};
const styles = StyleSheet.create({
@@ -33,5 +98,20 @@ const styles = StyleSheet.create({
width: IMAGE_WIDTH,
height: COVER_HEIGHT,
},
+ plus: {
+ position: 'absolute',
+ top: 75,
+ right: 125,
+ },
+ text: {
+ color: 'white',
+ position: 'absolute',
+ fontSize: normalize(16),
+ top: 80,
+ right: 20,
+ },
+ touch: {
+ flex: 1,
+ },
});
export default Cover;
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index 3d654724..7557de00 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -1,17 +1,7 @@
-import {useNavigation} from '@react-navigation/core';
-import React, {useContext} from 'react';
-import {
- Alert,
- LayoutChangeEvent,
- Linking,
- StyleSheet,
- Text,
- View,
-} from 'react-native';
+import React from 'react';
+import {LayoutChangeEvent, Linking, StyleSheet, Text, View} from 'react-native';
import {useDispatch, useSelector, useStore} from 'react-redux';
-import {ChatContext} from '../../App';
import {TAGG_DARK_BLUE, TOGGLE_BUTTON_TYPE} from '../../constants';
-import {ERROR_UNABLE_CONNECT_CHAT} from '../../constants/strings';
import {
acceptFriendRequest,
declineFriendRequest,
@@ -22,14 +12,14 @@ import {NO_PROFILE} from '../../store/initialStates';
import {RootState} from '../../store/rootReducer';
import {ScreenType} from '../../types';
import {
- createChannel,
getUserAsProfilePreviewType,
normalize,
SCREEN_HEIGHT,
SCREEN_WIDTH,
} from '../../utils';
import {canViewProfile} from '../../utils/users';
-import {BasicButton, FriendsButton} from '../common';
+import {FriendsButton} from '../common';
+import {MessageButton} from '../messages';
import ToggleButton from './ToggleButton';
interface ProfileBodyProps {
@@ -47,7 +37,6 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
screenType,
}) => {
const dispatch = useDispatch();
- const navigation = useNavigation();
const {profile = NO_PROFILE, user} = useSelector((state: RootState) =>
userXId ? state.userX[screenType][userXId] : state.user,
@@ -65,10 +54,7 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
profile,
);
- const {chatClient, setChannel} = useContext(ChatContext);
-
const state: RootState = useStore().getState();
- const loggedInUserId = state.user.user.userId;
const handleAcceptRequest = async () => {
await dispatch(acceptFriendRequest({id, username, first_name, last_name}));
@@ -81,32 +67,6 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
dispatch(updateUserXProfileAllScreens(id, state));
};
- const canMessage = () => {
- if (
- userXId &&
- !isBlocked &&
- (friendship_status === 'no_record' ||
- friendship_status === 'friends' ||
- (friendship_status === 'requested' &&
- friendship_requester_id === loggedInUserId)) &&
- canViewProfile(state, userXId, screenType)
- ) {
- return true;
- } else {
- return false;
- }
- };
-
- const onPressMessage = async () => {
- if (chatClient.user && userXId) {
- const channel = await createChannel(loggedInUserId, userXId, chatClient);
- setChannel(channel);
- navigation.navigate('Chat');
- } else {
- Alert.alert(ERROR_UNABLE_CONNECT_CHAT);
- }
- };
-
return (
<View onLayout={onLayout} style={styles.container}>
<Text style={styles.username}>{`@${username}`}</Text>
@@ -142,10 +102,12 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
onAcceptRequest={handleAcceptRequest}
onRejectRequest={handleDeclineFriendRequest}
/>
- {canMessage() && (
- <BasicButton
- title={'Message'}
- onPress={onPressMessage}
+ {canViewProfile(state, userXId, screenType) && (
+ <MessageButton
+ userXId={userXId}
+ isBlocked={isBlocked}
+ friendship_status={friendship_status}
+ friendship_requester_id={friendship_requester_id}
externalStyles={{
container: {
width: SCREEN_WIDTH * 0.42,
diff --git a/src/components/profile/TaggAvatar.tsx b/src/components/profile/TaggAvatar.tsx
index ea0bdb65..304b9e3a 100644
--- a/src/components/profile/TaggAvatar.tsx
+++ b/src/components/profile/TaggAvatar.tsx
@@ -1,9 +1,12 @@
-import React from 'react';
-import {StyleSheet} from 'react-native';
-import {useSelector} from 'react-redux';
+import React, {useState, useEffect} from 'react';
+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 {patchProfile, validateImageLink} from '../../utils';
const PROFILE_DIM = 100;
@@ -20,8 +23,59 @@ const TaggAvatar: React.FC<TaggAvatarProps> = ({
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<boolean>(true);
+ const {user} = useSelector((state: RootState) =>
+ userXId ? state.userX[screenType][userXId] : state.user,
+ );
+
+ useEffect(() => {
+ checkAvatar(avatar);
+ }, []);
+
+ useEffect(() => {
+ if (needsUpdate) {
+ const userId = user.userId;
+ const username = user.username;
+ dispatch(resetHeaderAndProfileImage());
+ dispatch(loadUserData({userId, username}));
+ }
+ }, [dispatch, needsUpdate]);
- return <Avatar style={[styles.image, style]} uri={avatar} />;
+ const handleNewImage = async () => {
+ setLoading(true);
+ const result = await patchProfile('profile', user.userId);
+ if (result) {
+ setNeedsUpdate(true);
+ } else {
+ setLoading(false);
+ }
+ };
+
+ const checkAvatar = async (url: string | undefined) => {
+ const valid = await validateImageLink(url);
+ if (valid !== validImage) {
+ setValidImage(valid);
+ }
+ };
+
+ if (!validImage && userXId === undefined && !loading) {
+ return (
+ <>
+ <Avatar style={[styles.image, style]} uri={avatar} />
+ <TouchableOpacity
+ accessible={true}
+ accessibilityLabel="ADD PROFILE PICTURE"
+ onPress={() => handleNewImage()}>
+ <PurplePlus style={styles.plus} />
+ </TouchableOpacity>
+ </>
+ );
+ } else {
+ return <Avatar style={[styles.image, style]} uri={avatar} />;
+ }
};
const styles = StyleSheet.create({
@@ -30,6 +84,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/components/taggs/TaggsBar.tsx b/src/components/taggs/TaggsBar.tsx
index 4d567b25..a7e8fc7a 100644
--- a/src/components/taggs/TaggsBar.tsx
+++ b/src/components/taggs/TaggsBar.tsx
@@ -113,13 +113,11 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
loadData();
}
}, [taggsNeedUpdate, user]);
- const paddingTopStylesProgress = useDerivedValue(() =>
- interpolate(
- y.value,
- [PROFILE_CUTOUT_BOTTOM_Y, PROFILE_CUTOUT_BOTTOM_Y + profileBodyHeight],
- [0, 1],
- Extrapolate.CLAMP,
- ),
+ const paddingTopStylesProgress = interpolate(
+ y.value,
+ [PROFILE_CUTOUT_BOTTOM_Y, PROFILE_CUTOUT_BOTTOM_Y + profileBodyHeight],
+ [0, 1],
+ Extrapolate.CLAMP,
);
const shadowOpacityStylesProgress = useDerivedValue(() =>
interpolate(
@@ -134,7 +132,7 @@ const TaggsBar: React.FC<TaggsBarProps> = ({
);
const animatedStyles = useAnimatedStyle(() => ({
shadowOpacity: shadowOpacityStylesProgress.value / 5,
- paddingTop: paddingTopStylesProgress.value * insetTop,
+ paddingTop: paddingTopStylesProgress + insetTop,
}));
return taggs.length > 0 ? (
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..430c843f 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,82 @@ export const navigateToProfile = async (
screenType,
});
};
+
+export const patchProfile = async (
+ title: 'profile' | 'header',
+ userId: string,
+) => {
+ let imageSettings = {};
+ let screenTitle: string;
+ let requestTitle: string;
+ let fileName: string;
+ switch (title) {
+ case 'header':
+ screenTitle = 'Select Header Picture';
+ requestTitle = 'largeProfilePicture';
+ fileName = 'large_profile_pic.jpg';
+ imageSettings = {
+ smartAlbums: [
+ 'Favorites',
+ 'RecentlyAdded',
+ 'SelfPortraits',
+ 'Screenshots',
+ 'UserLibrary',
+ ],
+ width: 580,
+ height: 580,
+ cropping: true,
+ cropperToolbarTitle: screenTitle,
+ mediaType: 'photo',
+ };
+ break;
+ case 'profile':
+ screenTitle = 'Select Profile Picture';
+ requestTitle = 'smallProfilePicture';
+ fileName = 'small_profile_pic.jpg';
+ imageSettings = {
+ smartAlbums: [
+ 'Favorites',
+ 'RecentlyAdded',
+ 'SelfPortraits',
+ 'Screenshots',
+ 'UserLibrary',
+ ],
+ width: 580,
+ height: 580,
+ cropping: true,
+ 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();
+ request.append(requestTitle, {
+ uri: picture.path,
+ name: fileName,
+ type: 'image/jpg',
+ });
+
+ return patchEditProfile(request, userId)
+ .then((_) => {
+ return true;
+ })
+ .catch((error) => {
+ Alert.alert(error);
+ return false;
+ });
+ }
+ })
+ .catch((_) => {
+ return false;
+ });
+};