diff options
author | Ivan Chen <ivan@tagg.id> | 2021-03-05 16:38:32 -0500 |
---|---|---|
committer | Ivan Chen <ivan@tagg.id> | 2021-03-05 16:38:32 -0500 |
commit | 1465df9621fb963ff873485ad927ff79ea547fa0 (patch) | |
tree | affcb43f37f263f3e0e555dd019dd952b62e1f0a /src/components/search/SearchResultCell.tsx | |
parent | 2360e774d94e271d1d9db0d5b92b801b9325535e (diff) | |
parent | b1dee65ee7bb8e120fc38a495f4027905d300650 (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.tsx | 187 |
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; |