diff options
-rw-r--r-- | src/components/profile/ProfilePreview.tsx | 7 | ||||
-rw-r--r-- | src/components/suggestedPeople/MutualFriends.tsx | 1 | ||||
-rw-r--r-- | src/screens/main/NotificationsScreen.tsx | 2 | ||||
-rw-r--r-- | src/screens/profile/ProfileScreen.tsx | 2 | ||||
-rw-r--r-- | src/screens/search/SearchScreen.tsx | 2 | ||||
-rw-r--r-- | src/screens/suggestedPeople/SPBody.tsx | 264 | ||||
-rw-r--r-- | src/screens/suggestedPeople/SuggestedPeopleScreen.tsx | 152 |
7 files changed, 313 insertions, 117 deletions
diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx index 02ab94e7..0021b1c6 100644 --- a/src/components/profile/ProfilePreview.tsx +++ b/src/components/profile/ProfilePreview.tsx @@ -37,12 +37,14 @@ interface ProfilePreviewProps extends ViewProps { profilePreview: ProfilePreviewType; previewType: PreviewType; screenType: ScreenType; + setMFDrawer?: Function; } const ProfilePreview: React.FC<ProfilePreviewProps> = ({ profilePreview: {username, first_name, last_name, id, thumbnail_url}, previewType, screenType, + setMFDrawer, }) => { const navigation = useNavigation(); const {user: loggedInUser} = useSelector((state: RootState) => state.user); @@ -139,6 +141,11 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ ); } + // Close Mutual Friends drawer on suggested people upon navigation + if (setMFDrawer) { + setMFDrawer(false); + } + navigation.push('Profile', { userXId, screenType, diff --git a/src/components/suggestedPeople/MutualFriends.tsx b/src/components/suggestedPeople/MutualFriends.tsx index fdda104a..f72104d4 100644 --- a/src/components/suggestedPeople/MutualFriends.tsx +++ b/src/components/suggestedPeople/MutualFriends.tsx @@ -70,6 +70,7 @@ const MutualFriends: React.FC<MutualFriendsProps> = ({ previewType={'Suggested People Drawer'} screenType={ScreenType.SuggestedPeople} profilePreview={profilePreview} + setMFDrawer={setDrawerVisible} /> ))} </ScrollView> diff --git a/src/screens/main/NotificationsScreen.tsx b/src/screens/main/NotificationsScreen.tsx index 511680ea..aa53c4a9 100644 --- a/src/screens/main/NotificationsScreen.tsx +++ b/src/screens/main/NotificationsScreen.tsx @@ -153,7 +153,7 @@ const NotificationsScreen: React.FC = () => { return ( <SafeAreaView> - <StatusBar barStyle={'dark-content'} /> + <StatusBar barStyle="dark-content" /> <View style={styles.header}> <Text style={styles.headerText}>Notifications</Text> </View> diff --git a/src/screens/profile/ProfileScreen.tsx b/src/screens/profile/ProfileScreen.tsx index 9cdba555..5edc6277 100644 --- a/src/screens/profile/ProfileScreen.tsx +++ b/src/screens/profile/ProfileScreen.tsx @@ -46,7 +46,7 @@ const ProfileScreen: React.FC<ProfileOnboardingProps> = ({route}) => { return ( <> - <StatusBar /> + <StatusBar barStyle="dark-content" /> <Content {...{y, userXId, screenType}} /> <TabsGradient /> </> diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index f0be7c9e..84efa931 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -139,7 +139,7 @@ const SearchScreen: React.FC = () => { return ( <SearchBackground> - <StatusBar /> + <StatusBar barStyle="dark-content" /> <ScrollView scrollEnabled={!searching} keyboardShouldPersistTaps={'always'} diff --git a/src/screens/suggestedPeople/SPBody.tsx b/src/screens/suggestedPeople/SPBody.tsx new file mode 100644 index 00000000..aa97dc94 --- /dev/null +++ b/src/screens/suggestedPeople/SPBody.tsx @@ -0,0 +1,264 @@ +import {useNavigation} from '@react-navigation/native'; +import React, {Fragment, useMemo} from 'react'; +import {StyleSheet, Text, View} from 'react-native'; +import {Image} from 'react-native-animatable'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import Animated from 'react-native-reanimated'; +import RequestedButton from '../../assets/ionicons/requested-button.svg'; +import {TaggsBar} from '../../components'; +import {MutualFriends} from '../../components/suggestedPeople'; +import { + ProfilePreviewType, + ScreenType, + SuggestedPeopleDataType, +} from '../../types'; +import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; + +interface SPBodyProps { + item: SuggestedPeopleDataType; + index: number; + onAddFriend: (user: ProfilePreviewType) => Promise<void>; + onCancelRequest: (user: ProfilePreviewType) => void; + loggedInUserId: string; +} + +const SPBody: React.FC<SPBodyProps> = ({ + item: {user, mutual_friends, social_links, suggested_people_url, friendship}, + index, + onAddFriend, + onCancelRequest, + loggedInUserId, +}) => { + const firstItem = index === 0; + const screenType = ScreenType.SuggestedPeople; + + const displayButton = () => { + switch (friendship.status) { + case 'friends': + return <Fragment />; + case 'requested': + if (friendship.requester_id === loggedInUserId) { + return ( + <TouchableOpacity + style={styles.requestedButton} + onPress={() => onCancelRequest(user)} + disabled={false}> + <RequestedButton + width={SCREEN_WIDTH * 0.3} + height={SCREEN_HEIGHT * 0.085} + /> + </TouchableOpacity> + ); + } else { + return ( + <TouchableOpacity style={styles.addButton} disabled={true}> + <Text style={styles.addButtonTitle}>{'Pending'}</Text> + </TouchableOpacity> + ); + } + case 'no_record': + return ( + <TouchableOpacity + style={styles.addButton} + onPress={() => onAddFriend(user)} + disabled={false}> + <Text style={styles.addButtonTitle}>{'Add Friend'}</Text> + </TouchableOpacity> + ); + default: + return <Fragment />; + } + }; + + const backgroundImage = useMemo( + () => ( + <Image + source={{ + uri: suggested_people_url, + }} + style={styles.image} + /> + ), + [suggested_people_url], + ); + const navigation = useNavigation(); + + return ( + <View> + {backgroundImage} + <View style={styles.mainContainer}> + <Text style={styles.title}>{firstItem && 'Suggested People'}</Text> + <View style={styles.body}> + <View style={styles.marginManager}> + <View style={styles.addUserContainer}> + <TouchableOpacity + onPress={() => { + navigation.push('Profile', { + userXId: user.id, + screenType, + }); + }} + style={styles.nameInfoContainer}> + <Text style={styles.firstName}>{user.first_name}</Text> + <Text style={styles.username}>@{user.username}</Text> + </TouchableOpacity> + {user.id !== loggedInUserId && displayButton()} + </View> + </View> + <TaggsBar + y={Animated.useValue(0)} + userXId={user.id === loggedInUserId ? undefined : user.id} + profileBodyHeight={0} + screenType={screenType} + whiteRing={true} + linkedSocials={social_links} + /> + <View style={styles.marginManager}> + <MutualFriends user={user} friends={mutual_friends} /> + </View> + </View> + </View> + </View> + ); +}; + +const styles = StyleSheet.create({ + mainContainer: { + flexDirection: 'column', + width: SCREEN_WIDTH, + height: SCREEN_HEIGHT, + paddingVertical: '15%', + paddingBottom: '20%', + justifyContent: 'space-between', + alignSelf: 'center', + }, + marginManager: {marginHorizontal: '5%'}, + image: { + position: 'absolute', + width: SCREEN_WIDTH, + height: SCREEN_HEIGHT, + zIndex: 0, + }, + title: { + zIndex: 1, + paddingTop: '3%', + alignSelf: 'center', + fontSize: normalize(22), + lineHeight: normalize(26), + fontWeight: '800', + letterSpacing: normalize(3), + color: '#FFFEFE', + textShadowColor: 'rgba(0, 0, 0, 0.4)', + textShadowOffset: {width: normalize(2), height: normalize(2)}, + textShadowRadius: normalize(2), + }, + firstName: { + color: '#fff', + fontWeight: '800', + fontSize: normalize(24), + lineHeight: normalize(29), + textShadowColor: 'rgba(0, 0, 0, 0.3)', + textShadowOffset: {width: normalize(2), height: normalize(2)}, + textShadowRadius: normalize(2), + letterSpacing: normalize(2.5), + alignSelf: 'baseline', + }, + username: { + color: '#fff', + fontWeight: '600', + fontSize: normalize(15), + lineHeight: normalize(18), + textShadowColor: 'rgba(0, 0, 0, 0.3)', + textShadowOffset: {width: normalize(2), height: normalize(2)}, + textShadowRadius: normalize(2), + letterSpacing: normalize(2), + }, + nameInfoContainer: {}, + addButton: { + justifyContent: 'center', + alignItems: 'center', + width: SCREEN_WIDTH * 0.3, + height: SCREEN_WIDTH * 0.085, + padding: 0, + borderWidth: 2, + borderColor: '#fff', + borderRadius: 1, + marginLeft: '1%', + marginTop: '4%', + shadowColor: 'rgb(0, 0, 0)', + shadowRadius: 2, + shadowOffset: {width: 2, height: 2}, + shadowOpacity: 0.5, + }, + addButtonTitle: { + color: 'white', + padding: 0, + fontSize: normalize(15), + lineHeight: normalize(18), + fontWeight: 'bold', + textAlign: 'center', + letterSpacing: normalize(1), + }, + addUserContainer: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', + marginBottom: '5%', + }, + requestedButton: { + justifyContent: 'center', + alignItems: 'center', + width: SCREEN_WIDTH * 0.3, + height: SCREEN_WIDTH * 0.085, + padding: 0, + borderWidth: 2, + borderColor: 'transparent', + borderRadius: 1, + marginLeft: '1%', + marginTop: '4%', + shadowColor: 'rgb(0, 0, 0)', + shadowRadius: 2, + shadowOffset: {width: 2, height: 2}, + shadowOpacity: 0.5, + }, + requestedButtonTitle: { + backgroundColor: 'transparent', + fontSize: normalize(15), + lineHeight: normalize(18), + fontWeight: 'bold', + textAlign: 'center', + letterSpacing: normalize(1), + }, + body: {}, + + button: { + justifyContent: 'center', + alignItems: 'center', + width: SCREEN_WIDTH * 0.4, + aspectRatio: 154 / 33, + borderWidth: 2, + borderColor: '#fff', + borderRadius: 3, + marginRight: '2%', + marginLeft: '1%', + }, + transparentBG: { + backgroundColor: 'transparent', + }, + lightBlueBG: { + backgroundColor: '#fff', + }, + label: { + fontSize: normalize(15), + fontWeight: '700', + letterSpacing: 1, + }, + blueLabel: { + color: '#fff', + }, + whiteLabel: { + color: 'white', + }, +}); + +export default SPBody; diff --git a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx index c2aab1b5..ec9d2f01 100644 --- a/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx +++ b/src/screens/suggestedPeople/SuggestedPeopleScreen.tsx @@ -6,6 +6,7 @@ import React, { useEffect, useState, useMemo, + useRef, } from 'react'; import { FlatList, @@ -45,7 +46,7 @@ import { SCREEN_WIDTH, } from '../../utils'; import {userXInStore} from './../../utils/'; - +import SPBody from './SPBody'; /** * Bare bones for suggested people consisting of: * * Image, title, name, username, add friend button [w/o functionality] @@ -70,7 +71,7 @@ const SuggestedPeopleScreen: React.FC = () => { const [refreshing, setRefreshing] = useState(false); const [shouldResetData, setShouldResetData] = useState(false); const [hideStatusBar, setHideStatusBar] = useState(false); - + const stausBarRef = useRef(hideStatusBar); // loads data and append it to users based on current page useEffect(() => { loadMore(); @@ -114,6 +115,7 @@ const SuggestedPeopleScreen: React.FC = () => { loadNextPage().then((newUsers) => { loadUserDataToStore(newUsers.map((ppl) => ppl.user)); + setPeople([]); setPeople(shouldResetData ? newUsers : people.concat(newUsers)); setShouldResetData(false); }); @@ -152,11 +154,17 @@ const SuggestedPeopleScreen: React.FC = () => { } }; navigateToAnimatedTutorial(); + StatusBar.setHidden(stausBarRef.current); + StatusBar.setBarStyle('light-content'); + return () => { + StatusBar.setHidden(false); + StatusBar.setBarStyle('dark-content'); + }; }, [navigation, suggested_people_linked]), ); const updateDisplayedUser = async ( - suggested: SuggestedPeopleDataType, + user: ProfilePreviewType, status: FriendshipStatusType, requester_id: string, ) => { @@ -166,136 +174,52 @@ const SuggestedPeopleScreen: React.FC = () => { }; setDisplayedUser(localDisplayedUser); - people.map((item) => { - if (item.user.id === suggested.user.id) { - item.friendship.status = status; - item.friendship.requester_id = requester_id; - } - }); - }; - - const onAddFriend = async (suggested: SuggestedPeopleDataType) => { - handleAddFriend(screenType, suggested.user, dispatch, state); - updateDisplayedUser(suggested, 'requested', loggedInUserId); + setPeople( + people.map((item) => { + if (item.user.id === user.id) { + item.friendship.status = status; + item.friendship.requester_id = requester_id; + } + return item; + }), + ); }; - const onCancelRequest = (suggested: SuggestedPeopleDataType) => { - dispatch(cancelFriendRequest(suggested.user.id)); - updateDisplayedUser(suggested, 'no_record', ''); + const onAddFriend = async (user: ProfilePreviewType) => { + handleAddFriend(screenType, user, dispatch, state); + updateDisplayedUser(user, 'requested', loggedInUserId); }; - const displayButton = (suggested: SuggestedPeopleDataType) => { - setDisplayedUser(suggested); - const friendship: FriendshipType = suggested.friendship; - switch (friendship.status) { - case 'friends': - return <Fragment />; - case 'requested': - if (friendship.requester_id === loggedInUserId) { - return ( - <TouchableOpacity - style={styles.requestedButton} - onPress={() => onCancelRequest(suggested)} - disabled={false}> - <RequestedButton - width={SCREEN_WIDTH * 0.3} - height={SCREEN_HEIGHT * 0.085} - /> - </TouchableOpacity> - ); - } else { - return ( - <TouchableOpacity style={styles.addButton} disabled={true}> - <Text style={styles.addButtonTitle}>{'Pending'}</Text> - </TouchableOpacity> - ); - } - case 'no_record': - return ( - <TouchableOpacity - style={styles.addButton} - onPress={() => onAddFriend(suggested)} - disabled={false}> - <Text style={styles.addButtonTitle}>{'Add Friend'}</Text> - </TouchableOpacity> - ); - default: - return <Fragment />; - } + const onCancelRequest = (user: ProfilePreviewType) => { + dispatch(cancelFriendRequest(user.id)); + updateDisplayedUser(user, 'no_record', ''); }; const onViewableItemsChanged = useCallback( ({viewableItems}: {viewableItems: ViewToken[]}) => { setHideStatusBar(viewableItems[0].index !== 0); + stausBarRef.current = viewableItems[0].index !== 0; }, [], ); - const SPBody = memo( - ({item}: {item: ListRenderItemInfo<SuggestedPeopleDataType>}) => { - const data = item.item; - const firstItem = item.index === 0; - const backgroundImage = useMemo( - () => ( - <Image - source={{ - uri: data.suggested_people_url, - }} - style={styles.image} - /> - ), - [data.suggested_people_url], - ); - return ( - <> - <StatusBar barStyle={'light-content'} hidden={hideStatusBar} /> - {backgroundImage} - <View style={styles.mainContainer}> - <Text style={styles.title}>{firstItem && 'Suggested People'}</Text> - <View style={styles.body}> - <View style={styles.marginManager}> - <View style={styles.addUserContainer}> - <TouchableOpacity - onPress={() => { - navigation.push('Profile', { - userXId: data.user.id, - screenType, - }); - }} - style={styles.nameInfoContainer}> - <Text style={styles.firstName}>{data.user.first_name}</Text> - <Text style={styles.username}>@{data.user.username}</Text> - </TouchableOpacity> - {displayButton(data)} - </View> - </View> - <TaggsBar - y={y} - userXId={ - data.user.id === loggedInUserId ? undefined : data.user.id - } - profileBodyHeight={0} - screenType={screenType} - whiteRing={true} - linkedSocials={data.social_links} - /> - <View style={styles.marginManager}> - <MutualFriends user={data.user} friends={data.mutual_friends} /> - </View> - </View> - </View> - </> - ); - }, - ); - return suggested_people_linked === 0 ? ( <SuggestedPeopleOnboardingStackScreen /> ) : ( <> <FlatList data={people} - renderItem={(item) => <SPBody item={item} />} + renderItem={(item) => { + return ( + <SPBody + index={item.index} + item={item.item} + onAddFriend={onAddFriend} + onCancelRequest={onCancelRequest} + loggedInUserId={loggedInUserId} + /> + ); + }} keyExtractor={(item, index) => index.toString()} showsVerticalScrollIndicator={false} onViewableItemsChanged={onViewableItemsChanged} |