diff options
author | Shravya Ramesh <shravs1208@gmail.com> | 2021-03-18 02:06:02 -0700 |
---|---|---|
committer | Shravya Ramesh <shravs1208@gmail.com> | 2021-03-18 02:06:02 -0700 |
commit | 1080adb75c18f6da6b91be4264c69a9bf908ff0d (patch) | |
tree | c29ea0a0e3be6f14d64057796ddb5b853426f070 /src | |
parent | 8569dafb631d99f325236fb7a134a0087d95b212 (diff) |
works
Diffstat (limited to 'src')
-rw-r--r-- | src/assets/icons/findFriends/find-friends-blue-icon.svg | 1 | ||||
-rw-r--r-- | src/components/friends/InviteFriendTile.tsx | 86 | ||||
-rw-r--r-- | src/components/friends/index.ts | 1 | ||||
-rw-r--r-- | src/components/profile/Friends.tsx | 162 | ||||
-rw-r--r-- | src/constants/api.ts | 4 | ||||
-rw-r--r-- | src/routes/main/MainStackNavigator.tsx | 3 | ||||
-rw-r--r-- | src/routes/main/MainStackScreen.tsx | 14 | ||||
-rw-r--r-- | src/screens/profile/FriendsListScreen.tsx | 3 | ||||
-rw-r--r-- | src/screens/profile/InviteFriendsScreen.tsx | 330 | ||||
-rw-r--r-- | src/screens/profile/index.ts | 1 | ||||
-rw-r--r-- | src/store/actions/userFriends.ts | 21 | ||||
-rw-r--r-- | src/utils/users.ts | 2 |
12 files changed, 601 insertions, 27 deletions
diff --git a/src/assets/icons/findFriends/find-friends-blue-icon.svg b/src/assets/icons/findFriends/find-friends-blue-icon.svg new file mode 100644 index 00000000..26ca145d --- /dev/null +++ b/src/assets/icons/findFriends/find-friends-blue-icon.svg @@ -0,0 +1 @@ +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216 216"><defs><style>.cls-1{fill:#08e2e2;}</style></defs><path class="cls-1" d="M104.28,135.51a58.59,58.59,0,1,0-8.85,8.86l21.79,21.26,9-8.27ZM58.62,145a46.22,46.22,0,1,1,46.21-46.21A46.23,46.23,0,0,1,58.62,145Z"/><path class="cls-1" d="M216,137.23a7.87,7.87,0,0,1-7.87,7.87H185.18v23a7.81,7.81,0,0,1-15.62,0v-23H146.62a7.87,7.87,0,0,1,0-15.73h22.94v-23a7.81,7.81,0,1,1,15.62,0v23h22.95A7.88,7.88,0,0,1,216,137.23Z"/></svg>
\ No newline at end of file diff --git a/src/components/friends/InviteFriendTile.tsx b/src/components/friends/InviteFriendTile.tsx new file mode 100644 index 00000000..2d2b8e04 --- /dev/null +++ b/src/components/friends/InviteFriendTile.tsx @@ -0,0 +1,86 @@ +import React, {useState} from 'react'; +import { + StyleSheet, + Text, + TouchableOpacity, + 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'; + +interface InviteFriendTileProps { + item: Object; +} + +const InviteFriendTile: React.FC<InviteFriendTileProps> = ({item}) => { + const [invited, setInvited] = useState<boolean>(false); + 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); + } + }; + + return ( + <TouchableWithoutFeedback> + <View style={styles.container}> + <Text style={styles.label}>{item.firstName + ' ' + item.lastName}</Text> + <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), + backgroundColor: 'thistle', + }, + label: { + fontWeight: '500', + fontSize: normalize(14), + }, + 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..a1030b49 100644 --- a/src/components/profile/Friends.tsx +++ b/src/components/profile/Friends.tsx @@ -1,14 +1,18 @@ -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 {ScrollView, StyleSheet, Text, View} from 'react-native'; +import {checkPermission, getAll} 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 {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 +21,102 @@ 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 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; + }; - const {user: loggedInUser = NO_USER} = state; + 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); + usersFromContacts.map((user) => console.log('user: ', user.username)); + } else if (permission === 'undefined') { + navigation.navigate('RequestContactsAccess'); + } else { + console.log('Go to settings'); + } + }); + }; + 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 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> <ScrollView keyboardShouldPersistTaps={'always'} style={styles.scrollView} @@ -41,7 +131,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 +153,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 +178,18 @@ const styles = StyleSheet.create({ fontWeight: '600', lineHeight: normalize(14.32), }, + friendsSubheaderText: { + alignSelf: 'center', + width: SCREEN_WIDTH * 0.85, + marginVertical: '1%', + marginBottom: '2%', + }, + findFriendsSubheaderText: { + color: '#08E2E2', + fontSize: normalize(12), + fontWeight: '600', + lineHeight: normalize(14.32), + }, container: { alignSelf: 'center', flexDirection: 'row', @@ -94,7 +203,7 @@ const styles = StyleSheet.create({ alignSelf: 'center', height: '100%', }, - button: { + addFriendButton: { alignSelf: 'center', justifyContent: 'center', alignItems: 'center', @@ -104,10 +213,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/constants/api.ts b/src/constants/api.ts index 34ef9a1c..eeac583e 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -33,6 +33,10 @@ export const DISCOVER_ENDPOINT: string = API_URL + 'discover/'; export const SEARCH_BUTTONS_ENDPOPINT: string = DISCOVER_ENDPOINT + 'search_buttons/'; export const WAITLIST_USER_ENDPOINT: string = API_URL + 'waitlist-user/'; export const COMMENT_THREAD_ENDPOINT: string = API_URL + 'reply/'; +export const USERS_FROM_CONTACTS_ENDPOINT: string = + API_URL + 'users-from-contacts/'; +export const INVITE_FRIEND_ENDPOINT: string = +USERS_FROM_CONTACTS_ENDPOINT + 'invite_friend/'; // Suggested People export const SP_USERS_ENDPOINT: string = API_URL + 'suggested_people/'; diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 142249ce..f848a5ab 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -84,6 +84,9 @@ export type MainStackParams = { badge_title: string; badge_img: string; }; + InviteFriendsScreen: { + screenType: ScreenType; + }; }; export const MainStack = createStackNavigator<MainStackParams>(); diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 95d45d32..4f655a64 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -15,6 +15,7 @@ import { EditProfile, FriendsListScreen, IndividualMoment, + InviteFriendsScreen, MomentCommentsScreen, MomentUploadPromptScreen, NotificationsScreen, @@ -221,6 +222,19 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => { }} /> <MainStack.Screen + name="InviteFriendsScreen" + component={InviteFriendsScreen} + initialParams={{screenType}} + options={{ + ...headerBarOptions('black', 'Invites'), + }} + /> + <MainStack.Screen + name="RequestContactsAccess" + component={RequestContactsAccess} + initialParams={{screenType}} + /> + <MainStack.Screen name="EditProfile" component={EditProfile} options={{ diff --git a/src/screens/profile/FriendsListScreen.tsx b/src/screens/profile/FriendsListScreen.tsx index 1cfef058..3016c767 100644 --- a/src/screens/profile/FriendsListScreen.tsx +++ b/src/screens/profile/FriendsListScreen.tsx @@ -1,6 +1,6 @@ import {RouteProp} from '@react-navigation/native'; import React from 'react'; -import {SafeAreaView, StyleSheet, View} from 'react-native'; +import {SafeAreaView, StatusBar, StyleSheet, View} from 'react-native'; import {useSelector} from 'react-redux'; import {Friends, TabsGradient} from '../../components'; import {MainStackParams} from '../../routes'; @@ -25,6 +25,7 @@ const FriendsListScreen: React.FC<FriendsListScreenProps> = ({route}) => { return ( <> <SafeAreaView> + <StatusBar barStyle="dark-content" /> <View style={styles.body}> <Friends result={friends} screenType={screenType} userId={userXId} /> </View> 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; diff --git a/src/screens/profile/index.ts b/src/screens/profile/index.ts index 9d651729..f74946a6 100644 --- a/src/screens/profile/index.ts +++ b/src/screens/profile/index.ts @@ -6,3 +6,4 @@ export {default as MomentCommentsScreen} from './MomentCommentsScreen'; export {default as FriendsListScreen} from './FriendsListScreen'; export {default as EditProfile} from './EditProfile'; export {default as MomentUploadPromptScreen} from './MomentUploadPromptScreen'; +export {default as InviteFriendsScreen} from './InviteFriendsScreen'; diff --git a/src/store/actions/userFriends.ts b/src/store/actions/userFriends.ts index 4f55acc8..9da3cb4a 100644 --- a/src/store/actions/userFriends.ts +++ b/src/store/actions/userFriends.ts @@ -1,4 +1,4 @@ -import {getTokenOrLogout} from '../../utils'; +import {getTokenOrLogout, userXInStore} from '../../utils'; import {RootState} from '../rootReducer'; import { FriendshipStatusType, @@ -90,6 +90,7 @@ export const friendUnfriendUser = ( export const addFriend = ( friend: ProfilePreviewType, // userX's profile preview screenType: ScreenType, //screentype from content + state: RootState, ): ThunkAction< Promise<boolean | undefined>, RootState, @@ -100,14 +101,16 @@ export const addFriend = ( const token = await getTokenOrLogout(dispatch); const success = await addFriendService(friend.id, token); if (success) { - dispatch({ - type: userXFriendshipEdited.type, - payload: { - userId: friend.id, - screenType, - data: 'requested', - }, - }); + if (userXInStore(state, screenType, friend.id)) { + dispatch({ + type: userXFriendshipEdited.type, + payload: { + userId: friend.id, + screen: screenType, + data: 'requested', + }, + }); + } return true; } } catch (error) { diff --git a/src/utils/users.ts b/src/utils/users.ts index af4f3813..82bcb309 100644 --- a/src/utils/users.ts +++ b/src/utils/users.ts @@ -96,7 +96,7 @@ export const userXInStore = ( userId: string, ) => { const userX = state.userX[screen]; - return userId in userX && userX[userId].user.userId; + return userX && userId in userX && userX[userId].user.userId; }; /** |