From 1080adb75c18f6da6b91be4264c69a9bf908ff0d Mon Sep 17 00:00:00 2001
From: Shravya Ramesh <shravs1208@gmail.com>
Date: Thu, 18 Mar 2021 02:06:02 -0700
Subject: works

---
 src/screens/profile/InviteFriendsScreen.tsx | 330 ++++++++++++++++++++++++++++
 1 file changed, 330 insertions(+)
 create mode 100644 src/screens/profile/InviteFriendsScreen.tsx

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
new file mode 100644
index 00000000..8fc12a5e
--- /dev/null
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -0,0 +1,330 @@
+import React, {useEffect, useState} from 'react';
+import {
+  View,
+  Text,
+  TouchableOpacity,
+  SafeAreaView,
+  StyleSheet,
+  TextInput,
+  FlatList,
+  Keyboard,
+  Linking,
+  StatusBar,
+  TouchableWithoutFeedback,
+} from 'react-native';
+import {useDispatch, useStore} from 'react-redux';
+import {ProfilePreviewType, ScreenType} from '../../types';
+import {
+  handleAddFriend,
+  HeaderHeight,
+  normalize,
+  SCREEN_HEIGHT,
+  SCREEN_WIDTH,
+} from '../../utils';
+import {checkPermission, getAll} from 'react-native-contacts';
+import {usersFromContactsService} from '../../services/UserFriendsService';
+import {ProfilePreview, TabsGradient} from '../../components';
+import Animated from 'react-native-reanimated';
+import Icon from 'react-native-vector-icons/Feather';
+import {InviteFriendTile} from '../../components/friends';
+import {TAGG_LIGHT_BLUE} from '../../constants';
+const AnimatedIcon = Animated.createAnimatedComponent(Icon);
+
+interface InviteFriendsScreenProps {
+  screenType: ScreenType;
+}
+
+const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
+  screenType,
+}) => {
+  const dispatch = useDispatch();
+  const state = useStore().getState();
+  const [usersFromContacts, setUsersFromContacts] = useState<
+    ProfilePreviewType[]
+  >([]);
+  const [nonUsersFromContacts, setNonUsersFromContacts] = useState<[]>([]);
+  type SearchResultType = {
+    usersFromContacts: ProfilePreviewType[];
+    nonUsersFromContacts: [];
+  };
+  const [results, setResults] = useState<SearchResultType>({
+    usersFromContacts: usersFromContacts,
+    nonUsersFromContacts: nonUsersFromContacts,
+  });
+  const [query, setQuery] = useState('');
+
+  const extractPhoneNumbers = async () => {
+    let phoneNumbers: Array<string> = [];
+    await getAll().then((contacts) => {
+      contacts.map((contact) => {
+        contact.phoneNumbers.map(async (phoneNumber) => {
+          phoneNumbers.push(await phoneNumber.number);
+        });
+      });
+    });
+    return phoneNumbers;
+  };
+
+  useEffect(() => {
+    const handleFindFriends = () => {
+      extractPhoneNumbers().then(async (phoneNumbers) => {
+        const permission = await checkPermission();
+        if (permission === 'authorized') {
+          let response = await usersFromContactsService(phoneNumbers);
+          await setUsersFromContacts(response.existing_tagg_users);
+          await setNonUsersFromContacts(response.invite_from_contacts);
+          usersFromContacts.map((user) => console.log('user: ', user.username));
+          setResults({
+            usersFromContacts: response.existing_tagg_users,
+            nonUsersFromContacts: response.invite_from_contacts,
+          });
+        } else {
+          Linking.openSettings();
+        }
+      });
+    };
+    handleFindFriends();
+  }, []);
+
+  /*
+   * Main handler for changes in query.
+   */
+  useEffect(() => {
+    const search = async () => {
+      if (query.length > 0) {
+        const searchResultsUsers = usersFromContacts.filter(
+          (item: ProfilePreviewType) => {
+            if (
+              item.first_name.includes(query) ||
+              item.last_name.includes(query) ||
+              item.username.includes(query)
+            ) {
+              return item;
+            }
+          },
+        );
+        const searchResultsNonUsers = nonUsersFromContacts.filter((item) => {
+          if (item.firstName.includes(query) || item.lastName.includes(query)) {
+            return item;
+          }
+        });
+        const sanitizedResult = {
+          usersFromContacts: searchResultsUsers,
+          nonUsersFromContacts: searchResultsNonUsers,
+        };
+        setResults(sanitizedResult);
+      } else {
+        setResults({
+          usersFromContacts: usersFromContacts,
+          nonUsersFromContacts: nonUsersFromContacts,
+        });
+      }
+    };
+    search();
+  }, [query]);
+
+  const UsersFromContacts = () => (
+    <>
+      <FlatList
+        style={{maxHeight: SCREEN_HEIGHT * 0.2}}
+        showsVerticalScrollIndicator={false}
+        data={results.usersFromContacts}
+        keyExtractor={(item) => item.username}
+        renderItem={({item}) => (
+          <View key={item.id} style={styles.ppContainer}>
+            <View style={styles.friend}>
+              <ProfilePreview
+                {...{profilePreview: item}}
+                previewType={'Friend'}
+                screenType={screenType}
+              />
+            </View>
+            <TouchableOpacity
+              style={styles.addFriendButton}
+              onPress={() => {
+                handleAddFriend(screenType, item, dispatch, state).then(
+                  (success) => {
+                    if (success) {
+                      let users = usersFromContacts;
+                      const filteredUsers = users.filter(
+                        (user) => user.username !== item.username,
+                      );
+                      console.log('filteredUsers: ', filteredUsers);
+                      setResults({
+                        ...results,
+                        usersFromContacts: filteredUsers,
+                      });
+                    }
+                  },
+                );
+              }}>
+              <Text style={styles.addFriendButtonTitle}>Add Friend</Text>
+            </TouchableOpacity>
+          </View>
+        )}
+      />
+    </>
+  );
+
+  const NonUsersFromContacts = () => (
+    <>
+      <FlatList
+        showsVerticalScrollIndicator={false}
+        data={results.nonUsersFromContacts}
+        keyExtractor={(item) => item.phoneNumber}
+        renderItem={({item}) => <InviteFriendTile item={item} />}
+      />
+    </>
+  );
+
+  return (
+    <View style={{backgroundColor: 'white', height: SCREEN_HEIGHT}}>
+      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
+        <SafeAreaView>
+          <StatusBar barStyle="dark-content" />
+          <View style={styles.body}>
+            <View style={{width: 319, height: 42, alignSelf: 'center', marginBottom: '2%',}}>
+              <Text style={[styles.subheaderText, {textAlign: 'center'}]}>
+                Sharing is caring, invite friends, and create moments together!
+              </Text>
+            </View>
+            <View style={styles.container}>
+              <Animated.View style={styles.inputContainer}>
+                <AnimatedIcon
+                  name="search"
+                  color={'#7E7E7E'}
+                  size={16}
+                  style={styles.searchIcon}
+                />
+                <TextInput
+                  style={[styles.input]}
+                  placeholderTextColor={'#828282'}
+                  clearButtonMode="while-editing"
+                  autoCapitalize="none"
+                  autoCorrect={false}
+                  onChangeText={(text) => {
+                    setQuery(text);
+                  }}
+                  onBlur={() => {
+                    Keyboard.dismiss();
+                  }}
+                  onEndEditing={() => {
+                    Keyboard.dismiss();
+                  }}
+                  value={query}
+                  placeholder={'Search'}
+                />
+              </Animated.View>
+            </View>
+            <View style={styles.subheader}>
+              <Text style={[styles.subheaderText, {marginBottom: '5%'}]}>
+                Add Friends
+              </Text>
+              <UsersFromContacts />
+            </View>
+            <View style={styles.subheader}>
+              <Text style={styles.subheaderText}>Invite your friends!</Text>
+              <NonUsersFromContacts />
+            </View>
+          </View>
+        </SafeAreaView>
+      </TouchableWithoutFeedback>
+      <TabsGradient />
+    </View>
+  );
+};
+
+const styles = StyleSheet.create({
+  body: {
+    paddingTop: HeaderHeight * 1.3,
+    height: SCREEN_HEIGHT * 0.8,
+    backgroundColor: '#fff',
+  },
+  subheader: {
+    alignSelf: 'center',
+    width: SCREEN_WIDTH * 0.85,
+    marginBottom: '5%',
+  },
+  subheaderText: {
+    color: '#828282',
+    fontSize: normalize(12),
+    fontWeight: '600',
+    lineHeight: normalize(14.32),
+  },
+  container: {
+    alignSelf: 'center',
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    width: '100%',
+    height: normalize(42),
+    alignItems: 'center',
+    marginBottom: '3%',
+    marginHorizontal: 10,
+  },
+  ppContainer: {
+    alignSelf: 'center',
+    flexDirection: 'row',
+    justifyContent: 'space-between',
+    width: '100%',
+    height: normalize(42),
+    alignItems: 'center',
+    marginBottom: '5%',
+    marginHorizontal: 10,
+  },
+  inputContainer: {
+    flexGrow: 1,
+    flexDirection: 'row',
+    alignItems: 'center',
+    paddingHorizontal: 8,
+    marginHorizontal: '3%',
+    borderRadius: 20,
+    backgroundColor: '#F0F0F0',
+    height: 34,
+  },
+  searchIcon: {
+    marginRight: '5%',
+  },
+  input: {
+    flex: 1,
+    fontSize: normalize(16),
+    color: '#000',
+    letterSpacing: normalize(0.5),
+  },
+  cancelButton: {
+    height: '100%',
+    position: 'absolute',
+    justifyContent: 'center',
+    paddingHorizontal: 8,
+  },
+  cancelText: {
+    color: '#818181',
+    fontWeight: '500',
+  },
+  friend: {
+    alignSelf: 'center',
+    height: '100%',
+  },
+  addFriendButton: {
+    alignSelf: 'center',
+    justifyContent: 'center',
+    alignItems: 'center',
+    width: 82,
+    height: 25,
+    borderColor: TAGG_LIGHT_BLUE,
+    borderWidth: 2,
+    borderRadius: 2,
+    padding: 0,
+    backgroundColor: TAGG_LIGHT_BLUE,
+  },
+  addFriendButtonTitle: {
+    color: 'white',
+    padding: 0,
+    fontSize: normalize(11),
+    fontWeight: '700',
+    lineHeight: normalize(13.13),
+    letterSpacing: normalize(0.6),
+    paddingHorizontal: '3.8%',
+  },
+});
+
+export default InviteFriendsScreen;
-- 
cgit v1.2.3-70-g09d2


