import React, {useEffect, useState, useContext} from 'react'; import {ProfilePreviewType} from '../../types'; import { View, Text, Image, StyleSheet, ViewProps, TouchableOpacity, } 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 {ProfileContext} from '../../routes/viewProfile'; const NO_USER: UserType = { userId: '', username: '', }; /** * This component returns user's profile picture followed by username as a touchable component. * What happens when someone clicks on this component is partly decided by the prop isComment. * If isComment is true then it means that we are not displaying this tile as a part of search results. * And hence we do not cache the search results. * On the other hand, if isComment is false, then we should update the search cache. (This cache needs to be revamped to clear outdated results.) * In either case, we load the ProfileContext with data and set the getNewMoments flag to true (Which ensures that everything that needs to be displayed on a user's profile is set). * Finally, We navigate to Profile if we are on the Search Stack. Else we navigate to ProfileView. */ interface ProfilePreviewProps extends ViewProps { profilePreview: ProfilePreviewType; isComment: boolean; } const ProfilePreview: React.FC = ({ profilePreview: {username, first_name, last_name, id}, isComment, style, }) => { const navigation = useNavigation(); const {loadProfile, updateMoments, updateFollowers} = useContext( ProfileContext, ); const [avatarURI, setAvatarURI] = useState(null); const [user, setUser] = useState(NO_USER); useEffect(() => { let mounted = true; const loadAvatar = async () => { try { const token = await AsyncStorage.getItem('token'); if (!token) { setUser(NO_USER); return; } const response = await RNFetchBlob.config({ fileCache: true, appendExt: 'jpg', }).fetch('GET', AVATAR_PHOTO_ENDPOINT + `${id}/`, { Authorization: 'Token ' + token, }); const status = response.info().status; if (status === 200) { if (mounted) { setAvatarURI(response.path()); } return; } if (mounted) { setAvatarURI(''); } } catch (error) { console.log(error); } }; loadAvatar(); return () => { mounted = false; }; }, [id]); /** * Adds a searched user to the recently searched cache if they're tapped on. * Cache maintains 10 recently searched users, popping off the oldest one if * needed to make space. */ const addToRecentlyStoredAndNavigateToProfile = async () => { let user: ProfilePreviewType = { id, username, first_name, last_name, }; try { if (!isComment) { const jsonValue = await AsyncStorage.getItem( '@recently_searched_users', ); let recentlySearchedList = jsonValue != null ? JSON.parse(jsonValue) : null; if (recentlySearchedList) { if (recentlySearchedList.length > 0) { if ( recentlySearchedList.some( (saved_user: ProfilePreviewType) => saved_user.id === id, ) ) { console.log('User already in recently searched.'); } else { if (recentlySearchedList.length >= 10) { recentlySearchedList.pop(); } recentlySearchedList.unshift(user); } } } else { recentlySearchedList = [user]; } try { let recentlySearchedListString = JSON.stringify(recentlySearchedList); await AsyncStorage.setItem( '@recently_searched_users', recentlySearchedListString, ); } catch (e) { console.log(e); } } //Load user profile and set new moments to true, navigate to Profile //Load user profile makes sure that we actually load profile of the user the logged in user want to view //Set new moments to true makes sure that we download the moment for the user being viewed again. loadProfile(user.id, user.username); updateMoments(true); updateFollowers(true); if (!isComment) { navigation.push('Profile', { isProfileView: true, }); } else { navigation.push('ProfileView', { isProfileView: true, }); } } catch (e) { console.log(e); } }; //With @ sign if on search screen. const usernameToDisplay = !isComment ? '@' + username : username; const usernameStyle = isComment ? styles.commentUsername : styles.searchUsername; const avatarStyle = !isComment ? styles.searchAvatar : styles.commentAvatar; return ( {usernameToDisplay} {first_name ? ( {first_name.concat(' ', last_name)} ) : ( React.Fragment )} ); }; const styles = StyleSheet.create({ container: { flexDirection: 'row', alignItems: 'center', }, searchAvatar: { height: 60, width: 60, borderRadius: 30, marginRight: 15, }, commentAvatar: { height: 40, width: 40, borderRadius: 20, marginRight: 15, marginTop: '2%', }, nameContainer: { justifyContent: 'space-evenly', alignSelf: 'stretch', }, searchUsername: { fontSize: 18, fontWeight: '500', }, commentUsername: { fontSize: 16, fontWeight: '500', }, name: { fontSize: 16, color: '#333', }, }); export default ProfilePreview;