aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorIvan Chen <ivan@thetaggid.com>2021-02-05 16:50:13 -0500
committerGitHub <noreply@github.com>2021-02-05 16:50:13 -0500
commit55914efe03da970f03970a2a9fa85196fce41b75 (patch)
treed475e92b463926fc4430b02fb80350aa50aefa1f /src/components
parentf591dd437a1273d99709aa6a3637a3a2922e6f4d (diff)
parent212eae20eb33d224525c52cea600b86fb2fd1126 (diff)
Merge pull request #212 from shravyaramesh/tma590-friendslist-buttons
[TMA-590] New Friends Screen
Diffstat (limited to 'src/components')
-rw-r--r--src/components/common/FriendsButton.tsx111
-rw-r--r--src/components/common/index.ts1
-rw-r--r--src/components/moments/IndividualMomentTitleBar.tsx7
-rw-r--r--src/components/profile/Content.tsx28
-rw-r--r--src/components/profile/Friends.tsx133
-rw-r--r--src/components/profile/ProfileBody.tsx47
-rw-r--r--src/components/profile/ProfilePreview.tsx32
7 files changed, 256 insertions, 103 deletions
diff --git a/src/components/common/FriendsButton.tsx b/src/components/common/FriendsButton.tsx
new file mode 100644
index 00000000..6ef23a96
--- /dev/null
+++ b/src/components/common/FriendsButton.tsx
@@ -0,0 +1,111 @@
+import React from 'react';
+import {StyleSheet} from 'react-native';
+import {Button} from 'react-native-elements';
+import {ScreenType} from '../../types';
+import {TAGG_LIGHT_BLUE} from '../../constants';
+import {handleFriendUnfriend, SCREEN_WIDTH} from '../../utils';
+import {NO_PROFILE, NO_USER} from '../../store/initialStates';
+import {useDispatch, useSelector, useStore} from 'react-redux';
+import {RootState} from '../../store/rootReducer';
+
+interface ProfileBodyProps {
+ userXId: string | undefined;
+ screenType: ScreenType;
+}
+const FriendsButton: React.FC<ProfileBodyProps> = ({userXId, screenType}) => {
+ const dispatch = useDispatch();
+
+ const {user = NO_USER, profile = NO_PROFILE} = userXId
+ ? useSelector((state: RootState) => state.userX[screenType][userXId])
+ : useSelector((state: RootState) => state.user);
+
+ const {user: loggedInUser = NO_USER} = useSelector(
+ (state: RootState) => state.user,
+ );
+
+ const state = useStore().getState();
+
+ const {friendship_status} = profile;
+
+ return (
+ <>
+ {friendship_status === 'no_record' && (
+ <Button
+ title={'Add Friend'}
+ buttonStyle={styles.button}
+ titleStyle={styles.buttonTitle}
+ onPress={() =>
+ handleFriendUnfriend(
+ screenType,
+ user,
+ profile,
+ dispatch,
+ state,
+ loggedInUser,
+ )
+ } // requested, requested status
+ />
+ )}
+ {friendship_status === 'friends' && (
+ <Button
+ title={'Unfriend'}
+ buttonStyle={styles.requestedButton}
+ titleStyle={styles.requestedButtonTitle}
+ onPress={() =>
+ handleFriendUnfriend(
+ screenType,
+ user,
+ profile,
+ dispatch,
+ state,
+ loggedInUser,
+ )
+ } // unfriend, no record status
+ />
+ )}
+ </>
+ );
+};
+
+const styles = StyleSheet.create({
+ requestedButton: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: SCREEN_WIDTH * 0.4,
+ height: SCREEN_WIDTH * 0.075,
+ borderColor: TAGG_LIGHT_BLUE,
+ borderWidth: 2,
+ borderRadius: 0,
+ marginRight: '2%',
+ marginLeft: '1%',
+ padding: 0,
+ backgroundColor: 'transparent',
+ },
+ requestedButtonTitle: {
+ color: TAGG_LIGHT_BLUE,
+ padding: 0,
+ fontSize: 14,
+ fontWeight: '700',
+ },
+ buttonTitle: {
+ color: 'white',
+ padding: 0,
+ fontSize: 14,
+ fontWeight: '700',
+ },
+ button: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: SCREEN_WIDTH * 0.4,
+ height: SCREEN_WIDTH * 0.075,
+ padding: 0,
+ borderWidth: 2,
+ borderColor: TAGG_LIGHT_BLUE,
+ borderRadius: 0,
+ marginRight: '2%',
+ marginLeft: '1%',
+ backgroundColor: TAGG_LIGHT_BLUE,
+ },
+});
+
+export default FriendsButton;
diff --git a/src/components/common/index.ts b/src/components/common/index.ts
index a5718c1e..95854ba8 100644
--- a/src/components/common/index.ts
+++ b/src/components/common/index.ts
@@ -20,4 +20,5 @@ export {default as GenericMoreInfoDrawer} from './GenericMoreInfoDrawer';
export {default as TaggPopUp} from './TaggPopup';
export {default as TaggPrompt} from './TaggPrompt';
export {default as AcceptDeclineButtons} from './AcceptDeclineButtons';
+export {default as FriendsButton} from './FriendsButton';
export {default as TaggSquareButton} from './TaggSquareButton';
diff --git a/src/components/moments/IndividualMomentTitleBar.tsx b/src/components/moments/IndividualMomentTitleBar.tsx
index bd5b307f..6cdfe0e8 100644
--- a/src/components/moments/IndividualMomentTitleBar.tsx
+++ b/src/components/moments/IndividualMomentTitleBar.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import {TouchableOpacity} from 'react-native';
import {Text, View, StyleSheet, ViewProps} from 'react-native';
+import {normalize} from '../../utils';
import CloseIcon from '../../assets/ionicons/close-outline.svg';
interface IndividualMomentTitleBarProps extends ViewProps {
@@ -30,9 +31,11 @@ const styles = StyleSheet.create({
height: '5%',
},
header: {
- fontSize: 20,
- fontWeight: 'bold',
color: 'white',
+ fontSize: normalize(18),
+ fontWeight: '700',
+ lineHeight: normalize(21.48),
+ letterSpacing: normalize(1.3),
},
closeButton: {
position: 'absolute',
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index a35a5820..28000dd7 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -25,11 +25,9 @@ import {
import {
blockUnblockUser,
deleteUserMomentsForCategory,
- friendUnfriendUser,
loadFriendsData,
updateMomentCategories,
updateUserXFriends,
- updateUserXProfileAllScreens,
} from '../../store/actions';
import {
EMPTY_MOMENTS_LIST,
@@ -216,31 +214,6 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
}
}, [blockedUsers, user]);
- // Handles click on friend/requested/unfriend button
- /*
- * When user logged in clicks on the friend button:
- A request is sent.
- Which means you have to update the status of their friendshpi to requested
- When the status is changed to requested the button should change to requested.
- When the button is changed to requested and thr user clicks on it,
- a request much go to the backend to delete that request
- When that succeeds, their friendship must be updated to no-record again;
- When the button is changed to no_record, the add friends button should be displayed again
- */
- const handleFriendUnfriend = async () => {
- const {friendship_status} = profile;
- await dispatch(
- friendUnfriendUser(
- loggedInUser,
- getUserAsProfilePreviewType(user, profile),
- friendship_status,
- screenType,
- ),
- );
- await dispatch(updateUserXFriends(user.userId, state));
- dispatch(updateUserXProfileAllScreens(user.userId, state));
- };
-
/**
* Handles a click on the block / unblock button.
* loadFriends updates friends list for the logged in user
@@ -332,7 +305,6 @@ const Content: React.FC<ContentProps> = ({y, userXId, screenType}) => {
userXId,
screenType,
isFriend,
- handleFriendUnfriend,
handleBlockUnblock,
isBlocked,
}}
diff --git a/src/components/profile/Friends.tsx b/src/components/profile/Friends.tsx
index 23ce28fe..9b9e5302 100644
--- a/src/components/profile/Friends.tsx
+++ b/src/components/profile/Friends.tsx
@@ -1,64 +1,123 @@
import React from 'react';
-import {View, StyleSheet, Text} from 'react-native';
+import {View, StyleSheet, ScrollView, Text} from 'react-native';
import {ProfilePreviewType, ScreenType} from '../../types';
import {ProfilePreview} from '..';
-import {useNavigation} from '@react-navigation/native';
import {Button} from 'react-native-elements';
+import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {TAGG_LIGHT_BLUE} from '../../constants';
+import {RootState} from '../../store/rootReducer';
+import {useDispatch, useStore} from 'react-redux';
+import {handleUnfriend} from '../../utils/friends';
+import {NO_USER} from '../../store/initialStates';
+import {TouchableOpacity} from 'react-native-gesture-handler';
interface FriendsProps {
result: Array<ProfilePreviewType>;
screenType: ScreenType;
+ userId: string;
}
-const Friends: React.FC<FriendsProps> = ({result, screenType}) => {
- const navigation = useNavigation();
+const Friends: React.FC<FriendsProps> = ({result, screenType, userId}) => {
+ const state: RootState = useStore().getState();
+ const dispatch = useDispatch();
+
+ const {user: loggedInUser = NO_USER} = state;
+
return (
<>
- <View style={styles.header}>
- <Button
- title="X"
- buttonStyle={styles.button}
- titleStyle={styles.buttonText}
- onPress={() => {
- navigation.pop();
- }}
- />
- <Text style={styles.title}>Friends</Text>
+ <View style={styles.subheader}>
+ <Text style={styles.subheaderText}>Friends</Text>
</View>
- {result.map((profilePreview) => (
- <ProfilePreview
- style={styles.friend}
- key={profilePreview.id}
- {...{profilePreview}}
- previewType={'Friend'}
- screenType={screenType}
- />
- ))}
+ <ScrollView
+ keyboardShouldPersistTaps={'always'}
+ stickyHeaderIndices={[4]}
+ style={styles.scrollView}
+ contentContainerStyle={styles.scrollViewContent}
+ showsVerticalScrollIndicator={false}>
+ {result.map((profilePreview) => (
+ <View key={profilePreview.id} style={styles.container}>
+ <View style={styles.friend}>
+ <ProfilePreview
+ {...{profilePreview}}
+ previewType={'Friend'}
+ screenType={screenType}
+ />
+ </View>
+ {loggedInUser.userId === userId && (
+ <TouchableOpacity
+ style={styles.button}
+ onPress={() =>
+ handleUnfriend(screenType, profilePreview, dispatch, state)
+ }>
+ <Text style={styles.buttonTitle}>Unfriend</Text>
+ </TouchableOpacity>
+ )}
+ </View>
+ ))}
+ </ScrollView>
</>
);
};
const styles = StyleSheet.create({
+ scrollView: {
+ flexDirection: 'column',
+ alignSelf: 'center',
+ width: SCREEN_WIDTH * 0.85,
+ height: SCREEN_HEIGHT,
+ },
+ scrollViewContent: {
+ alignSelf: 'center',
+ paddingBottom: SCREEN_HEIGHT / 15,
+ width: SCREEN_WIDTH * 0.85,
+ height: SCREEN_HEIGHT * 0.75,
+ marginTop: '1%',
+ },
header: {flexDirection: 'row'},
- friend: {
- marginVertical: 10,
+ subheader: {
+ alignSelf: 'center',
+ width: SCREEN_WIDTH * 0.85,
+ marginVertical: '3%',
+ },
+ subheaderText: {
+ color: '#828282',
+ fontSize: normalize(12),
+ fontWeight: '600',
+ lineHeight: normalize(14.32),
},
- title: {
- position: 'relative',
- fontSize: 17,
- fontWeight: 'bold',
- paddingBottom: 10,
- paddingTop: 10,
- flexGrow: 1,
- paddingLeft: '26%',
+ container: {
+ alignSelf: 'center',
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ width: '100%',
+ height: normalize(42),
+ alignItems: 'center',
+ marginBottom: '5%',
+ },
+ friend: {
+ alignSelf: 'center',
+ height: '100%',
},
button: {
+ alignSelf: 'center',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: '100%',
+ height: '55%',
+ borderColor: TAGG_LIGHT_BLUE,
+ borderWidth: 2,
+ borderRadius: 2,
+ padding: 0,
backgroundColor: 'transparent',
},
- buttonText: {
- color: 'black',
- fontSize: 18,
- fontWeight: '400',
+ buttonTitle: {
+ color: TAGG_LIGHT_BLUE,
+ padding: 0,
+ fontSize: normalize(11),
+ fontWeight: '700',
+ lineHeight: normalize(13.13),
+ letterSpacing: normalize(0.6),
+ paddingHorizontal: '3.8%',
},
});
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index f2d75519..106b20a7 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -9,14 +9,17 @@ import {
import ToggleButton from './ToggleButton';
import {RootState} from '../../store/rootReducer';
import {useDispatch, useSelector, useStore} from 'react-redux';
-import {FriendshipStatusType, ScreenType} from '../../types';
-import {NO_PROFILE} from '../../store/initialStates';
-import {getUserAsProfilePreviewType, SCREEN_WIDTH} from '../../utils';
-import {AcceptDeclineButtons} from '../common';
+import {ScreenType} from '../../types';
+import {NO_PROFILE, NO_USER} from '../../store/initialStates';
+import {
+ getUserAsProfilePreviewType,
+ handleFriendUnfriend,
+ SCREEN_WIDTH,
+} from '../../utils';
+import {AcceptDeclineButtons, FriendsButton} from '../common';
import {
acceptFriendRequest,
declineFriendRequest,
- loadUserNotifications,
updateUserXFriends,
updateUserXProfileAllScreens,
} from '../../store/actions';
@@ -24,7 +27,6 @@ import {
interface ProfileBodyProps {
onLayout: (event: LayoutChangeEvent) => void;
isBlocked: boolean;
- handleFriendUnfriend: () => void;
handleBlockUnblock: () => void;
userXId: string | undefined;
screenType: ScreenType;
@@ -32,7 +34,6 @@ interface ProfileBodyProps {
const ProfileBody: React.FC<ProfileBodyProps> = ({
onLayout,
isBlocked,
- handleFriendUnfriend,
handleBlockUnblock,
userXId,
screenType,
@@ -41,6 +42,10 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
? useSelector((state: RootState) => state.userX[screenType][userXId])
: useSelector((state: RootState) => state.user);
+ const {user: loggedInUser = NO_USER} = useSelector(
+ (state: RootState) => state.user,
+ );
+
const {
biography,
website,
@@ -94,29 +99,23 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
)}
{userXId && !isBlocked && (
<View style={styles.buttonsContainer}>
- {friendship_status === 'no_record' && (
- <Button
- title={'Add Friend'}
- buttonStyle={styles.button}
- titleStyle={styles.buttonTitle}
- onPress={handleFriendUnfriend} // requested, requested status
- />
- )}
- {friendship_status === 'friends' && (
- <Button
- title={'Unfriend'}
- buttonStyle={styles.requestedButton}
- titleStyle={styles.requestedButtonTitle}
- onPress={handleFriendUnfriend} // unfriend, no record status
- />
- )}
+ <FriendsButton userXId={userXId} screenType={screenType} />
{(friendship_status === 'requested' &&
friendship_requester_id !== userXId && (
<Button
title={'Requested'}
buttonStyle={styles.requestedButton}
titleStyle={styles.requestedButtonTitle}
- onPress={handleFriendUnfriend} // delete request, no record status
+ onPress={() =>
+ handleFriendUnfriend(
+ screenType,
+ user,
+ profile,
+ dispatch,
+ state,
+ loggedInUser,
+ )
+ } // delete request, no record status
/>
)) ||
(friendship_status === 'requested' &&
diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx
index 38defb8d..fad3ec09 100644
--- a/src/components/profile/ProfilePreview.tsx
+++ b/src/components/profile/ProfilePreview.tsx
@@ -15,7 +15,13 @@ import {ERROR_UNABLE_TO_VIEW_PROFILE} from '../../constants/strings';
import {loadImageFromURL} from '../../services';
import {RootState} from '../../store/rootreducer';
import {PreviewType, ProfilePreviewType, ScreenType} from '../../types';
-import {checkIfUserIsBlocked, fetchUserX, userXInStore} from '../../utils';
+import {
+ checkIfUserIsBlocked,
+ fetchUserX,
+ normalize,
+ SCREEN_WIDTH,
+ userXInStore,
+} from '../../utils';
/**
* This component returns user's profile picture friended by username as a touchable component.
@@ -308,29 +314,31 @@ const styles = StyleSheet.create({
friendContainer: {
flexDirection: 'row',
alignItems: 'center',
- marginVertical: 10,
+ justifyContent: 'flex-start',
+ width: SCREEN_WIDTH * 0.6,
},
friendAvatar: {
- height: 42,
- width: 42,
+ height: normalize(42),
+ width: normalize(42),
marginRight: 15,
- borderRadius: 20,
+ borderRadius: 50,
},
friendNameContainer: {
+ height: '100%',
justifyContent: 'space-evenly',
alignSelf: 'stretch',
},
friendUsername: {
- fontSize: 14,
- fontWeight: '700',
- color: '#3C3C3C',
- letterSpacing: 0.6,
+ fontSize: normalize(14),
+ fontWeight: '500',
+ color: '#000',
+ letterSpacing: normalize(0.1),
},
friendName: {
- fontSize: 12,
- fontWeight: '500',
+ fontSize: normalize(12),
+ fontWeight: '400',
color: '#6C6C6C',
- letterSpacing: 0.5,
+ letterSpacing: normalize(0.1),
},
});