aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/profile/Content.tsx57
-rw-r--r--src/components/profile/FollowUnfollow.tsx40
-rw-r--r--src/components/profile/ProfileBody.tsx33
-rw-r--r--src/components/profile/ProfilePreview.tsx21
-rw-r--r--src/components/profile/ToggleButton.tsx44
5 files changed, 140 insertions, 55 deletions
diff --git a/src/components/profile/Content.tsx b/src/components/profile/Content.tsx
index 7afc3fbc..13db60a5 100644
--- a/src/components/profile/Content.tsx
+++ b/src/components/profile/Content.tsx
@@ -11,7 +11,7 @@ import {Moment} from '../moments';
import ProfileBody from './ProfileBody';
import ProfileCutout from './ProfileCutout';
import ProfileHeader from './ProfileHeader';
-import {followOrUnfollowUser} from '../../services';
+import {followOrUnfollowUser, blockOrUnblockUser} from '../../services';
interface ContentProps {
y: Animated.Value<number>;
@@ -24,10 +24,12 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
? React.useContext(ProfileContext)
: React.useContext(AuthContext);
- const {logout} = React.useContext(AuthContext);
const {
+ logout,
user: loggedInUser,
updateFollowers: updateLoggedInUserFollowers,
+ blockedUsers,
+ updateBlockedUsers,
} = React.useContext(AuthContext);
/**
@@ -36,7 +38,8 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
const [imagesMap, setImagesMap] = useState<Map<string, MomentType[]>>(
new Map(),
);
- const [followed, setFollowed] = React.useState<boolean>(false);
+ const [isFollowed, setIsFollowed] = React.useState<boolean>(false);
+ const [isBlocked, setIsBlocked] = React.useState<boolean>(false);
/**
* If own profile is being viewed then do not show the follow button.
@@ -81,11 +84,24 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
const isActuallyFollowed = followers.some(
(follower) => follower.username === loggedInUser.username,
);
- if (followed != isActuallyFollowed) {
- setFollowed(isActuallyFollowed);
+ if (isFollowed != isActuallyFollowed) {
+ setIsFollowed(isActuallyFollowed);
}
}, [followers]);
+ useEffect(() => {
+ if (!userId) {
+ return;
+ }
+
+ const isActuallyBlocked = blockedUsers.some(
+ (cur_user) => user.username === cur_user.username,
+ );
+ if (isBlocked != isActuallyBlocked) {
+ setIsBlocked(isActuallyBlocked);
+ }
+ }, [blockedUsers]);
+
/**
* Handles a click on the follow / unfollow button.
* updateFollowers and updateLoggedInUerFollowers to make sure that we update followers list / count for both the users in context.
@@ -100,10 +116,33 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
loggedInUser.userId,
userId,
token,
- followed,
+ isFollowed,
+ );
+ if (isUpdatedSuccessful) {
+ setIsFollowed(!isFollowed);
+ updateFollowers(true);
+ updateLoggedInUserFollowers(true);
+ }
+ };
+
+ /**
+ * Handles a click on the block / unblock button.
+ */
+ const handleBlockUnblock = async () => {
+ const token = await AsyncStorage.getItem('token');
+ if (!token) {
+ logout();
+ return;
+ }
+ const isUpdatedSuccessful = await blockOrUnblockUser(
+ loggedInUser.userId,
+ userId,
+ token,
+ isBlocked,
);
if (isUpdatedSuccessful) {
- setFollowed(!followed);
+ setIsBlocked(!isBlocked);
+ updateBlockedUsers(true);
updateFollowers(true);
updateLoggedInUserFollowers(true);
}
@@ -126,8 +165,10 @@ const Content: React.FC<ContentProps> = ({y, isProfileView}) => {
onLayout,
isProfileView,
isOwnProfile,
- followed,
+ isFollowed,
handleFollowUnfollow,
+ isBlocked,
+ handleBlockUnblock,
}}
/>
<TaggsBar {...{y, profileBodyHeight, isProfileView}} />
diff --git a/src/components/profile/FollowUnfollow.tsx b/src/components/profile/FollowUnfollow.tsx
deleted file mode 100644
index fa224be3..00000000
--- a/src/components/profile/FollowUnfollow.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import * as React from 'react';
-import {StyleSheet, Text} from 'react-native';
-import {TouchableOpacity} from 'react-native-gesture-handler';
-
-type FollowUnfollowProps = {
- followed: boolean;
- handleFollowUnfollow: Function;
-};
-
-const FollowUnfollow: React.FC<FollowUnfollowProps> = ({
- followed,
- handleFollowUnfollow,
-}) => {
- return (
- <TouchableOpacity
- style={styles.button}
- onPress={() => handleFollowUnfollow()}>
- <Text style={styles.text}>{!followed ? 'Follow' : 'Unfollow'}</Text>
- </TouchableOpacity>
- );
-};
-
-const styles = StyleSheet.create({
- button: {
- justifyContent: 'center',
- alignItems: 'center',
- width: 110,
- height: 40,
- borderRadius: 8,
- marginTop: '5%',
- borderColor: '#698dd3',
- backgroundColor: 'white',
- borderWidth: 3,
- },
- text: {
- fontWeight: 'bold',
- color: '#698dd3',
- },
-});
-export default FollowUnfollow;
diff --git a/src/components/profile/ProfileBody.tsx b/src/components/profile/ProfileBody.tsx
index 7091a077..db8c6e0b 100644
--- a/src/components/profile/ProfileBody.tsx
+++ b/src/components/profile/ProfileBody.tsx
@@ -1,21 +1,26 @@
import React from 'react';
import {StyleSheet, View, Text, LayoutChangeEvent} from 'react-native';
+import {TOGGLE_BUTTON_TYPE} from '../../constants';
import {AuthContext, ProfileContext} from '../../routes/';
-import FollowUnfollow from './FollowUnfollow';
+import ToggleButton from './ToggleButton';
interface ProfileBodyProps {
onLayout: (event: LayoutChangeEvent) => void;
isProfileView: boolean;
- followed: boolean;
+ isFollowed: boolean;
+ isBlocked: boolean;
isOwnProfile: boolean;
handleFollowUnfollow: Function;
+ handleBlockUnblock: Function;
}
const ProfileBody: React.FC<ProfileBodyProps> = ({
onLayout,
isProfileView,
- followed,
+ isFollowed,
+ isBlocked,
isOwnProfile,
handleFollowUnfollow,
+ handleBlockUnblock,
}) => {
const {
profile,
@@ -32,10 +37,20 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
<Text style={styles.biography}>{`${biography}`}</Text>
<Text style={styles.website}>{`${website}`}</Text>
{isProfileView && !isOwnProfile ? (
- <FollowUnfollow
- followed={followed}
- handleFollowUnfollow={handleFollowUnfollow}
- />
+ <View style={styles.toggleButtonContainer}>
+ {!isBlocked && (
+ <ToggleButton
+ toggleState={isFollowed}
+ handleToggle={handleFollowUnfollow}
+ buttonType={TOGGLE_BUTTON_TYPE.FOLLOW_UNFOLLOW}
+ />
+ )}
+ <ToggleButton
+ toggleState={isBlocked}
+ handleToggle={handleBlockUnblock}
+ buttonType={TOGGLE_BUTTON_TYPE.BLOCK_UNBLOCK}
+ />
+ </View>
) : (
<></>
)}
@@ -44,6 +59,10 @@ const ProfileBody: React.FC<ProfileBodyProps> = ({
};
const styles = StyleSheet.create({
+ toggleButtonContainer: {
+ flexDirection: 'row',
+ flex: 1,
+ },
container: {
paddingVertical: 5,
paddingHorizontal: 20,
diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx
index 9c953e7d..abc29422 100644
--- a/src/components/profile/ProfilePreview.tsx
+++ b/src/components/profile/ProfilePreview.tsx
@@ -7,12 +7,15 @@ import {
StyleSheet,
ViewProps,
TouchableOpacity,
+ Alert,
} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import RNFetchBlob from 'rn-fetch-blob';
import AsyncStorage from '@react-native-community/async-storage';
import {AVATAR_PHOTO_ENDPOINT} from '../../constants';
import {UserType} from '../../types';
+import {AuthContext} from '../../routes/';
+import {isUserBlocked} from '../../services';
const NO_USER: UserType = {
userId: '',
username: '',
@@ -38,6 +41,7 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({
style,
}) => {
const navigation = useNavigation();
+ const {user: loggedInUser, logout} = React.useContext(AuthContext);
const [avatarURI, setAvatarURI] = useState<string | null>(null);
const [user, setUser] = useState<UserType>(NO_USER);
useEffect(() => {
@@ -80,6 +84,16 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({
* Cache maintains 10 recently searched users, popping off the oldest one if
* needed to make space.
*/
+
+ const checkIfUserIsBlocked = async (userId: string) => {
+ const token = await AsyncStorage.getItem('token');
+ if (!token) {
+ logout();
+ return false;
+ }
+ return await isUserBlocked(userId, loggedInUser.userId, token);
+ };
+
const addToRecentlyStoredAndNavigateToProfile = async () => {
let user: ProfilePreviewType = {
id,
@@ -87,7 +101,14 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({
first_name,
last_name,
};
+
try {
+ //If the logged in user is blocked by the user being viewed, do not proceed.
+ const isUserBlocked = await checkIfUserIsBlocked(user.id);
+ if (isUserBlocked) {
+ Alert.alert('You cannot view this profile');
+ return;
+ }
if (!isComment) {
const jsonValue = await AsyncStorage.getItem(
'@recently_searched_users',
diff --git a/src/components/profile/ToggleButton.tsx b/src/components/profile/ToggleButton.tsx
new file mode 100644
index 00000000..ff14cdde
--- /dev/null
+++ b/src/components/profile/ToggleButton.tsx
@@ -0,0 +1,44 @@
+import * as React from 'react';
+import {StyleSheet, Text} from 'react-native';
+import {TouchableOpacity} from 'react-native-gesture-handler';
+import {getToggleButtonText, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+
+type ToggleButtonProps = {
+ toggleState: boolean;
+ handleToggle: Function;
+ buttonType: string;
+};
+
+const ToggleButton: React.FC<ToggleButtonProps> = ({
+ toggleState,
+ handleToggle,
+ buttonType,
+}) => {
+ return (
+ <TouchableOpacity style={styles.button} onPress={() => handleToggle()}>
+ <Text style={styles.text}>
+ {getToggleButtonText(buttonType, toggleState)}
+ </Text>
+ </TouchableOpacity>
+ );
+};
+
+const styles = StyleSheet.create({
+ button: {
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: SCREEN_WIDTH * 0.25,
+ height: SCREEN_WIDTH * 0.1,
+ borderRadius: 8,
+ marginTop: '3%',
+ borderColor: '#698dd3',
+ backgroundColor: 'white',
+ borderWidth: 3,
+ marginHorizontal: '1%',
+ },
+ text: {
+ fontWeight: 'bold',
+ color: '#698dd3',
+ },
+});
+export default ToggleButton;