aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-03-18 19:48:53 -0400
committerGitHub <noreply@github.com>2021-03-18 19:48:53 -0400
commitaa0ddb7c5a6612ff067f7dce1c6d5b083db44309 (patch)
tree89326275ce5ff4e48bc29952c60856258cd8b0ab /src/components
parent07a15098625786451270e30e61e2d6e78c02d4db (diff)
parent9a7e34bf992e0bfa3b9ce7d83643d97fad209e6e (diff)
Merge pull request #303 from shravyaramesh/add-friends-thru-contacts
[TMA-622] Add friends from contacts
Diffstat (limited to 'src/components')
-rw-r--r--src/components/friends/InviteFriendTile.tsx118
-rw-r--r--src/components/friends/index.ts1
-rw-r--r--src/components/profile/Friends.tsx178
-rw-r--r--src/components/search/SearchBar.tsx2
4 files changed, 279 insertions, 20 deletions
diff --git a/src/components/friends/InviteFriendTile.tsx b/src/components/friends/InviteFriendTile.tsx
new file mode 100644
index 00000000..3fbf2e73
--- /dev/null
+++ b/src/components/friends/InviteFriendTile.tsx
@@ -0,0 +1,118 @@
+import React, {useEffect, useState} from 'react';
+import {
+ Alert,
+ StyleSheet,
+ Text,
+ TouchableOpacity,
+ TouchableWithoutFeedback,
+ 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';
+
+interface InviteFriendTileProps {
+ item: Object;
+}
+
+const InviteFriendTile: React.FC<InviteFriendTileProps> = ({item}) => {
+ const [invited, setInvited] = useState<boolean>(false);
+ const [formatedPhoneNumber, setFormattedPhoneNumber] = useState<string>('');
+ const handleInviteFriend = async () => {
+ const response = await inviteFriendService(
+ item.phoneNumber,
+ item.firstName,
+ item.lastName,
+ );
+ if (response) {
+ setInvited(response);
+ } else {
+ Alert.alert(ERROR_SOMETHING_WENT_WRONG);
+ }
+ };
+
+ useEffect(() => {
+ const formatPhoneNumer = () => {
+ const unformatted_number: string = item.phoneNumber;
+ const part_one: string = unformatted_number.substring(2, 5);
+ const part_two: string = unformatted_number.substring(5, 8);
+ const part_three: string = unformatted_number.substring(
+ 8,
+ unformatted_number.length,
+ );
+ const temp = '(' + part_one + ')' + part_two + '-' + part_three;
+ setFormattedPhoneNumber(temp);
+ };
+ formatPhoneNumer();
+ });
+
+ return (
+ <TouchableWithoutFeedback>
+ <View style={styles.container}>
+ <View style={styles.bodyContainer}>
+ <Text style={styles.label}>
+ {item.firstName + ' ' + item.lastName}
+ </Text>
+ <Text style={styles.phoneNumber}>{formatedPhoneNumber}</Text>
+ </View>
+ <TouchableOpacity
+ disabled={invited}
+ style={styles.button}
+ onPress={handleInviteFriend}>
+ <Text style={styles.buttonTitle}>
+ {invited ? 'Invited' : 'Invite'}
+ </Text>
+ </TouchableOpacity>
+ </View>
+ </TouchableWithoutFeedback>
+ );
+};
+
+const styles = StyleSheet.create({
+ container: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'space-between',
+ 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',
+ alignItems: 'center',
+ width: 82,
+ height: 25,
+ borderColor: TAGG_LIGHT_BLUE,
+ borderWidth: 2,
+ borderRadius: 2,
+ padding: 0,
+ backgroundColor: 'transparent',
+ },
+ buttonTitle: {
+ color: TAGG_LIGHT_BLUE,
+ padding: 0,
+ fontSize: normalize(11),
+ fontWeight: '700',
+ lineHeight: normalize(13.13),
+ letterSpacing: normalize(0.6),
+ paddingHorizontal: '3.8%',
+ },
+});
+
+export default InviteFriendTile;
diff --git a/src/components/friends/index.ts b/src/components/friends/index.ts
new file mode 100644
index 00000000..42727784
--- /dev/null
+++ b/src/components/friends/index.ts
@@ -0,0 +1 @@
+export {default as InviteFriendTile} from './InviteFriendTile';
diff --git a/src/components/profile/Friends.tsx b/src/components/profile/Friends.tsx
index 7c7265c5..0592def8 100644
--- a/src/components/profile/Friends.tsx
+++ b/src/components/profile/Friends.tsx
@@ -1,14 +1,23 @@
-import React from 'react';
-import {View, StyleSheet, ScrollView, Text} from 'react-native';
-import {ProfilePreviewType, ScreenType} from '../../types';
-import {ProfilePreview} from '../profile';
-import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {useNavigation} from '@react-navigation/native';
+import React, {useEffect, useState} from 'react';
+import {Alert, Linking, ScrollView, StyleSheet, Text, View} from 'react-native';
+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';
-import {RootState} from '../../store/rootReducer';
-import {useDispatch, useStore} from 'react-redux';
-import {handleUnfriend} from '../../utils/friends';
+import {usersFromContactsService} from '../../services';
import {NO_USER} from '../../store/initialStates';
-import {TouchableOpacity} from 'react-native-gesture-handler';
+import {RootState} from '../../store/rootReducer';
+import {ProfilePreviewType, ScreenType} from '../../types';
+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';
interface FriendsProps {
result: Array<ProfilePreviewType>;
@@ -17,16 +26,107 @@ interface FriendsProps {
}
const Friends: React.FC<FriendsProps> = ({result, screenType, userId}) => {
- const state: RootState = useStore().getState();
const dispatch = useDispatch();
+ const navigation = useNavigation();
+ const {user: loggedInUser = NO_USER} = useSelector(
+ (state: RootState) => state.user,
+ );
+ const state = useStore().getState();
+ const [usersFromContacts, setUsersFromContacts] = useState<
+ ProfilePreviewType[]
+ >([]);
- const {user: loggedInUser = NO_USER} = state;
+ useEffect(() => {
+ const handleFindFriends = () => {
+ extractContacts().then(async (contacts) => {
+ const permission = await checkPermission();
+ if (permission === 'authorized') {
+ let response = await usersFromContactsService(contacts);
+ await setUsersFromContacts(response.existing_tagg_users);
+ } else {
+ console.log('Authorize access to contacts');
+ }
+ });
+ };
+ handleFindFriends();
+ }, []);
+
+ const UsersFromContacts = () => (
+ <>
+ {usersFromContacts?.splice(0, 2).map((profilePreview) => (
+ <View key={profilePreview.id} style={styles.container}>
+ <View style={styles.friend}>
+ <ProfilePreview
+ {...{profilePreview}}
+ previewType={'Friend'}
+ screenType={screenType}
+ />
+ </View>
+ <TouchableOpacity
+ style={styles.button}
+ onPress={() => {
+ console.log('screentype: ', screenType);
+ handleAddFriend(screenType, profilePreview, dispatch, state).then(
+ (success) => {
+ if (success) {
+ let users = usersFromContacts;
+ setUsersFromContacts(
+ users.filter(
+ (user) => user.username !== profilePreview.username,
+ ),
+ );
+ }
+ },
+ );
+ }}>
+ <Text style={styles.buttonTitle}>Add Friend</Text>
+ </TouchableOpacity>
+ </View>
+ ))}
+ </>
+ );
return (
<>
- <View style={styles.subheader}>
- {/* <Text style={styles.subheaderText}>Friends</Text> */}
- </View>
+ {loggedInUser.userId === userId ||
+ (userId === undefined && (
+ <View style={styles.subheader}>
+ <View style={styles.addFriendHeaderContainer}>
+ <Text style={[styles.subheaderText]}>Add Friends</Text>
+ <TouchableOpacity
+ style={styles.findFriendsButton}
+ onPress={async () => {
+ const permission = await checkPermission();
+ if (permission === 'authorized') {
+ navigation.navigate('InviteFriendsScreen', {
+ screenType: ScreenType.Profile,
+ });
+ } else {
+ Alert.alert(
+ '"Tagg" Would Like to Access Your Contacts',
+ 'This helps you quickly get in touch with friends on the app and more',
+ [
+ {
+ text: "Don't Allow",
+ style: 'cancel',
+ },
+ {text: 'Allow', onPress: () => Linking.openSettings()},
+ ],
+ );
+ }
+ }}>
+ <FindFriendsBlueIcon width={20} height={20} />
+ <Text style={styles.findFriendsSubheaderText}>
+ Find Friends
+ </Text>
+ </TouchableOpacity>
+ </View>
+ <UsersFromContacts />
+ </View>
+ ))}
+ <Text style={[styles.subheaderText, styles.friendsSubheaderText]}>
+ Friends
+ </Text>
<ScrollView
keyboardShouldPersistTaps={'always'}
style={styles.scrollView}
@@ -41,7 +141,7 @@ const Friends: React.FC<FriendsProps> = ({result, screenType, userId}) => {
screenType={screenType}
/>
</View>
- {loggedInUser.userId === userId && (
+ {loggedInUser.userId !== userId && (
<TouchableOpacity
style={styles.button}
onPress={() =>
@@ -63,12 +163,19 @@ const styles = StyleSheet.create({
alignSelf: 'center',
width: SCREEN_WIDTH * 0.85,
},
+ firstScrollView: {},
scrollViewContent: {
alignSelf: 'center',
paddingBottom: SCREEN_HEIGHT / 7,
width: SCREEN_WIDTH * 0.85,
marginTop: '1%',
},
+ addFriendHeaderContainer: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ marginBottom: '3%',
+ marginTop: '2%',
+ },
header: {flexDirection: 'row'},
subheader: {
alignSelf: 'center',
@@ -81,6 +188,20 @@ const styles = StyleSheet.create({
fontWeight: '600',
lineHeight: normalize(14.32),
},
+ findFriendsButton: {flexDirection: 'row'},
+ friendsSubheaderText: {
+ alignSelf: 'center',
+ width: SCREEN_WIDTH * 0.85,
+ marginVertical: '1%',
+ marginBottom: '2%',
+ },
+ findFriendsSubheaderText: {
+ marginLeft: '5%',
+ color: '#08E2E2',
+ fontSize: normalize(12),
+ fontWeight: '600',
+ lineHeight: normalize(14.32),
+ },
container: {
alignSelf: 'center',
flexDirection: 'row',
@@ -94,7 +215,7 @@ const styles = StyleSheet.create({
alignSelf: 'center',
height: '100%',
},
- button: {
+ addFriendButton: {
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
@@ -104,10 +225,31 @@ const styles = StyleSheet.create({
borderWidth: 2,
borderRadius: 2,
padding: 0,
- backgroundColor: 'transparent',
+ 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%',
+ },
+ button: {
+ alignSelf: 'center',
+ justifyContent: 'center',
+ alignItems: 'center',
+ width: 82,
+ height: '55%',
+ borderColor: TAGG_LIGHT_BLUE,
+ borderWidth: 2,
+ borderRadius: 2,
+ padding: 0,
+ backgroundColor: TAGG_LIGHT_BLUE,
},
buttonTitle: {
- color: TAGG_LIGHT_BLUE,
+ color: 'white',
padding: 0,
fontSize: normalize(11),
fontWeight: '700',
diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx
index 1a855f20..62bda77e 100644
--- a/src/components/search/SearchBar.tsx
+++ b/src/components/search/SearchBar.tsx
@@ -70,8 +70,6 @@ const SearchBar: React.FC<SearchBarProps> = ({
// TODO: FIGURE OUT WHY CHANGES IN placeholderId ARE NOT REFLECTED HERE
// my thought: the value is set when the function is defined, so it keeps
// its inital value of -1 forever.
- console.log(`Previous ID: ${placeholderId}`);
- console.log(`Next ID: ${nextId}`);
setPlaceholderId(nextId);
};