aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/screens/suggestedPeople/SuggestedPeopleScreen.tsx115
-rw-r--r--src/services/UserFriendsService.ts28
-rw-r--r--src/store/actions/userFriends.ts65
-rw-r--r--src/types/types.ts6
-rw-r--r--src/utils/friends.ts13
5 files changed, 195 insertions, 32 deletions
diff --git a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
index 195604a3..79b9abc8 100644
--- a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
+++ b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
@@ -1,6 +1,6 @@
import AsyncStorage from '@react-native-community/async-storage';
import {useFocusEffect, useNavigation} from '@react-navigation/native';
-import React, {useCallback, useEffect, useState} from 'react';
+import React, {Fragment, useCallback, useEffect, useState} from 'react';
import {
FlatList,
ListRenderItemInfo,
@@ -19,9 +19,11 @@ import {MutualFriends} from '../../components/suggestedPeople';
import {SP_PAGE_SIZE} from '../../constants';
import SuggestedPeopleOnboardingStackScreen from '../../routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen';
import {getSuggestedPeople} from '../../services/SuggestedPeopleService';
-import {resetScreenType} from '../../store/actions';
+import {cancelFriendRequest, resetScreenType} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {
+ FriendshipStatusType,
+ FriendshipType,
ProfilePreviewType,
ScreenType,
SuggestedPeopleDataType,
@@ -29,6 +31,7 @@ import {
import {
fetchUserX,
getUserAsProfilePreviewType,
+ handleAddFriend,
normalize,
SCREEN_HEIGHT,
SCREEN_WIDTH,
@@ -53,6 +56,7 @@ const SuggestedPeopleScreen: React.FC = () => {
(state: RootState) => state.user.user,
);
const [people, setPeople] = useState<SuggestedPeopleDataType[]>([]);
+ const [displayedUser, setDisplayedUser] = useState<SuggestedPeopleDataType>();
const [page, setPage] = useState(0);
const [refreshing, setRefreshing] = useState(false);
const [hideStatusBar, setHideStatusBar] = useState(false);
@@ -154,12 +158,79 @@ const SuggestedPeopleScreen: React.FC = () => {
// [],
// );
+ const updateDisplayedUser = async (
+ suggested: SuggestedPeopleDataType,
+ status: FriendshipStatusType,
+ requester_id: string,
+ ) => {
+ const localDisplayedUser: SuggestedPeopleDataType = {
+ ...displayedUser,
+ friendship: {status, requester_id},
+ };
+ setDisplayedUser(localDisplayedUser);
+
+ people.map((item) => {
+ if (item.user.id === suggested.user.id) {
+ item.friendship.status = status;
+ item.friendship.requester_id = requester_id;
+ }
+ });
+ };
+
+ const onAddFriend = async (suggested: SuggestedPeopleDataType) => {
+ handleAddFriend(screenType, suggested.user, dispatch, state);
+ updateDisplayedUser(suggested, 'requested', loggedInUserId);
+ };
+
+ const onCancelRequest = (suggested: SuggestedPeopleDataType) => {
+ dispatch(cancelFriendRequest(suggested.user.id));
+ updateDisplayedUser(suggested, 'no_record', '');
+ };
+
+ const displayButton = (suggested: SuggestedPeopleDataType) => {
+ setDisplayedUser(suggested);
+ const friendship: FriendshipType = suggested.friendship;
+ switch (friendship.status) {
+ case 'friends':
+ return <Fragment />;
+ case 'requested':
+ if (friendship.requester_id === loggedInUserId) {
+ return (
+ <TouchableOpacity
+ style={styles.addButton}
+ onPress={() => onCancelRequest(suggested)}
+ disabled={false}>
+ <Text style={styles.addButtonTitle}>{'Requested'}</Text>
+ </TouchableOpacity>
+ );
+ } else {
+ return (
+ <TouchableOpacity style={styles.addButton} disabled={true}>
+ <Text style={styles.addButtonTitle}>{'Pending'}</Text>
+ </TouchableOpacity>
+ );
+ }
+ case 'no_record':
+ return (
+ <TouchableOpacity
+ style={styles.addButton}
+ onPress={() => onAddFriend(suggested)}
+ disabled={false}>
+ <Text style={styles.addButtonTitle}>{'Add Friend'}</Text>
+ </TouchableOpacity>
+ );
+ default:
+ return <Fragment />;
+ }
+ };
+
const SPBody = ({
item,
}: {
item: ListRenderItemInfo<SuggestedPeopleDataType>;
}) => {
const data = item.item;
+ setDisplayedUser(item.item);
const firstItem = item.index === 0;
return (
<>
@@ -186,15 +257,8 @@ const SuggestedPeopleScreen: React.FC = () => {
<Text style={styles.firstName}>{data.user.first_name}</Text>
<Text style={styles.username}>@{data.user.username}</Text>
</TouchableOpacity>
- {/* TODO: Finish me ?! */}
- {/* <TouchableOpacity
- activeOpacity={0.5}
- // TODO: Call function to Add Friend
- onPress={() => console.log('Call add friend function')}>
- <View style={styles.addButton}>
- <Text style={styles.addButtonTitle}>{'Add Friend'}</Text>
- </View>
- </TouchableOpacity> */}
+ {/* Friendship Button */}
+ {displayButton(data)}
</View>
</View>
<TaggsBar
@@ -320,5 +384,34 @@ const styles = StyleSheet.create({
marginBottom: '5%',
},
body: {},
+
+ button: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: SCREEN_WIDTH * 0.4,
+ aspectRatio: 154 / 33,
+ borderWidth: 2,
+ borderColor: '#fff',
+ borderRadius: 3,
+ marginRight: '2%',
+ marginLeft: '1%',
+ },
+ transparentBG: {
+ backgroundColor: 'transparent',
+ },
+ lightBlueBG: {
+ backgroundColor: '#fff',
+ },
+ label: {
+ fontSize: normalize(15),
+ fontWeight: '700',
+ letterSpacing: 1,
+ },
+ blueLabel: {
+ color: '#fff',
+ },
+ whiteLabel: {
+ color: 'white',
+ },
});
export default SuggestedPeopleScreen;
diff --git a/src/services/UserFriendsService.ts b/src/services/UserFriendsService.ts
index eff18f16..a0bf7ac7 100644
--- a/src/services/UserFriendsService.ts
+++ b/src/services/UserFriendsService.ts
@@ -86,18 +86,16 @@ export const friendOrUnfriendUser = async (
}
};
-export const declineFriendRequestService = async (
- user_id: string,
- token: string | null,
-) => {
+export const addFriendService = async (friend: string, token: string) => {
try {
- const response = await fetch(FRIENDS_ENDPOINT + `${user_id}/`, {
- method: 'DELETE',
+ const response = await fetch(FRIENDS_ENDPOINT, {
+ method: 'POST',
headers: {
+ 'Content-Type': 'application/json',
Authorization: 'Token ' + token,
},
body: JSON.stringify({
- reason: 'declined',
+ requested: friend,
}),
});
const status = response.status;
@@ -105,12 +103,18 @@ export const declineFriendRequestService = async (
return true;
} else {
console.log(await response.json());
- Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH);
+ Alert.alert(
+ 'Something went wrong! 😭',
+ "Would you believe me if I told you that I don't know what happened?",
+ );
return false;
}
} catch (error) {
console.log(error);
- Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH);
+ Alert.alert(
+ 'Something went wrong! 😭',
+ "Would you believe me if I told you that I don't know what happened?",
+ );
return false;
}
};
@@ -148,18 +152,20 @@ export const acceptFriendRequestService = async (
}
};
-export const unfriendService = async (
+export const deleteFriendshipService = async (
user_id: string,
+ reason: 'declined' | 'cancelled' | 'unfriended',
token: string | null,
) => {
try {
+ console.log('deleteFriendshipService!');
const response = await fetch(FRIENDS_ENDPOINT + `${user_id}/`, {
method: 'DELETE',
headers: {
Authorization: 'Token ' + token,
},
body: JSON.stringify({
- reason: 'unfriended',
+ reason,
}),
});
const status = response.status;
diff --git a/src/store/actions/userFriends.ts b/src/store/actions/userFriends.ts
index 763f2575..054b7fbf 100644
--- a/src/store/actions/userFriends.ts
+++ b/src/store/actions/userFriends.ts
@@ -8,10 +8,10 @@ import {
} from '../../types/types';
import {
acceptFriendRequestService,
- declineFriendRequestService,
+ addFriendService,
friendOrUnfriendUser,
loadFriends,
- unfriendService,
+ deleteFriendshipService,
} from '../../services';
import {Action, ThunkAction} from '@reduxjs/toolkit';
import {
@@ -88,6 +88,34 @@ export const friendUnfriendUser = (
}
};
+export const addFriend = (
+ friend: ProfilePreviewType, // userX's profile preview
+ screenType: ScreenType, //screentype from content
+): ThunkAction<
+ Promise<boolean | undefined>,
+ RootState,
+ unknown,
+ Action<string>
+> => async (dispatch) => {
+ try {
+ const token = await getTokenOrLogout(dispatch);
+ const success = await addFriendService(friend.id, token);
+ if (success) {
+ dispatch({
+ type: userXFriendshipEdited.type,
+ payload: {
+ userId: friend.id,
+ screenType,
+ data: 'requested',
+ },
+ });
+ return true;
+ }
+ } catch (error) {
+ console.log(error);
+ }
+};
+
export const unfriendUser = (
friend: ProfilePreviewType, // userX's profile preview
screenType: ScreenType, //screentype from content
@@ -97,7 +125,8 @@ export const unfriendUser = (
try {
const token = await getTokenOrLogout(dispatch);
// Calls method to send post or delete request
- const success = await unfriendService(friend.id, token);
+ const reason = 'unfriended';
+ const success = await deleteFriendshipService(friend.id, reason, token);
if (success) {
let data = 'no_record';
await dispatch({
@@ -150,16 +179,32 @@ export const declineFriendRequest = (
) => {
try {
const token = await getTokenOrLogout(dispatch);
- const success = await declineFriendRequestService(user_id, token);
+ const reason = 'declined';
+ const success = await deleteFriendshipService(user_id, reason, token);
if (success) {
// Get profile of requester
console.log('declined request: ', success);
- // dispatch({
- // type: updateFriends.type,
- // payload: {
- // data: requester, // has to be a requester not id
- // },
- // });
+ } else {
+ console.log('Unsuccessful call');
+ }
+ } catch (error) {
+ console.log(error);
+ }
+};
+
+export const cancelFriendRequest = (
+ user_id: string,
+): ThunkAction<Promise<void>, RootState, unknown, Action<string>> => async (
+ dispatch,
+) => {
+ try {
+ console.log('cancelFriendRequest!');
+ const token = await getTokenOrLogout(dispatch);
+ const reason = 'cancelled';
+ const success = await deleteFriendshipService(user_id, reason, token);
+ if (success) {
+ // Get profile of requester
+ console.log('cancelled request: ', success);
} else {
console.log('Unsuccessful call');
}
diff --git a/src/types/types.ts b/src/types/types.ts
index 97471171..3ad787f2 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -237,4 +237,10 @@ export type SuggestedPeopleDataType = {
badges: UniversityBadge[];
social_links: string[];
suggested_people_url: string;
+ friendship: FriendshipType;
+};
+
+export type FriendshipType = {
+ status: FriendshipStatusType;
+ requester_id: string;
};
diff --git a/src/utils/friends.ts b/src/utils/friends.ts
index ba15e087..3398c123 100644
--- a/src/utils/friends.ts
+++ b/src/utils/friends.ts
@@ -4,6 +4,7 @@ import {RootState} from '../store/rootReducer';
import {ProfilePreviewType, ProfileType, ScreenType, UserType} from '../types';
import {AppDispatch} from '../store/configureStore';
import {
+ addFriend,
friendUnfriendUser,
unfriendUser,
updateUserXFriends,
@@ -52,3 +53,15 @@ export const handleUnfriend = async (
await dispatch(updateUserXFriends(friend.id, state));
dispatch(updateUserXProfileAllScreens(friend.id, state));
};
+
+export const handleAddFriend = async (
+ screenType: ScreenType,
+ friend: ProfilePreviewType,
+ dispatch: AppDispatch,
+ state: RootState,
+) => {
+ const success = await dispatch(addFriend(friend, screenType));
+ await dispatch(updateUserXFriends(friend.id, state));
+ await dispatch(updateUserXProfileAllScreens(friend.id, state));
+ return success;
+};