import AsyncStorage from '@react-native-community/async-storage'; import React, {useCallback, useEffect, useState} from 'react'; import {Alert, LayoutChangeEvent, StyleSheet, View} from 'react-native'; import Animated from 'react-native-reanimated'; import {AuthContext, ProfileContext} from '../../routes/'; import {MomentType, ProfilePreviewType} from 'src/types'; import {defaultMoments, MOMENTS_ENDPOINT} from '../../constants'; import {SCREEN_HEIGHT} from '../../utils'; import TaggsBar from '../taggs/TaggsBar'; import {Moment} from '../moments'; import ProfileBody from './ProfileBody'; import ProfileCutout from './ProfileCutout'; import ProfileHeader from './ProfileHeader'; import {loadFollowers, followOrUnfollowUser} from '../../services'; interface ContentProps { y: Animated.Value; isProfileView: boolean; } const Content: React.FC = ({y, isProfileView}) => { const [profileBodyHeight, setProfileBodyHeight] = useState(0); const {newMomentsAvailable, updateMoments, user} = isProfileView ? React.useContext(ProfileContext) : React.useContext(AuthContext); const {logout} = React.useContext(AuthContext); const [imagesList, setImagesList] = useState([]); const [imagesMap, setImagesMap] = useState>( new Map(), ); const [followed, setFollowed] = React.useState(false); const [followers, setFollowers] = React.useState>( [], ); const {user: loggedInUser} = React.useContext(AuthContext); /** * If own profile is being viewed then do not show the follow button. */ const isOwnProfile = loggedInUser.username === user.username; const onLayout = (e: LayoutChangeEvent) => { const {height} = e.nativeEvent.layout; setProfileBodyHeight(height); }; const {userId, username} = user; const createImagesMap = useCallback(() => { var map = new Map(); imagesList.forEach(function (imageObject) { var moment_category = imageObject.moment_category; if (map.has(moment_category)) { map.get(moment_category).push(imageObject); } else { map.set(moment_category, [imageObject]); } }); setImagesMap(map); }, [imagesList]); useEffect(() => { if (!userId) { return; } const retrieveMoments = async () => { try { const token = await AsyncStorage.getItem('token'); const response = await fetch(MOMENTS_ENDPOINT + '?user_id=' + userId, { method: 'GET', headers: { Authorization: 'Token ' + token, }, }); const status = response.status; if (status === 200) { const data = await response.json(); setImagesList(data); updateMoments(!newMomentsAvailable); } else { console.log('Could not load moments!'); } } catch (err) { console.log(err); } }; if (newMomentsAvailable) { retrieveMoments(); createImagesMap(); } }, [userId, createImagesMap, updateMoments, newMomentsAvailable]); /** * This hook is called just on the load of profile. */ useEffect(() => { const updateFollowedValue = async () => { const token = await AsyncStorage.getItem('token'); if (!token) { logout(); return; } const listFollowers: ProfilePreviewType[] = await loadFollowers( userId, token, ); /** * Check if the logged in user actually follows the user being viewed. */ const isActuallyFollowed = listFollowers.some( (follower) => follower.username === loggedInUser.username, ); if (followed != isActuallyFollowed) { setFollowed(isActuallyFollowed); } setFollowers(listFollowers); }; /** * Update the followed value if and only if a profile is being viewed and you are loading a profile afresh that is not your own profile. */ if (isProfileView && !isOwnProfile) { updateFollowedValue(); } }, []); /** * Handles a click on the follow / unfollow button. */ const handleFollowUnfollow = async () => { const token = await AsyncStorage.getItem('token'); if (!token) { logout(); return; } const isUpdatedSuccessful = await followOrUnfollowUser( loggedInUser.userId, userId, token, followed, ); if (isUpdatedSuccessful) { setFollowed(!followed); } }; return ( y.setValue(e.nativeEvent.contentOffset.y)} showsVerticalScrollIndicator={false} scrollEventThrottle={1} stickyHeaderIndices={[2, 4]}> {defaultMoments.map((title, index) => ( ))} ); }; const styles = StyleSheet.create({ container: { flex: 1, }, momentsContainer: { backgroundColor: '#f2f2f2', paddingBottom: SCREEN_HEIGHT / 10, }, }); export default Content;