aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-02-18 19:08:16 -0500
committerIvan Chen <ivan@tagg.id>2021-02-18 19:08:16 -0500
commitcd10595e8675c8bcf32399a910f90a626d706f3a (patch)
tree3b42405eb871c965abb599f58098119e079d0d52 /src
parent0c1b1831392825556d9731f95561da2ef413dd4b (diff)
pagination mostly working
Diffstat (limited to 'src')
-rw-r--r--src/components/suggestedPeople/MutualFriends.tsx24
-rw-r--r--src/constants/api.ts3
-rw-r--r--src/constants/constants.ts2
-rw-r--r--src/screens/suggestedPeople/SuggestedPeopleScreen.tsx152
-rw-r--r--src/services/SuggestedPeopleService.ts32
5 files changed, 145 insertions, 68 deletions
diff --git a/src/components/suggestedPeople/MutualFriends.tsx b/src/components/suggestedPeople/MutualFriends.tsx
index f99279c0..283ee6c5 100644
--- a/src/components/suggestedPeople/MutualFriends.tsx
+++ b/src/components/suggestedPeople/MutualFriends.tsx
@@ -1,29 +1,21 @@
import React, {useState} from 'react';
import {SafeAreaView, StyleSheet, Text, View} from 'react-native';
+import {normalize} from 'react-native-elements';
import {ScrollView, TouchableOpacity} from 'react-native-gesture-handler';
-import {useSelector} from 'react-redux';
-import {ScreenType} from '../../types';
import {BottomDrawer, TabsGradient} from '../../components';
-import {RootState} from '../../store/rootReducer';
+import {ProfilePreviewType, ScreenType} from '../../types';
import {isIPhoneX, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
import {ProfilePreview} from '../profile';
-import {normalize} from 'react-native-elements';
-const MutualFriends: React.FC = () => {
- // Requires user id of profile being viewed
- const userXId = '53a7df9c-c3b2-4b1c-b197-7b1149ecfc8d';
-
- // Fetch mutual friends of user X
- let {friends} = userXId
- ? useSelector((state: RootState) => state.userX[ScreenType.Search][userXId])
- : useSelector((state: RootState) => state.friends);
+interface MutualFriendsProps {
+ user: ProfilePreviewType;
+ friends: ProfilePreviewType[];
+}
+const MutualFriends: React.FC<MutualFriendsProps> = ({user, friends}) => {
// Getting list of first 4 friends to display on suggested people screen
const friendsPreview = friends.slice(0, 4);
- // Extract username of user whose profile is being viewed
- const username = '@' + '12345678901234';
-
// Count to be displayed after + symbol
const count = friends.length - friendsPreview.length;
@@ -61,7 +53,7 @@ const MutualFriends: React.FC = () => {
<View style={styles.headerTextContainer}>
<Text style={styles.headerTitle}>Mutual Friends</Text>
<Text style={styles.headerDescription} numberOfLines={2}>
- {username} and you are both friends with
+ @{user.username} and you are both friends with
</Text>
</View>
</View>
diff --git a/src/constants/api.ts b/src/constants/api.ts
index 215dadc0..57c26824 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -34,7 +34,8 @@ export const WAITLIST_USER_ENDPOINT: string = API_URL + 'waitlist-user/';
export const COMMENT_THREAD_ENDPOINT: string = API_URL + 'reply/';
// Suggested People
-export const SP_UPDATE_PICTURE: string = API_URL + 'suggested_people/update_picture/';
+export const SP_USERS_ENDPOINT: string = API_URL + 'suggested_people/';
+export const SP_UPDATE_PICTURE_ENDPOINT: string = API_URL + 'suggested_people/update_picture/';
// Register as FCM device
export const FCM_ENDPOINT: string = API_URL + 'fcm/';
diff --git a/src/constants/constants.ts b/src/constants/constants.ts
index fbf03744..6e2c9e1c 100644
--- a/src/constants/constants.ts
+++ b/src/constants/constants.ts
@@ -184,3 +184,5 @@ export const EXPLORE_SECTION_TITLES: ExploreSectionType[] = [
export const SP_WIDTH = 375;
export const SP_HEIGHT = 812;
+
+export const SP_PAGE_SIZE = 5;
diff --git a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
index 3437cd85..d61ba2fe 100644
--- a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
+++ b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx
@@ -1,22 +1,25 @@
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 {TabsGradient, TaggsBar} from '../../components';
+import {useDispatch, useSelector, useStore} from 'react-redux';
+import {TabsGradient} 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 {RootState} from '../../store/rootReducer';
-import {ScreenType} from '../../types';
-import {isIPhoneX, normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {ScreenType, SuggestedPeopleDataType} from '../../types';
+import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
/**
* Bare bones for suggested people consisting of:
@@ -24,17 +27,40 @@ 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 [users, setUsers] = useState<SuggestedPeopleDataType[]>([]);
+ const [page, setPage] = useState(0);
+ const [refreshing, setRefreshing] = 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(() => {
+ const loadNextPage = async () =>
+ await getSuggestedPeople(SP_PAGE_SIZE, page * SP_PAGE_SIZE);
+ loadNextPage().then((newUsers) => {
+ setUsers(users.concat(newUsers));
+ });
+ }, [page]);
- // Adviced to maintain username as a variable here to append @ symbol for maintainability
- const username = '@' + 'sarahmiller';
- const navigation = useNavigation();
+ const resetPage = () => {
+ const reset = async () => {
+ await setPage(0);
+ };
+ setRefreshing(true);
+ reset().then(() => {
+ setRefreshing(false);
+ });
+ };
+
+ const onRefresh = useCallback(() => {
+ resetPage();
+ }, []);
useFocusEffect(
useCallback(() => {
@@ -48,47 +74,74 @@ 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.addUserContainer}>
- <View style={styles.nameInfoContainer}>
- <Text style={styles.firstName}>{firstName}</Text>
- <Text style={styles.username}>{username}</Text>
- </View>
- <TouchableOpacity
- activeOpacity={0.5}
- onPress={() => console.log('Call add friend function')}>
- <View style={styles.addButton}>
- <Text style={styles.addButtonTitle}>{'Add Friend'}</Text>
+ const SPBody = ({
+ item,
+ }: {
+ item: ListRenderItemInfo<SuggestedPeopleDataType>;
+ }) => {
+ const data = item.item;
+ return (
+ <>
+ <Image
+ // tmp smiller image on s3 for now
+ source={{
+ uri:
+ 'https://tagg-dev.s3.us-east-2.amazonaws.com/suggestedPeople/sdp-53a7df9c-c3b2-4b1c-b197-7b1149ecfc8d.png',
+ }}
+ // 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.addUserContainer}>
+ <View style={styles.nameInfoContainer}>
+ <Text style={styles.firstName}>{data.user.first_name}</Text>
+ <Text style={styles.username}>{data.user.username}</Text>
</View>
- </TouchableOpacity>
+ {/* TODO: uncomment 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> */}
+ </View>
+ {/* {loadedStatus[data.user.username] && (
+ <TaggsBar
+ y={y}
+ userXId={undefined}
+ profileBodyHeight={0}
+ screenType={ScreenType.SuggestedPeople}
+ />
+ )} */}
+ <MutualFriends user={data.user} friends={data.mutual_friends} />
</View>
- <TaggsBar
- y={y}
- userXId={undefined}
- profileBodyHeight={0}
- screenType={ScreenType.SuggestedPeople}
- />
- <MutualFriends />
</View>
- </View>
- <TabsGradient />
- </SafeAreaView>
- );
+ </>
+ );
+ };
return suggested_people_linked === 0 ? (
<SuggestedPeopleOnboardingStackScreen />
) : (
- mainContent()
+ <>
+ <StatusBar barStyle={'light-content'} />
+ <FlatList
+ data={users}
+ renderItem={(item) => <SPBody item={item} />}
+ keyExtractor={(item, index) => index.toString()}
+ showsVerticalScrollIndicator={false}
+ onEndReached={() => setPage(page + 1)}
+ refreshControl={
+ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
+ }
+ pagingEnabled
+ />
+ <TabsGradient />
+ </>
);
};
@@ -96,7 +149,8 @@ const styles = StyleSheet.create({
mainContainer: {
flexDirection: 'column',
width: SCREEN_WIDTH * 0.9,
- height: isIPhoneX() ? SCREEN_HEIGHT * 0.85 : SCREEN_HEIGHT * 0.88,
+ height: SCREEN_HEIGHT,
+ paddingVertical: '15%',
justifyContent: 'space-between',
alignSelf: 'center',
marginHorizontal: '5%',
@@ -171,7 +225,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-start',
- marginBottom: '5%',
+ marginBottom: '10%',
},
body: {},
});
diff --git a/src/services/SuggestedPeopleService.ts b/src/services/SuggestedPeopleService.ts
index 7e43c3b6..332e2f9a 100644
--- a/src/services/SuggestedPeopleService.ts
+++ b/src/services/SuggestedPeopleService.ts
@@ -1,5 +1,10 @@
import AsyncStorage from '@react-native-community/async-storage';
-import {EDIT_PROFILE_ENDPOINT, SP_UPDATE_PICTURE} from '../constants';
+import {
+ EDIT_PROFILE_ENDPOINT,
+ SP_UPDATE_PICTURE_ENDPOINT,
+ SP_USERS_ENDPOINT,
+} from '../constants';
+import {SuggestedPeopleDataType} from '../types';
export const sendSuggestedPeopleLinked = async (
userId: string,
@@ -34,7 +39,7 @@ export const sendSuggestedPeoplePhoto = async (photoUri: string) => {
name: 'sp_photo.jpg',
type: 'image/jpg',
});
- const response = await fetch(SP_UPDATE_PICTURE, {
+ const response = await fetch(SP_UPDATE_PICTURE_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
@@ -48,3 +53,26 @@ export const sendSuggestedPeoplePhoto = async (photoUri: string) => {
return false;
}
};
+
+export const getSuggestedPeople = async (limit: number, offset: number) => {
+ try {
+ const token = await AsyncStorage.getItem('token');
+ const url = `${SP_USERS_ENDPOINT}?limit=${limit}&offset=${offset}`;
+ const response = await fetch(url, {
+ method: 'GET',
+ headers: {
+ Authorization: 'Token ' + token,
+ },
+ });
+ if (response.status !== 200) {
+ throw 'Non-200 response';
+ }
+ const data = await response.json();
+ const typedData: SuggestedPeopleDataType[] = data.results;
+ return typedData;
+ } catch (error) {
+ console.log('Error fetching SP user data');
+ console.log(error);
+ return [];
+ }
+};