From fe5ff5ec516302811b7323cadf8e3dd0939beea4 Mon Sep 17 00:00:00 2001
From: Shravya Ramesh <shravs1208@gmail.com>
Date: Thu, 18 Mar 2021 02:45:46 -0700
Subject: services +

---
 src/components/profile/Friends.tsx          | 37 +++++++++-------
 src/screens/profile/InviteFriendsScreen.tsx | 21 ++++++---
 src/services/UserFriendsService.ts          | 67 ++++++++++++++++++++++++++++-
 src/types/types.ts                          |  6 +++
 src/utils/friends.ts                        |  2 +-
 5 files changed, 107 insertions(+), 26 deletions(-)

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/components/profile/Friends.tsx b/src/components/profile/Friends.tsx
index a1030b49..36e0ef8a 100644
--- a/src/components/profile/Friends.tsx
+++ b/src/components/profile/Friends.tsx
@@ -98,22 +98,27 @@ const Friends: React.FC<FriendsProps> = ({result, screenType, userId}) => {
 
   return (
     <>
-      <View style={styles.subheader}>
-        <View style={styles.addFriendHeaderContainer}>
-          <Text style={[styles.subheaderText]}>Add Friends</Text>
-          <TouchableOpacity
-            style={{flexDirection: 'row'}}
-            onPress={() =>
-              navigation.navigate('InviteFriendsScreen', {
-                screenType: ScreenType.Profile,
-              })
-            }>
-            <FindFriendsBlueIcon width={20} height={20} />
-            <Text style={styles.findFriendsSubheaderText}>Find Friends</Text>
-          </TouchableOpacity>
-        </View>
-        <UsersFromContacts />
-      </View>
+      {loggedInUser.userId === userId ||
+        (userId === undefined && (
+          <View style={styles.subheader}>
+            <View style={styles.addFriendHeaderContainer}>
+              <Text style={[styles.subheaderText]}>Add Friends</Text>
+              <TouchableOpacity
+                style={{flexDirection: 'row'}}
+                onPress={() =>
+                  navigation.navigate('InviteFriendsScreen', {
+                    screenType: ScreenType.Profile,
+                  })
+                }>
+                <FindFriendsBlueIcon width={20} height={20} />
+                <Text style={styles.findFriendsSubheaderText}>
+                  Find Friends
+                </Text>
+              </TouchableOpacity>
+            </View>
+            <UsersFromContacts />
+          </View>
+        ))}
       <Text style={[styles.subheaderText, styles.friendsSubheaderText]}>
         Friends
       </Text>
diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
index 8fc12a5e..1a5de1ce 100644
--- a/src/screens/profile/InviteFriendsScreen.tsx
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -13,7 +13,7 @@ import {
   TouchableWithoutFeedback,
 } from 'react-native';
 import {useDispatch, useStore} from 'react-redux';
-import {ProfilePreviewType, ScreenType} from '../../types';
+import {ContactType, ProfilePreviewType, ScreenType} from '../../types';
 import {
   handleAddFriend,
   HeaderHeight,
@@ -53,24 +53,30 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
   });
   const [query, setQuery] = useState('');
 
-  const extractPhoneNumbers = async () => {
-    let phoneNumbers: Array<string> = [];
+  const extractContacts = async () => {
+    let retrievedContacts: Array<ContactType> = [];
     await getAll().then((contacts) => {
       contacts.map((contact) => {
+        let obj: ContactType = {
+          first_name: contact.givenName,
+          last_name: contact.familyName,
+        };
         contact.phoneNumbers.map(async (phoneNumber) => {
-          phoneNumbers.push(await phoneNumber.number);
+          obj.phone_number = phoneNumber.number;
+          retrievedContacts.push(obj);
+          console.log('contact: ', obj);
         });
       });
     });
-    return phoneNumbers;
+    return retrievedContacts;
   };
 
   useEffect(() => {
     const handleFindFriends = () => {
-      extractPhoneNumbers().then(async (phoneNumbers) => {
+      extractContacts().then(async (retrievedContacts) => {
         const permission = await checkPermission();
         if (permission === 'authorized') {
-          let response = await usersFromContactsService(phoneNumbers);
+          let response = await usersFromContactsService(retrievedContacts);
           await setUsersFromContacts(response.existing_tagg_users);
           await setNonUsersFromContacts(response.invite_from_contacts);
           usersFromContacts.map((user) => console.log('user: ', user.username));
@@ -169,6 +175,7 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
   const NonUsersFromContacts = () => (
     <>
       <FlatList
+        contentContainerStyle={{paddingBottom: 130}}
         showsVerticalScrollIndicator={false}
         data={results.nonUsersFromContacts}
         keyExtractor={(item) => item.phoneNumber}
diff --git a/src/services/UserFriendsService.ts b/src/services/UserFriendsService.ts
index dbec1974..86339868 100644
--- a/src/services/UserFriendsService.ts
+++ b/src/services/UserFriendsService.ts
@@ -1,8 +1,13 @@
 //Abstracted common friends api calls out here
 
+import AsyncStorage from '@react-native-community/async-storage';
 import {Alert} from 'react-native';
-import {FriendshipStatusType} from '../types';
-import {FRIENDS_ENDPOINT} from '../constants';
+import {ContactType, FriendshipStatusType} from '../types';
+import {
+  FRIENDS_ENDPOINT,
+  INVITE_FRIEND_ENDPOINT,
+  USERS_FROM_CONTACTS_ENDPOINT,
+} from '../constants';
 import {ERROR_SOMETHING_WENT_WRONG_REFRESH} from '../constants/strings';
 
 export const loadFriends = async (userId: string, token: string) => {
@@ -181,3 +186,61 @@ export const deleteFriendshipService = async (
     return false;
   }
 };
+
+export const usersFromContactsService = async (
+  contacts: Array<ContactType>,
+) => {
+  console.log('Contacts: ', contacts);
+  try {
+    const token = await AsyncStorage.getItem('token');
+    const response = await fetch(USERS_FROM_CONTACTS_ENDPOINT, {
+      method: 'POST',
+      headers: {
+        Authorization: 'Token ' + token,
+      },
+      body: JSON.stringify({
+        contacts: contacts,
+      }),
+    });
+    const status = response.status;
+    if (Math.floor(status / 100) === 2) {
+      const users_data = await response.json();
+      return users_data;
+    } else {
+      console.log(
+        'Something went wrong! 😭',
+        'Not able to retrieve tagg users list',
+      );
+    }
+  } catch (error) {
+    console.log(error);
+    Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH);
+    return false;
+  }
+};
+
+export const inviteFriendService = async (
+  phoneNumber: string,
+  inviteeFirstName: string,
+  inviteeLastName: string,
+  inviterFullName: string,
+) => {
+  const token = await AsyncStorage.getItem('token');
+  const response = await fetch(INVITE_FRIEND_ENDPOINT, {
+    method: 'POST',
+    headers: {
+      Authorization: 'Token ' + token,
+    },
+    body: JSON.stringify({
+      phone_number: phoneNumber,
+      invitee_first_name: inviteeFirstName,
+      invitee_last_name: inviteeLastName,
+      inviter_full_name: inviterFullName,
+    }),
+  });
+  if (response.status === 201) {
+    const response_body = await response.json();
+    return response_body;
+  }
+  return false;
+};
diff --git a/src/types/types.ts b/src/types/types.ts
index e068eeba..dc2817bd 100644
--- a/src/types/types.ts
+++ b/src/types/types.ts
@@ -256,3 +256,9 @@ export type SearchCategoryType = {
   name: string;
   category: string;
 };
+
+export type ContactType = {
+  phone_number: string;
+  first_name: string;
+  last_name: string;
+};
diff --git a/src/utils/friends.ts b/src/utils/friends.ts
index 3398c123..55d65170 100644
--- a/src/utils/friends.ts
+++ b/src/utils/friends.ts
@@ -60,7 +60,7 @@ export const handleAddFriend = async (
   dispatch: AppDispatch,
   state: RootState,
 ) => {
-  const success = await dispatch(addFriend(friend, screenType));
+  const success = await dispatch(addFriend(friend, screenType, state));
   await dispatch(updateUserXFriends(friend.id, state));
   await dispatch(updateUserXProfileAllScreens(friend.id, state));
   return success;
-- 
cgit v1.2.3-70-g09d2


From f81a4e1a05ca3fa66c2798b047d4bfd6995f462d Mon Sep 17 00:00:00 2001
From: Shravya Ramesh <shravs1208@gmail.com>
Date: Thu, 18 Mar 2021 13:44:19 -0700
Subject: Support modified endpoints + refactoring

---
 src/components/friends/InviteFriendTile.tsx |  2 --
 src/components/profile/Friends.tsx          | 23 ++++++++-------------
 src/screens/profile/InviteFriendsScreen.tsx | 32 +++++++++--------------------
 src/services/UserFriendsService.ts          | 10 +++++----
 src/utils/common.ts                         | 21 ++++++++++++++++++-
 5 files changed, 44 insertions(+), 44 deletions(-)

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/components/friends/InviteFriendTile.tsx b/src/components/friends/InviteFriendTile.tsx
index c49792f9..f56d3514 100644
--- a/src/components/friends/InviteFriendTile.tsx
+++ b/src/components/friends/InviteFriendTile.tsx
@@ -19,13 +19,11 @@ interface InviteFriendTileProps {
 const InviteFriendTile: React.FC<InviteFriendTileProps> = ({item}) => {
   const [invited, setInvited] = useState<boolean>(false);
   const [formatedPhoneNumber, setFormattedPhoneNumber] = useState<string>('');
-  const {profile} = useSelector((state: RootState) => state.user);
   const handleInviteFriend = async () => {
     const response = await inviteFriendService(
       item.phoneNumber,
       item.firstName,
       item.lastName,
-      profile.name,
     );
     if (response) {
       setInvited(response);
diff --git a/src/components/profile/Friends.tsx b/src/components/profile/Friends.tsx
index 36e0ef8a..7d57177c 100644
--- a/src/components/profile/Friends.tsx
+++ b/src/components/profile/Friends.tsx
@@ -9,7 +9,12 @@ import {usersFromContactsService} from '../../services';
 import {NO_USER} from '../../store/initialStates';
 import {RootState} from '../../store/rootReducer';
 import {ProfilePreviewType, ScreenType} from '../../types';
-import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {
+  extractContacts,
+  normalize,
+  SCREEN_HEIGHT,
+  SCREEN_WIDTH,
+} from '../../utils';
 import {handleAddFriend, handleUnfriend} from '../../utils/friends';
 import {ProfilePreview} from '../profile';
 import FindFriendsBlueIcon from '../../assets/icons/findFriends/find-friends-blue-icon.svg';
@@ -31,24 +36,12 @@ const Friends: React.FC<FriendsProps> = ({result, screenType, userId}) => {
     ProfilePreviewType[]
   >([]);
 
-  const extractPhoneNumbers = async () => {
-    let phoneNumbers: Array<string> = [];
-    await getAll().then((contacts) => {
-      contacts.map((contact) => {
-        contact.phoneNumbers.map(async (phoneNumber) => {
-          phoneNumbers.push(await phoneNumber.number);
-        });
-      });
-    });
-    return phoneNumbers;
-  };
-
   useEffect(() => {
     const handleFindFriends = () => {
-      extractPhoneNumbers().then(async (phoneNumbers) => {
+      extractContacts().then(async (contacts) => {
         const permission = await checkPermission();
         if (permission === 'authorized') {
-          let response = await usersFromContactsService(phoneNumbers);
+          let response = await usersFromContactsService(contacts);
           await setUsersFromContacts(response.existing_tagg_users);
           usersFromContacts.map((user) => console.log('user: ', user.username));
         } else if (permission === 'undefined') {
diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
index 1a5de1ce..53215d8a 100644
--- a/src/screens/profile/InviteFriendsScreen.tsx
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -15,6 +15,7 @@ import {
 import {useDispatch, useStore} from 'react-redux';
 import {ContactType, ProfilePreviewType, ScreenType} from '../../types';
 import {
+  extractContacts,
   handleAddFriend,
   HeaderHeight,
   normalize,
@@ -53,24 +54,6 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
   });
   const [query, setQuery] = useState('');
 
-  const extractContacts = async () => {
-    let retrievedContacts: Array<ContactType> = [];
-    await getAll().then((contacts) => {
-      contacts.map((contact) => {
-        let obj: ContactType = {
-          first_name: contact.givenName,
-          last_name: contact.familyName,
-        };
-        contact.phoneNumbers.map(async (phoneNumber) => {
-          obj.phone_number = phoneNumber.number;
-          retrievedContacts.push(obj);
-          console.log('contact: ', obj);
-        });
-      });
-    });
-    return retrievedContacts;
-  };
-
   useEffect(() => {
     const handleFindFriends = () => {
       extractContacts().then(async (retrievedContacts) => {
@@ -190,7 +173,13 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
         <SafeAreaView>
           <StatusBar barStyle="dark-content" />
           <View style={styles.body}>
-            <View style={{width: 319, height: 42, alignSelf: 'center', marginBottom: '2%',}}>
+            <View
+              style={{
+                width: 319,
+                height: 42,
+                alignSelf: 'center',
+                marginBottom: '2%',
+              }}>
               <Text style={[styles.subheaderText, {textAlign: 'center'}]}>
                 Sharing is caring, invite friends, and create moments together!
               </Text>
@@ -224,9 +213,7 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
               </Animated.View>
             </View>
             <View style={styles.subheader}>
-              <Text style={[styles.subheaderText, {marginBottom: '5%'}]}>
-                Add Friends
-              </Text>
+              <Text style={styles.subheaderText}>Add Friends</Text>
               <UsersFromContacts />
             </View>
             <View style={styles.subheader}>
@@ -257,6 +244,7 @@ const styles = StyleSheet.create({
     fontSize: normalize(12),
     fontWeight: '600',
     lineHeight: normalize(14.32),
+    marginBottom: '5%',
   },
   container: {
     alignSelf: 'center',
diff --git a/src/services/UserFriendsService.ts b/src/services/UserFriendsService.ts
index 86339868..c6679bef 100644
--- a/src/services/UserFriendsService.ts
+++ b/src/services/UserFriendsService.ts
@@ -8,7 +8,10 @@ import {
   INVITE_FRIEND_ENDPOINT,
   USERS_FROM_CONTACTS_ENDPOINT,
 } from '../constants';
-import {ERROR_SOMETHING_WENT_WRONG_REFRESH} from '../constants/strings';
+import {
+  ERROR_SOMETHING_WENT_WRONG,
+  ERROR_SOMETHING_WENT_WRONG_REFRESH,
+} from '../constants/strings';
 
 export const loadFriends = async (userId: string, token: string) => {
   try {
@@ -223,7 +226,6 @@ export const inviteFriendService = async (
   phoneNumber: string,
   inviteeFirstName: string,
   inviteeLastName: string,
-  inviterFullName: string,
 ) => {
   const token = await AsyncStorage.getItem('token');
   const response = await fetch(INVITE_FRIEND_ENDPOINT, {
@@ -232,15 +234,15 @@ export const inviteFriendService = async (
       Authorization: 'Token ' + token,
     },
     body: JSON.stringify({
-      phone_number: phoneNumber,
+      invitee_phone_number: phoneNumber,
       invitee_first_name: inviteeFirstName,
       invitee_last_name: inviteeLastName,
-      inviter_full_name: inviterFullName,
     }),
   });
   if (response.status === 201) {
     const response_body = await response.json();
     return response_body;
   }
+  Alert.alert(ERROR_SOMETHING_WENT_WRONG);
   return false;
 };
diff --git a/src/utils/common.ts b/src/utils/common.ts
index c1049c42..5f0e26ba 100644
--- a/src/utils/common.ts
+++ b/src/utils/common.ts
@@ -1,8 +1,9 @@
-import {NotificationType} from './../types/types';
+import {ContactType, NotificationType} from './../types/types';
 import moment from 'moment';
 import {Linking} from 'react-native';
 import {BROWSABLE_SOCIAL_URLS, TOGGLE_BUTTON_TYPE} from '../constants';
 import AsyncStorage from '@react-native-community/async-storage';
+import {getAll} from 'react-native-contacts';
 
 export const getToggleButtonText: (
   buttonType: string,
@@ -115,3 +116,21 @@ export const shuffle = (array: any[]) => {
 
   return array;
 };
+
+export const extractContacts = async () => {
+  let retrievedContacts: Array<ContactType> = [];
+  await getAll().then((contacts) => {
+    contacts.map((contact) => {
+      let obj: ContactType = {
+        first_name: contact.givenName,
+        last_name: contact.familyName,
+      };
+      contact.phoneNumbers.map(async (phoneNumber) => {
+        obj.phone_number = phoneNumber.number;
+        retrievedContacts.push(obj);
+        console.log('contact: ', obj);
+      });
+    });
+  });
+  return retrievedContacts;
+};
-- 
cgit v1.2.3-70-g09d2


From 8d243eef5db576c053d521d082feb87a1a834558 Mon Sep 17 00:00:00 2001
From: Shravya Ramesh <shravs1208@gmail.com>
Date: Thu, 18 Mar 2021 15:23:18 -0700
Subject: cleaned lint erros

---
 src/components/friends/InviteFriendTile.tsx | 30 ++++++++++++---------------
 src/components/profile/Friends.tsx          |  5 +++--
 src/screens/profile/InviteFriendsScreen.tsx | 32 ++++++++++++++++++-----------
 3 files changed, 36 insertions(+), 31 deletions(-)

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/components/friends/InviteFriendTile.tsx b/src/components/friends/InviteFriendTile.tsx
index f56d3514..9613b1ac 100644
--- a/src/components/friends/InviteFriendTile.tsx
+++ b/src/components/friends/InviteFriendTile.tsx
@@ -6,8 +6,6 @@ import {
   TouchableWithoutFeedback,
   View,
 } from 'react-native';
-import {useSelector} from 'react-redux';
-import {RootState} from '../../store/rootReducer';
 import {TAGG_LIGHT_BLUE} from '../../constants';
 import {inviteFriendService} from '../../services';
 import {normalize} from '../../utils';
@@ -48,24 +46,11 @@ const InviteFriendTile: React.FC<InviteFriendTileProps> = ({item}) => {
   return (
     <TouchableWithoutFeedback>
       <View style={styles.container}>
-        <View
-          style={{
-            flexDirection: 'column',
-            height: normalize(42),
-            justifyContent: 'space-around',
-          }}>
+        <View style={styles.bodyContainer}>
           <Text style={styles.label}>
             {item.firstName + ' ' + item.lastName}
           </Text>
-          <Text
-            style={{
-              fontSize: normalize(12),
-              fontWeight: '400',
-              color: '#6C6C6C',
-              letterSpacing: normalize(0.1),
-            }}>
-            {formatedPhoneNumber}
-          </Text>
+          <Text style={styles.phoneNumber}>{formatedPhoneNumber}</Text>
         </View>
         <TouchableOpacity
           disabled={invited}
@@ -88,10 +73,21 @@ const styles = StyleSheet.create({
     height: normalize(42),
     marginBottom: '5%',
   },
+  bodyContainer: {
+    flexDirection: 'column',
+    height: normalize(42),
+    justifyContent: 'space-around',
+  },
   label: {
     fontWeight: '500',
     fontSize: normalize(14),
   },
+  phoneNumber: {
+    fontSize: normalize(12),
+    fontWeight: '400',
+    color: '#6C6C6C',
+    letterSpacing: normalize(0.1),
+  },
   button: {
     alignSelf: 'center',
     justifyContent: 'center',
diff --git a/src/components/profile/Friends.tsx b/src/components/profile/Friends.tsx
index 7d57177c..1c295c25 100644
--- a/src/components/profile/Friends.tsx
+++ b/src/components/profile/Friends.tsx
@@ -1,7 +1,7 @@
 import {useNavigation} from '@react-navigation/native';
 import React, {useEffect, useState} from 'react';
 import {ScrollView, StyleSheet, Text, View} from 'react-native';
-import {checkPermission, getAll} from 'react-native-contacts';
+import {checkPermission} from 'react-native-contacts';
 import {TouchableOpacity} from 'react-native-gesture-handler';
 import {useDispatch, useSelector, useStore} from 'react-redux';
 import {TAGG_LIGHT_BLUE} from '../../constants';
@@ -97,7 +97,7 @@ const Friends: React.FC<FriendsProps> = ({result, screenType, userId}) => {
             <View style={styles.addFriendHeaderContainer}>
               <Text style={[styles.subheaderText]}>Add Friends</Text>
               <TouchableOpacity
-                style={{flexDirection: 'row'}}
+                style={styles.findFriendsButton}
                 onPress={() =>
                   navigation.navigate('InviteFriendsScreen', {
                     screenType: ScreenType.Profile,
@@ -176,6 +176,7 @@ const styles = StyleSheet.create({
     fontWeight: '600',
     lineHeight: normalize(14.32),
   },
+  findFriendsButton: {flexDirection: 'row'},
   friendsSubheaderText: {
     alignSelf: 'center',
     width: SCREEN_WIDTH * 0.85,
diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
index 53215d8a..c98b90f8 100644
--- a/src/screens/profile/InviteFriendsScreen.tsx
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -13,7 +13,7 @@ import {
   TouchableWithoutFeedback,
 } from 'react-native';
 import {useDispatch, useStore} from 'react-redux';
-import {ContactType, ProfilePreviewType, ScreenType} from '../../types';
+import {ProfilePreviewType, ScreenType} from '../../types';
 import {
   extractContacts,
   handleAddFriend,
@@ -22,7 +22,7 @@ import {
   SCREEN_HEIGHT,
   SCREEN_WIDTH,
 } from '../../utils';
-import {checkPermission, getAll} from 'react-native-contacts';
+import {checkPermission} from 'react-native-contacts';
 import {usersFromContactsService} from '../../services/UserFriendsService';
 import {ProfilePreview, TabsGradient} from '../../components';
 import Animated from 'react-native-reanimated';
@@ -158,7 +158,7 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
   const NonUsersFromContacts = () => (
     <>
       <FlatList
-        contentContainerStyle={{paddingBottom: 130}}
+        contentContainerStyle={styles.nonUsersFlatListContainer}
         showsVerticalScrollIndicator={false}
         data={results.nonUsersFromContacts}
         keyExtractor={(item) => item.phoneNumber}
@@ -168,19 +168,13 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
   );
 
   return (
-    <View style={{backgroundColor: 'white', height: SCREEN_HEIGHT}}>
+    <View style={styles.mainContainer}>
       <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
         <SafeAreaView>
           <StatusBar barStyle="dark-content" />
           <View style={styles.body}>
-            <View
-              style={{
-                width: 319,
-                height: 42,
-                alignSelf: 'center',
-                marginBottom: '2%',
-              }}>
-              <Text style={[styles.subheaderText, {textAlign: 'center'}]}>
+            <View style={styles.headerContainer}>
+              <Text style={styles.headerText}>
                 Sharing is caring, invite friends, and create moments together!
               </Text>
             </View>
@@ -229,11 +223,25 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
 };
 
 const styles = StyleSheet.create({
+  mainContainer: {backgroundColor: 'white', height: SCREEN_HEIGHT},
   body: {
     paddingTop: HeaderHeight * 1.3,
     height: SCREEN_HEIGHT * 0.8,
     backgroundColor: '#fff',
   },
+  headerContainer: {
+    width: 319,
+    height: 42,
+    alignSelf: 'center',
+    marginBottom: '2%',
+  },
+  headerText: {
+    alignSelf: 'center',
+    width: SCREEN_WIDTH * 0.85,
+    marginBottom: '5%',
+    textAlign: 'center',
+  },
+  nonUsersFlatListContainer: {paddingBottom: 130},
   subheader: {
     alignSelf: 'center',
     width: SCREEN_WIDTH * 0.85,
-- 
cgit v1.2.3-70-g09d2


From dba4d3fa7bb174ae2c0c5324e41144508b5dc8ed Mon Sep 17 00:00:00 2001
From: Shravya Ramesh <shravs1208@gmail.com>
Date: Thu, 18 Mar 2021 15:33:45 -0700
Subject: style

---
 src/screens/profile/InviteFriendsScreen.tsx | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
index c98b90f8..0abac136 100644
--- a/src/screens/profile/InviteFriendsScreen.tsx
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -174,7 +174,7 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
           <StatusBar barStyle="dark-content" />
           <View style={styles.body}>
             <View style={styles.headerContainer}>
-              <Text style={styles.headerText}>
+              <Text style={styles.subheaderText}>
                 Sharing is caring, invite friends, and create moments together!
               </Text>
             </View>
@@ -230,16 +230,9 @@ const styles = StyleSheet.create({
     backgroundColor: '#fff',
   },
   headerContainer: {
-    width: 319,
-    height: 42,
-    alignSelf: 'center',
-    marginBottom: '2%',
-  },
-  headerText: {
-    alignSelf: 'center',
     width: SCREEN_WIDTH * 0.85,
-    marginBottom: '5%',
-    textAlign: 'center',
+    height: 50,
+    alignSelf: 'center',
   },
   nonUsersFlatListContainer: {paddingBottom: 130},
   subheader: {
@@ -253,6 +246,7 @@ const styles = StyleSheet.create({
     fontWeight: '600',
     lineHeight: normalize(14.32),
     marginBottom: '5%',
+    textAlign: 'center',
   },
   container: {
     alignSelf: 'center',
-- 
cgit v1.2.3-70-g09d2


From 02f3b84cb94677079dd2a9f3aacb8c9c11e9696e Mon Sep 17 00:00:00 2001
From: Shravya Ramesh <shravs1208@gmail.com>
Date: Thu, 18 Mar 2021 15:39:57 -0700
Subject: minor

---
 src/screens/profile/InviteFriendsScreen.tsx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
index 0abac136..a57b72b6 100644
--- a/src/screens/profile/InviteFriendsScreen.tsx
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -174,7 +174,7 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
           <StatusBar barStyle="dark-content" />
           <View style={styles.body}>
             <View style={styles.headerContainer}>
-              <Text style={styles.subheaderText}>
+              <Text style={styles.headerText}>
                 Sharing is caring, invite friends, and create moments together!
               </Text>
             </View>
@@ -246,7 +246,14 @@ const styles = StyleSheet.create({
     fontWeight: '600',
     lineHeight: normalize(14.32),
     marginBottom: '5%',
+  },
+  headerText: {
     textAlign: 'center',
+    color: '#828282',
+    fontSize: normalize(12),
+    fontWeight: '600',
+    lineHeight: normalize(14.32),
+    marginBottom: '5%',
   },
   container: {
     alignSelf: 'center',
-- 
cgit v1.2.3-70-g09d2


From ccd7d12fa20591b19ac8c8df0c9146740667f90f Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Thu, 18 Mar 2021 19:35:38 -0400
Subject: scroll view fix, search for case insensitive

---
 src/components/friends/InviteFriendTile.tsx |  4 ++
 src/screens/profile/InviteFriendsScreen.tsx | 62 +++++++++++++----------------
 src/services/UserFriendsService.ts          |  6 +--
 3 files changed, 34 insertions(+), 38 deletions(-)

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/components/friends/InviteFriendTile.tsx b/src/components/friends/InviteFriendTile.tsx
index 9613b1ac..3fbf2e73 100644
--- a/src/components/friends/InviteFriendTile.tsx
+++ b/src/components/friends/InviteFriendTile.tsx
@@ -1,5 +1,6 @@
 import React, {useEffect, useState} from 'react';
 import {
+  Alert,
   StyleSheet,
   Text,
   TouchableOpacity,
@@ -7,6 +8,7 @@ import {
   View,
 } from 'react-native';
 import {TAGG_LIGHT_BLUE} from '../../constants';
+import {ERROR_SOMETHING_WENT_WRONG} from '../../constants/strings';
 import {inviteFriendService} from '../../services';
 import {normalize} from '../../utils';
 
@@ -25,6 +27,8 @@ const InviteFriendTile: React.FC<InviteFriendTileProps> = ({item}) => {
     );
     if (response) {
       setInvited(response);
+    } else {
+      Alert.alert(ERROR_SOMETHING_WENT_WRONG);
     }
   };
 
diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
index a57b72b6..06e98b90 100644
--- a/src/screens/profile/InviteFriendsScreen.tsx
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -11,6 +11,7 @@ import {
   Linking,
   StatusBar,
   TouchableWithoutFeedback,
+  ScrollView,
 } from 'react-native';
 import {useDispatch, useStore} from 'react-redux';
 import {ProfilePreviewType, ScreenType} from '../../types';
@@ -21,6 +22,7 @@ import {
   normalize,
   SCREEN_HEIGHT,
   SCREEN_WIDTH,
+  StatusBarHeight,
 } from '../../utils';
 import {checkPermission} from 'react-native-contacts';
 import {usersFromContactsService} from '../../services/UserFriendsService';
@@ -79,24 +81,20 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
    * Main handler for changes in query.
    */
   useEffect(() => {
+    console.log('query is now ', query);
     const search = async () => {
       if (query.length > 0) {
         const searchResultsUsers = usersFromContacts.filter(
-          (item: ProfilePreviewType) => {
-            if (
-              item.first_name.includes(query) ||
-              item.last_name.includes(query) ||
-              item.username.includes(query)
-            ) {
-              return item;
-            }
-          },
+          (item: ProfilePreviewType) =>
+            item.first_name.toLowerCase().includes(query) ||
+            item.last_name.toLowerCase().includes(query) ||
+            item.username.toLowerCase().includes(query),
+        );
+        const searchResultsNonUsers = nonUsersFromContacts.filter(
+          (item) =>
+            item.firstName.toLowerCase().includes(query) ||
+            item.lastName.toLowerCase().includes(query),
         );
-        const searchResultsNonUsers = nonUsersFromContacts.filter((item) => {
-          if (item.firstName.includes(query) || item.lastName.includes(query)) {
-            return item;
-          }
-        });
         const sanitizedResult = {
           usersFromContacts: searchResultsUsers,
           nonUsersFromContacts: searchResultsNonUsers,
@@ -138,7 +136,6 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
                       const filteredUsers = users.filter(
                         (user) => user.username !== item.username,
                       );
-                      console.log('filteredUsers: ', filteredUsers);
                       setResults({
                         ...results,
                         usersFromContacts: filteredUsers,
@@ -155,24 +152,14 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
     </>
   );
 
-  const NonUsersFromContacts = () => (
-    <>
-      <FlatList
-        contentContainerStyle={styles.nonUsersFlatListContainer}
-        showsVerticalScrollIndicator={false}
-        data={results.nonUsersFromContacts}
-        keyExtractor={(item) => item.phoneNumber}
-        renderItem={({item}) => <InviteFriendTile item={item} />}
-      />
-    </>
-  );
-
   return (
     <View style={styles.mainContainer}>
       <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
-        <SafeAreaView>
+        <SafeAreaView style={{marginTop: HeaderHeight + StatusBarHeight}}>
           <StatusBar barStyle="dark-content" />
-          <View style={styles.body}>
+          <ScrollView
+            style={styles.body}
+            contentContainerStyle={{paddingBottom: SCREEN_HEIGHT * 0.1}}>
             <View style={styles.headerContainer}>
               <Text style={styles.headerText}>
                 Sharing is caring, invite friends, and create moments together!
@@ -193,7 +180,7 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
                   autoCapitalize="none"
                   autoCorrect={false}
                   onChangeText={(text) => {
-                    setQuery(text);
+                    setQuery(text.toLowerCase());
                   }}
                   onBlur={() => {
                     Keyboard.dismiss();
@@ -212,9 +199,16 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
             </View>
             <View style={styles.subheader}>
               <Text style={styles.subheaderText}>Invite your friends!</Text>
-              <NonUsersFromContacts />
+              <FlatList
+                contentContainerStyle={styles.nonUsersFlatListContainer}
+                showsVerticalScrollIndicator={false}
+                scrollEnabled={false}
+                data={results.nonUsersFromContacts}
+                keyExtractor={(item) => item.phoneNumber}
+                renderItem={({item}) => <InviteFriendTile item={item} />}
+              />
             </View>
-          </View>
+          </ScrollView>
         </SafeAreaView>
       </TouchableWithoutFeedback>
       <TabsGradient />
@@ -225,8 +219,8 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
 const styles = StyleSheet.create({
   mainContainer: {backgroundColor: 'white', height: SCREEN_HEIGHT},
   body: {
-    paddingTop: HeaderHeight * 1.3,
-    height: SCREEN_HEIGHT * 0.8,
+    paddingTop: 10,
+    height: SCREEN_HEIGHT,
     backgroundColor: '#fff',
   },
   headerContainer: {
diff --git a/src/services/UserFriendsService.ts b/src/services/UserFriendsService.ts
index c6679bef..cea20fbe 100644
--- a/src/services/UserFriendsService.ts
+++ b/src/services/UserFriendsService.ts
@@ -239,10 +239,8 @@ export const inviteFriendService = async (
       invitee_last_name: inviteeLastName,
     }),
   });
-  if (response.status === 201) {
-    const response_body = await response.json();
-    return response_body;
+  if (response.status === 201 || response.status === 200) {
+    return await response.json();
   }
-  Alert.alert(ERROR_SOMETHING_WENT_WRONG);
   return false;
 };
-- 
cgit v1.2.3-70-g09d2


From 9a7e34bf992e0bfa3b9ce7d83643d97fad209e6e Mon Sep 17 00:00:00 2001
From: Ivan Chen <ivan@tagg.id>
Date: Thu, 18 Mar 2021 19:41:29 -0400
Subject: disable scroll

---
 src/screens/profile/InviteFriendsScreen.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/screens/profile/InviteFriendsScreen.tsx')

diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx
index 06e98b90..d1142b7f 100644
--- a/src/screens/profile/InviteFriendsScreen.tsx
+++ b/src/screens/profile/InviteFriendsScreen.tsx
@@ -113,8 +113,8 @@ const InviteFriendsScreen: React.FC<InviteFriendsScreenProps> = ({
   const UsersFromContacts = () => (
     <>
       <FlatList
-        style={{maxHeight: SCREEN_HEIGHT * 0.2}}
         showsVerticalScrollIndicator={false}
+        scrollEnabled={false}
         data={results.usersFromContacts}
         keyExtractor={(item) => item.username}
         renderItem={({item}) => (
-- 
cgit v1.2.3-70-g09d2

