diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/screens/suggestedPeople/SuggestedPeopleScreen.tsx | 115 | ||||
-rw-r--r-- | src/services/UserFriendsService.ts | 28 | ||||
-rw-r--r-- | src/store/actions/userFriends.ts | 65 | ||||
-rw-r--r-- | src/types/types.ts | 6 | ||||
-rw-r--r-- | src/utils/friends.ts | 13 |
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; +}; |