aboutsummaryrefslogtreecommitdiff
path: root/src/screens
diff options
context:
space:
mode:
authorIvan Chen <ivan@thetaggid.com>2021-02-20 12:27:45 -0500
committerGitHub <noreply@github.com>2021-02-20 12:27:45 -0500
commiteae63e4a336785ae45cd01c4448a8444a7793613 (patch)
tree08aeb9ce90be7ca69b56923bab6c34871b3a793a /src/screens
parent4b8130932b943afe9fdf63c611f1897622ab795e (diff)
parent82fc3c7ded1022a31cd532d469457d77f9214cc8 (diff)
Merge pull request #248 from IvanIFChen/tma258-sp-pagination-2
[TMA-258] SP Pagination
Diffstat (limited to 'src/screens')
-rw-r--r--src/screens/suggestedPeople/SuggestedPeopleScreen.tsx174
1 files changed, 129 insertions, 45 deletions
diff --git a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
index ba9c36a7..b9dee55a 100644
--- a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
+++ b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
@@ -1,22 +1,31 @@
import {useFocusEffect, useNavigation} from '@react-navigation/native';
-import React, {useCallback} from 'react';
+import React, {useCallback, useEffect, useState} from 'react';
import {
+ FlatList,
+ ListRenderItemInfo,
+ RefreshControl,
StatusBar,
StyleSheet,
Text,
- TouchableOpacity,
View,
} from 'react-native';
import {Image} from 'react-native-animatable';
import Animated from 'react-native-reanimated';
-import {SafeAreaView} from 'react-native-safe-area-context';
-import {useSelector} from 'react-redux';
+import {useDispatch, useSelector, useStore} from 'react-redux';
import {TabsGradient, TaggsBar} from '../../components';
import {MutualFriends} from '../../components/suggestedPeople';
+import {SP_PAGE_SIZE} from '../../constants';
import SuggestedPeopleOnboardingStackScreen from '../../routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen';
+import {getSuggestedPeople} from '../../services/SuggestedPeopleService';
+import {resetScreenType} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
-import {ScreenType} from '../../types';
-import {isIPhoneX, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {
+ ProfilePreviewType,
+ ScreenType,
+ SuggestedPeopleDataType,
+} from '../../types';
+import {fetchUserX, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {userXInStore} from './../../utils/';
/**
* Bare bones for suggested people consisting of:
@@ -24,17 +33,64 @@ import {isIPhoneX, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
*/
const SuggestedPeopleScreen: React.FC = () => {
+ const y = Animated.useValue(0);
+ const navigation = useNavigation();
+ const state: RootState = useStore().getState();
+ const dispatch = useDispatch();
+ const screenType = ScreenType.SuggestedPeople;
const {suggested_people_linked} = useSelector(
(state: RootState) => state.user.profile,
) ?? {suggested_people_linked: -1};
- const y = Animated.useValue(0);
+ const [people, setPeople] = useState<SuggestedPeopleDataType[]>([]);
+ const [page, setPage] = useState(0);
+ const [refreshing, setRefreshing] = useState(false);
+ const [hideStatusBar, setHideStatusBar] = useState(false);
- // Can be removed once firstname, username props are received
- const firstName = 'Sarah';
+ // loads data and append it to users based on current page
+ useEffect(() => {
+ // console.log('current page', page);
+ loadMore(false);
+ }, [page]);
- // Adviced to maintain username as a variable here to append @ symbol for maintainability
- const username = '@' + 'sarahmiller';
- const navigation = useNavigation();
+ const loadMore = (resetData: boolean) => {
+ const loadNextPage = async () =>
+ await getSuggestedPeople(SP_PAGE_SIZE, page * SP_PAGE_SIZE);
+ loadNextPage().then((newUsers) => {
+ if (resetData) {
+ setPeople([]);
+ setPage(0);
+ }
+ loadUserDataToStore(newUsers.map((ppl) => ppl.user));
+ setPeople(people.concat(newUsers));
+ });
+ };
+
+ const loadUserDataToStore = async (users: ProfilePreviewType[]) => {
+ const loadUserData = async (user: ProfilePreviewType) => {
+ if (!userXInStore(state, screenType, user.id)) {
+ await fetchUserX(
+ dispatch,
+ {userId: user.id, username: user.username},
+ screenType,
+ );
+ }
+ };
+ await Promise.all(users.map((user) => loadUserData(user)));
+ };
+ const resetPage = () => {
+ const reset = async () => {
+ await dispatch(resetScreenType(screenType));
+ loadMore(true);
+ };
+ setRefreshing(true);
+ reset().then(() => {
+ setRefreshing(false);
+ });
+ };
+
+ const onRefresh = useCallback(() => {
+ resetPage();
+ }, []);
useFocusEffect(
useCallback(() => {
@@ -48,60 +104,88 @@ const SuggestedPeopleScreen: React.FC = () => {
}, [navigation, suggested_people_linked]),
);
- const mainContent = () => (
- <SafeAreaView>
- <StatusBar barStyle={'light-content'} />
- <Image
- // !!! Displaying Sarah Miller's image
- source={require('../../assets/images/sarah_miller_full.jpeg')}
- style={styles.image}
- />
- <View style={styles.mainContainer}>
- <Text style={styles.title}>Suggested People</Text>
- <View style={styles.body}>
- <View style={styles.marginManager}>
+ // const onViewableItemsChanged = useCallback(
+ // ({viewableItems}: {viewableItems: ViewToken[]}) => {
+ // setHideStatusBar(viewableItems[0].index !== 0);
+ // },
+ // [],
+ // );
+
+ const SPBody = ({
+ item,
+ }: {
+ item: ListRenderItemInfo<SuggestedPeopleDataType>;
+ }) => {
+ const data = item.item;
+ const firstItem = item.index === 0;
+ return (
+ <>
+ <StatusBar barStyle={'light-content'} hidden={hideStatusBar} />
+ <Image
+ source={{
+ uri: data.suggested_people_url,
+ }}
+ style={styles.image}
+ />
+ <View style={styles.mainContainer}>
+ <Text style={styles.title}>{firstItem && 'Suggested People'}</Text>
+ <View style={styles.body}>
<View style={styles.addUserContainer}>
<View style={styles.nameInfoContainer}>
- <Text style={styles.firstName}>{firstName}</Text>
- <Text style={styles.username}>{username}</Text>
+ <Text style={styles.firstName}>{data.user.first_name}</Text>
+ <Text style={styles.username}>{'@' + data.user.username}</Text>
</View>
- <TouchableOpacity
+ {/* TODO: Finish me ?! */}
+ {/* <TouchableOpacity
activeOpacity={0.5}
+ // TODO: Call function to Add Friend
onPress={() => console.log('Call add friend function')}>
<View style={styles.addButton}>
<Text style={styles.addButtonTitle}>{'Add Friend'}</Text>
</View>
- </TouchableOpacity>
+ </TouchableOpacity> */}
</View>
- </View>
- <TaggsBar
- y={y}
- userXId={undefined}
- profileBodyHeight={0}
- screenType={ScreenType.SuggestedPeople}
- whiteRing={true}
- />
- <View style={styles.marginManager}>
- <MutualFriends />
+ <TaggsBar
+ y={y}
+ userXId={data.user.id}
+ profileBodyHeight={0}
+ screenType={ScreenType.SuggestedPeople}
+ />
+ <MutualFriends user={data.user} friends={data.mutual_friends} />
</View>
</View>
- </View>
- <TabsGradient />
- </SafeAreaView>
- );
+ </>
+ );
+ };
return suggested_people_linked === 0 ? (
<SuggestedPeopleOnboardingStackScreen />
) : (
- mainContent()
+ <>
+ <FlatList
+ data={people}
+ renderItem={(item) => <SPBody item={item} />}
+ keyExtractor={(item, index) => index.toString()}
+ showsVerticalScrollIndicator={false}
+ onEndReached={() => setPage(page + 1)}
+ // onViewableItemsChanged={onViewableItemsChanged}
+ refreshControl={
+ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
+ }
+ pagingEnabled
+ />
+ <TabsGradient />
+ </>
);
};
const styles = StyleSheet.create({
mainContainer: {
flexDirection: 'column',
- width: SCREEN_WIDTH,
- height: isIPhoneX() ? SCREEN_HEIGHT * 0.85 : SCREEN_HEIGHT * 0.88,
+ width: SCREEN_WIDTH * 0.9,
+ height: SCREEN_HEIGHT,
+ paddingVertical: '15%',
+ paddingBottom: '20%',
justifyContent: 'space-between',
alignSelf: 'center',
},