aboutsummaryrefslogtreecommitdiff
path: root/src/components/search/SearchResultCell.tsx
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-03-05 16:38:32 -0500
committerIvan Chen <ivan@tagg.id>2021-03-05 16:38:32 -0500
commit1465df9621fb963ff873485ad927ff79ea547fa0 (patch)
treeaffcb43f37f263f3e0e555dd019dd952b62e1f0a /src/components/search/SearchResultCell.tsx
parent2360e774d94e271d1d9db0d5b92b801b9325535e (diff)
parentb1dee65ee7bb8e120fc38a495f4027905d300650 (diff)
Merge branch 'master' into tma-634-badge-selection-screen
# Conflicts: # src/components/taggs/SocialMediaInfo.tsx
Diffstat (limited to 'src/components/search/SearchResultCell.tsx')
-rw-r--r--src/components/search/SearchResultCell.tsx187
1 files changed, 187 insertions, 0 deletions
diff --git a/src/components/search/SearchResultCell.tsx b/src/components/search/SearchResultCell.tsx
new file mode 100644
index 00000000..705fb5c9
--- /dev/null
+++ b/src/components/search/SearchResultCell.tsx
@@ -0,0 +1,187 @@
+import {useNavigation} from '@react-navigation/native';
+import React, {useEffect, useState} from 'react';
+import {Alert, Image, StyleSheet, Text, View} from 'react-native';
+import {TouchableOpacity} from 'react-native-gesture-handler';
+import {useDispatch, useStore} from 'react-redux';
+import {ERROR_UNABLE_TO_VIEW_PROFILE} from '../../constants/strings';
+import {loadImageFromURL} from '../../services';
+import {RootState} from '../../store/rootReducer';
+import {ProfilePreviewType, ScreenType, UserType} from '../../types';
+import {normalize, SCREEN_WIDTH} from '../../utils';
+import {
+ addUserToRecentlyViewed,
+ checkIfUserIsBlocked,
+ defaultUserProfile,
+ fetchUserX,
+ userXInStore,
+} from '../../utils/users';
+
+interface SearchResults {
+ profileData: ProfilePreviewType;
+ loggedInUser: UserType;
+}
+
+const SearchResultsCell: React.FC<SearchResults> = ({
+ profileData: {
+ id,
+ name,
+ username,
+ first_name,
+ last_name,
+ thumbnail_url,
+ category,
+ },
+ loggedInUser,
+}) => {
+ const [avatar, setAvatar] = useState<string | undefined>(undefined);
+ useEffect(() => {
+ (async () => {
+ if (thumbnail_url !== undefined) {
+ try {
+ const response = await loadImageFromURL(thumbnail_url);
+ if (response) {
+ setAvatar(response);
+ }
+ } catch (error) {
+ console.log('Error while downloading ', error);
+ throw error;
+ }
+ }
+ })();
+ }, [thumbnail_url]);
+
+ const dispatch = useDispatch();
+ const state: RootState = useStore().getState();
+ const navigation = useNavigation();
+ const addToRecentlyStoredAndNavigateToProfile = async () => {
+ try {
+ //If the logged in user is blocked by the user being viewed, do not proceed.
+ const isUserBlocked = await checkIfUserIsBlocked(
+ id,
+ dispatch,
+ loggedInUser,
+ );
+ if (isUserBlocked) {
+ Alert.alert(ERROR_UNABLE_TO_VIEW_PROFILE);
+ return;
+ }
+
+ await addUserToRecentlyViewed({
+ id,
+ first_name,
+ last_name,
+ thumbnail_url,
+ username,
+ });
+
+ const userXId = loggedInUser.username === username ? undefined : id;
+
+ /**
+ * Dispatch an event to Fetch the user details only if we're navigating to
+ * a userX's profile.
+ * If the user is already present in store, do not fetch again.
+ * Finally, Navigate to profile of the user selected.
+ */
+ if (userXId && !userXInStore(state, ScreenType.Search, id)) {
+ await fetchUserX(
+ dispatch,
+ {userId: id, username: username},
+ ScreenType.Search,
+ );
+ }
+
+ navigation.navigate('Profile', {
+ userXId,
+ screenType: ScreenType.Search,
+ });
+ } catch (e) {
+ console.log(e);
+ }
+ };
+
+ const userCell = () => {
+ return (
+ <TouchableOpacity
+ onPress={addToRecentlyStoredAndNavigateToProfile}
+ style={styles.cellContainer}>
+ <Image
+ defaultSource={defaultUserProfile()}
+ source={{uri: avatar}}
+ style={styles.imageContainer}
+ />
+ <View style={[styles.initialTextContainer, styles.multiText]}>
+ <Text style={styles.initialTextStyle}>{`@${username}`}</Text>
+ <Text style={styles.secondaryTextStyle}>
+ {first_name + ' ' + last_name}
+ </Text>
+ </View>
+ </TouchableOpacity>
+ );
+ };
+
+ const searchIcon = () => {
+ return require('../../assets/images/search.png');
+ };
+
+ const universityIcon = () => {
+ return require('../../assets/images/bwbadges.png');
+ };
+
+ const categoryCell = () => {
+ return (
+ <TouchableOpacity style={styles.cellContainer}>
+ <View style={[styles.imageContainer, styles.categoryBackground]}>
+ <Image
+ resizeMode="contain"
+ source={category === 'Brown' ? universityIcon() : searchIcon()}
+ style={styles.categoryImage}
+ />
+ </View>
+ <View style={styles.initialTextContainer}>
+ <Text style={styles.initialTextStyle}>{name}</Text>
+ </View>
+ </TouchableOpacity>
+ );
+ };
+
+ return name === undefined ? userCell() : categoryCell();
+};
+
+const styles = StyleSheet.create({
+ cellContainer: {
+ flexDirection: 'row',
+ marginHorizontal: SCREEN_WIDTH * 0.08,
+ marginBottom: SCREEN_WIDTH * 0.08,
+ },
+ imageContainer: {
+ width: SCREEN_WIDTH * 0.112,
+ height: SCREEN_WIDTH * 0.112,
+ borderRadius: (SCREEN_WIDTH * 0.112) / 2,
+ },
+ categoryBackground: {
+ backgroundColor: 'rgba(196, 196, 196, 0.45)',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ categoryImage: {
+ width: '40%',
+ height: '40%',
+ },
+ initialTextContainer: {
+ marginLeft: SCREEN_WIDTH * 0.08,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ },
+ initialTextStyle: {
+ fontWeight: '500',
+ fontSize: normalize(14),
+ },
+ secondaryTextStyle: {
+ fontWeight: '500',
+ fontSize: normalize(12),
+ color: '#828282',
+ },
+ multiText: {justifyContent: 'space-between'},
+});
+
+export default SearchResultsCell;