diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/common/Avatar.tsx | 1 | ||||
-rw-r--r-- | src/components/common/TaggRadioButton.tsx | 48 | ||||
-rw-r--r-- | src/components/common/TaggUserSelectionCell.tsx | 73 | ||||
-rw-r--r-- | src/components/common/index.ts | 1 | ||||
-rw-r--r-- | src/components/profile/ProfilePreview.tsx | 44 | ||||
-rw-r--r-- | src/components/search/SearchBar.tsx | 24 | ||||
-rw-r--r-- | src/constants/index.ts | 1 | ||||
-rw-r--r-- | src/routes/main/MainStackNavigator.tsx | 5 | ||||
-rw-r--r-- | src/routes/main/MainStackScreen.tsx | 8 | ||||
-rw-r--r-- | src/screens/chat/ChatSearchBar.tsx | 14 | ||||
-rw-r--r-- | src/screens/chat/NewChatModal.tsx | 1 | ||||
-rw-r--r-- | src/screens/index.ts | 1 | ||||
-rw-r--r-- | src/screens/moments/TagSelectionScreen.tsx | 181 | ||||
-rw-r--r-- | src/screens/moments/index.ts | 1 | ||||
-rw-r--r-- | src/screens/profile/CaptionScreen.tsx | 47 | ||||
-rw-r--r-- | src/screens/profile/InviteFriendsScreen.tsx | 93 | ||||
-rw-r--r-- | src/types/types.ts | 3 | ||||
-rw-r--r-- | src/utils/search.ts | 13 |
18 files changed, 477 insertions, 82 deletions
diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx index fa80f121..29197d6e 100644 --- a/src/components/common/Avatar.tsx +++ b/src/components/common/Avatar.tsx @@ -16,6 +16,7 @@ const Avatar: FC<AvatarProps> = ({ return loading ? ( <ImageBackground style={style} + imageStyle={style} defaultSource={require('../../assets/images/avatar-placeholder.png')} source={{uri, cache: 'reload'}}> {loading && ( diff --git a/src/components/common/TaggRadioButton.tsx b/src/components/common/TaggRadioButton.tsx new file mode 100644 index 00000000..fc4008e5 --- /dev/null +++ b/src/components/common/TaggRadioButton.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {StyleSheet, TouchableOpacity, View} from 'react-native'; + +interface TaggRadioButtonProps { + pressed: boolean; + onPress: Function; +} +const TaggRadioButton: React.FC<TaggRadioButtonProps> = ({ + pressed, + onPress, +}) => { + const activeOuterStyle = { + borderColor: pressed ? '#6EE7E7' : '#BEBEBE', + }; + + const activeInnerStyle = { + backgroundColor: pressed ? '#6EE7E7' : 'white', + }; + return ( + <TouchableOpacity + style={[styles.outer, activeOuterStyle]} + onPress={() => { + onPress(); + }}> + {pressed && <View style={[styles.inner, activeInnerStyle]} />} + </TouchableOpacity> + ); +}; + +export default TaggRadioButton; +const styles = StyleSheet.create({ + outer: { + width: 20, + height: 20, + borderWidth: 1.5, + borderRadius: 20, + + backgroundColor: 'white', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, + inner: { + width: 14, + height: 14, + borderRadius: 8, + }, +}); diff --git a/src/components/common/TaggUserSelectionCell.tsx b/src/components/common/TaggUserSelectionCell.tsx new file mode 100644 index 00000000..01d965cf --- /dev/null +++ b/src/components/common/TaggUserSelectionCell.tsx @@ -0,0 +1,73 @@ +import React, {useEffect, useState} from 'react'; +import {StyleSheet, View} from 'react-native'; +import {ProfilePreview} from '..'; +import {ProfilePreviewType, ScreenType} from '../../types'; +import {SCREEN_WIDTH} from '../../utils'; +import TaggRadioButton from './TaggRadioButton'; + +interface TaggUserSelectionCellProps { + item: ProfilePreviewType; + selectedUsers: ProfilePreviewType[]; + setSelectedUsers: Function; +} +const TaggUserSelectionCell: React.FC<TaggUserSelectionCellProps> = ({ + item, + selectedUsers, + setSelectedUsers, +}) => { + const [pressed, setPressed] = useState<boolean>(false); + + /* + * To update state of radio button on initial render and subsequent re-renders + */ + useEffect(() => { + const updatePressed = () => { + const userSelected = selectedUsers.findIndex( + (selectedUser) => item.id === selectedUser.id, + ); + setPressed(userSelected !== -1); + }; + updatePressed(); + }); + + /* + * Handles on press on radio button + * Adds/removes user from selected list of users + */ + const handlePress = () => { + // Add to selected list of users + if (pressed === false) { + setSelectedUsers([...selectedUsers, item]); + } + // Remove item from selected list of users + else { + const filteredSelection = selectedUsers.filter( + (user) => user.id !== item.id, + ); + setSelectedUsers(filteredSelection); + } + }; + return ( + <View style={styles.container}> + <View style={{width: SCREEN_WIDTH * 0.8}}> + <ProfilePreview + profilePreview={item} + previewType={'Search'} + screenType={ScreenType.Profile} + /> + </View> + <TaggRadioButton pressed={pressed} onPress={handlePress} /> + </View> + ); +}; + +export default TaggUserSelectionCell; + +const styles = StyleSheet.create({ + container: { + marginHorizontal: '3%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, +}); diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 48abb8b8..44edbe5f 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -27,3 +27,4 @@ export {default as Avatar} from './Avatar'; export {default as TaggTypeahead} from './TaggTypeahead'; export {default as TaggUserRowCell} from './TaggUserRowCell'; export {default as LikeButton} from './LikeButton'; +export {default as TaggUserSelectionCell} from './TaggUserSelectionCell'; diff --git a/src/components/profile/ProfilePreview.tsx b/src/components/profile/ProfilePreview.tsx index 66d68d8f..af49c6a2 100644 --- a/src/components/profile/ProfilePreview.tsx +++ b/src/components/profile/ProfilePreview.tsx @@ -148,6 +148,14 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ usernameStyle = styles.discoverUsersUsername; nameStyle = styles.discoverUsersName; break; + case 'Tag Selection': + containerStyle = styles.tagSelectionContainer; + avatarStyle = styles.tagSelectionAvatar; + nameContainerStyle = styles.tagSelectionNameContainer; + usernameToDisplay = '@' + username; + usernameStyle = styles.tagSelectionUsername; + nameStyle = styles.tagSelectionName; + break; case 'Comment': containerStyle = styles.commentContainer; avatarStyle = styles.commentAvatar; @@ -195,10 +203,9 @@ const ProfilePreview: React.FC<ProfilePreviewProps> = ({ <Text style={nameStyle}>{first_name.concat(' ', last_name)}</Text> </> )} - {previewType === 'Comment' && ( - <Text style={usernameStyle}>{usernameToDisplay}</Text> - )} - {previewType === 'Discover Users' && ( + {(previewType === 'Discover Users' || + previewType === 'Tag Selection' || + previewType === 'Comment') && ( <> <Text style={usernameStyle}>{usernameToDisplay}</Text> </> @@ -368,6 +375,35 @@ const styles = StyleSheet.create({ marginRight: 15, borderRadius: 50, }, + tagSelectionContainer: { + width: 60, + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'flex-start', + margin: '1%', + }, + tagSelectionAvatar: { + width: 34, + height: 34, + borderRadius: 20, + }, + tagSelectionNameContainer: { + width: '100%', + paddingVertical: '5%', + }, + tagSelectionUsername: { + fontWeight: '500', + fontSize: normalize(9), + lineHeight: normalize(10), + letterSpacing: normalize(0.2), + color: 'white', + textAlign: 'center', + }, + tagSelectionName: { + fontWeight: '500', + fontSize: 8, + color: 'white', + }, }); export default ProfilePreview; diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx index 25ea3b59..a17d0695 100644 --- a/src/components/search/SearchBar.tsx +++ b/src/components/search/SearchBar.tsx @@ -21,10 +21,10 @@ import {getSearchSuggestions, normalize} from '../../utils'; const AnimatedIcon = Animated.createAnimatedComponent(Icon); interface SearchBarProps extends TextInputProps { - onCancel: () => void; - animationProgress: Animated.SharedValue<number>; - searching: boolean; - onLayout: (e: LayoutChangeEvent) => void; + onCancel?: () => void; + animationProgress?: Animated.SharedValue<number>; + searching?: boolean; + onLayout?: (e: LayoutChangeEvent) => void; } const SearchBar: React.FC<SearchBarProps> = ({ onFocus, @@ -113,8 +113,8 @@ const SearchBar: React.FC<SearchBarProps> = ({ * On-search marginRight style ("cancel" button slides and fades in). */ const animatedStyles = useAnimatedStyle<ViewStyle>(() => ({ - marginRight: animationProgress.value * 58, - opacity: animationProgress.value, + marginRight: (animationProgress ? animationProgress.value : 0) * 58, + opacity: animationProgress ? animationProgress.value : 0, })); return ( @@ -136,11 +136,13 @@ const SearchBar: React.FC<SearchBarProps> = ({ {...{placeholder, value, onChangeText, onFocus, onBlur}} /> </Animated.View> - <Animated.View style={animatedStyles}> - <TouchableOpacity style={styles.cancelButton} onPress={onCancel}> - <Text style={styles.cancelText}>Cancel</Text> - </TouchableOpacity> - </Animated.View> + {onCancel && ( + <Animated.View style={animatedStyles}> + <TouchableOpacity style={styles.cancelButton} onPress={onCancel}> + <Text style={styles.cancelText}>Cancel</Text> + </TouchableOpacity> + </Animated.View> + )} </View> ); }; diff --git a/src/constants/index.ts b/src/constants/index.ts index a9cfe947..96ed3fb0 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,3 +1,4 @@ export * from './api'; export * from './constants'; export * from './regex'; +export * from './badges'; diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 8f2192f1..054fb643 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -6,6 +6,7 @@ import {Image} from 'react-native-image-crop-picker'; import { CommentBaseType, MomentType, + ProfilePreviewType, ScreenType, SearchCategoryType, } from '../../types'; @@ -39,6 +40,7 @@ export type MainStackParams = { title: string; image: Image; screenType: ScreenType; + selectedUsers?: ProfilePreviewType[]; }; IndividualMoment: { moment: MomentType; @@ -97,6 +99,9 @@ export type MainStackParams = { ChatList: undefined; Chat: undefined; NewChatModal: undefined; + TagSelectionScreen: { + selectedUsers: ProfilePreviewType[]; + }; }; export const MainStack = createStackNavigator<MainStackParams>(); diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index d76f9137..61491641 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -32,6 +32,7 @@ import { SuggestedPeopleScreen, SuggestedPeopleUploadPictureScreen, SuggestedPeopleWelcomeScreen, + TagSelectionScreen, } from '../../screens'; import MutualBadgeHolders from '../../screens/suggestedPeople/MutualBadgeHolders'; import {ScreenType} from '../../types'; @@ -310,6 +311,13 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => { component={NewChatModal} options={{headerShown: false, ...newChatModalStyle}} /> + <MainStack.Screen + name="TagSelectionScreen" + component={TagSelectionScreen} + options={{ + ...headerBarOptions('black', ''), + }} + /> </MainStack.Navigator> ); }; diff --git a/src/screens/chat/ChatSearchBar.tsx b/src/screens/chat/ChatSearchBar.tsx index 91018d4c..1c91f493 100644 --- a/src/screens/chat/ChatSearchBar.tsx +++ b/src/screens/chat/ChatSearchBar.tsx @@ -17,6 +17,7 @@ interface SearchBarProps extends TextInputProps { onCancel: () => void; searching: boolean; placeholder: string; + label?: string; } const ChatSearchBar: React.FC<SearchBarProps> = ({ onFocus, @@ -26,6 +27,7 @@ const ChatSearchBar: React.FC<SearchBarProps> = ({ onCancel, onLayout, placeholder, + label, }) => { const handleSubmit = ( e: NativeSyntheticEvent<TextInputSubmitEditingEventData>, @@ -34,14 +36,18 @@ const ChatSearchBar: React.FC<SearchBarProps> = ({ Keyboard.dismiss(); }; + const extraLabelStyle = {paddingLeft: label ? 0 : 10}; + return ( <View style={styles.container} onLayout={onLayout}> <Animated.View style={styles.inputContainer}> - <Animated.View style={styles.searchTextContainer}> - <Text style={styles.searchTextStyes}>To:</Text> - </Animated.View> + {label && ( + <Animated.View style={styles.searchTextContainer}> + <Text style={styles.searchTextStyes}>{label}</Text> + </Animated.View> + )} <TextInput - style={styles.input} + style={[extraLabelStyle, styles.input]} placeholderTextColor={'#828282'} onSubmitEditing={handleSubmit} clearButtonMode="always" diff --git a/src/screens/chat/NewChatModal.tsx b/src/screens/chat/NewChatModal.tsx index 9872dd6f..e57e7f7a 100644 --- a/src/screens/chat/NewChatModal.tsx +++ b/src/screens/chat/NewChatModal.tsx @@ -98,6 +98,7 @@ const NewChatModal: React.FC<NewChatModalProps> = ({ value={query} searching={searching} placeholder={''} + label={'To:'} /> {results.length > 0 && ( <View style={styles.headerContainerStyles}> diff --git a/src/screens/index.ts b/src/screens/index.ts index 44ae4b52..0c7d911f 100644 --- a/src/screens/index.ts +++ b/src/screens/index.ts @@ -6,3 +6,4 @@ export * from './suggestedPeople'; export * from './suggestedPeopleOnboarding'; export * from './badge'; export * from './chat'; +export * from './moments'; diff --git a/src/screens/moments/TagSelectionScreen.tsx b/src/screens/moments/TagSelectionScreen.tsx new file mode 100644 index 00000000..d68447f8 --- /dev/null +++ b/src/screens/moments/TagSelectionScreen.tsx @@ -0,0 +1,181 @@ +import {useNavigation} from '@react-navigation/core'; +import {RouteProp} from '@react-navigation/native'; +import React, {useEffect, useState} from 'react'; +import { + SafeAreaView, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import {FlatList} from 'react-native-gesture-handler'; +import BackIcon from '../../assets/icons/back-arrow.svg'; +import {SearchBar, TaggUserSelectionCell} from '../../components'; +import {SEARCH_ENDPOINT_MESSAGES} from '../../constants'; +import {MainStackParams} from '../../routes'; +import {loadSearchResults} from '../../services'; +import {ProfilePreviewType} from '../../types'; +import { + loadTaggUserSuggestions, + normalize, + SCREEN_HEIGHT, + SCREEN_WIDTH, +} from '../../utils'; + +type TagSelectionScreenRouteProps = RouteProp< + MainStackParams, + 'TagSelectionScreen' +>; +interface TagSelectionScreenProps { + route: TagSelectionScreenRouteProps; +} + +const TagSelectionScreen: React.FC<TagSelectionScreenProps> = ({route}) => { + const navigation = useNavigation(); + const [users, setUsers] = useState<ProfilePreviewType[]>([]); + const [selectedUsers, setSelectedUsers] = useState<ProfilePreviewType[]>( + route.params.selectedUsers, + ); + const [searching, setSearching] = useState(false); + const [query, setQuery] = useState<string>(''); + const [label, setLabel] = useState<string>('Recent'); + + /* + * Add back button, Send selected users to CaptionScreen + */ + useEffect(() => { + navigation.setOptions({ + headerLeft: () => ( + <TouchableOpacity + onPress={() => { + if (selectedUsers.length > 0) { + navigation.navigate('CaptionScreen', { + ...route.params, + selectedUsers: selectedUsers, + }); + } else { + navigation.goBack(); + } + }}> + <BackIcon + height={normalize(18)} + width={normalize(18)} + color={'black'} + style={styles.backButton} + /> + </TouchableOpacity> + ), + }); + }); + + /* + * Load the initial list users from search/suggested endpoint + * that the loggedInUser might want to select + */ + const loadUsers = async () => { + const data: ProfilePreviewType[] = await loadTaggUserSuggestions(); + const filteredData: ProfilePreviewType[] = data.filter((user) => { + const index = selectedUsers.findIndex((s) => s.id === user.id); + return index === -1; + }); + setUsers([...filteredData, ...selectedUsers]); + }; + + /* + * Load list of users based on search query + */ + const getQuerySuggested = async () => { + if (query.length > 0) { + const searchResults = await loadSearchResults( + `${SEARCH_ENDPOINT_MESSAGES}?query=${query}`, + ); + setUsers(searchResults?.users); + } else { + setUsers([]); + } + }; + + /* + * Make calls to appropriate functions to load user lists for selection + */ + useEffect(() => { + if (query.length === 0) { + setLabel('Recent'); + loadUsers(); + } + + if (!searching) { + return; + } + + if (query.length < 3) { + return; + } + setLabel(''); + getQuerySuggested(); + }, [query]); + + return ( + <SafeAreaView style={styles.safeAreaView}> + <View style={styles.searchBarContainer}> + <SearchBar + onChangeText={setQuery} + onFocus={() => { + setSearching(true); + }} + value={query} + /> + </View> + <Text style={styles.title}>{label}</Text> + {users && ( + <FlatList + data={users} + keyExtractor={(item) => item.id} + renderItem={(item) => ( + <TaggUserSelectionCell + item={item.item} + selectedUsers={selectedUsers} + setSelectedUsers={setSelectedUsers} + /> + )} + /> + )} + </SafeAreaView> + ); +}; + +export default TagSelectionScreen; + +const styles = StyleSheet.create({ + safeAreaView: { + backgroundColor: 'white', + height: SCREEN_HEIGHT, + }, + backButton: { + marginLeft: 30, + marginTop: 20, + }, + searchBarContainer: { + width: SCREEN_WIDTH * 0.9, + alignSelf: 'flex-end', + marginTop: 10, + }, + searchContainer: { + alignSelf: 'center', + flexDirection: 'row', + justifyContent: 'space-between', + width: '100%', + height: normalize(42), + alignItems: 'center', + marginBottom: '3%', + marginHorizontal: 10, + }, + title: { + fontWeight: '700', + fontSize: normalize(17), + lineHeight: normalize(20.29), + marginHorizontal: '7%', + marginTop: '4%', + marginBottom: '2%', + }, +}); diff --git a/src/screens/moments/index.ts b/src/screens/moments/index.ts new file mode 100644 index 00000000..3cdd3128 --- /dev/null +++ b/src/screens/moments/index.ts @@ -0,0 +1 @@ +export {default as TagSelectionScreen} from './TagSelectionScreen'; diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx index a41abba6..146ad86c 100644 --- a/src/screens/profile/CaptionScreen.tsx +++ b/src/screens/profile/CaptionScreen.tsx @@ -1,6 +1,6 @@ import {RouteProp} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; -import React, {Fragment, useState} from 'react'; +import React, {Fragment, useEffect, useState} from 'react'; import { Alert, Image, @@ -8,13 +8,15 @@ import { KeyboardAvoidingView, Platform, StyleSheet, + Text, + TouchableOpacity, TouchableWithoutFeedback, View, } from 'react-native'; import {MentionInput} from 'react-native-controlled-mentions'; -import {Button} from 'react-native-elements'; +import {Button, normalize} from 'react-native-elements'; import {useDispatch, useSelector} from 'react-redux'; -import {SearchBackground} from '../../components'; +import {ProfilePreview, SearchBackground} from '../../components'; import {CaptionScreenHeader} from '../../components/'; import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator'; import {TAGG_LIGHT_BLUE_2} from '../../constants'; @@ -26,6 +28,7 @@ import { updateProfileCompletionStage, } from '../../store/actions'; import {RootState} from '../../store/rootReducer'; +import {ProfilePreviewType, ScreenType} from '../../types'; import {SCREEN_WIDTH, StatusBarHeight} from '../../utils'; import {mentionPartTypes} from '../../utils/comments'; @@ -43,13 +46,18 @@ interface CaptionScreenProps { } const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { - const {title, image, screenType} = route.params; + const {title, image, screenType, selectedUsers} = route.params; const { user: {userId}, } = useSelector((state: RootState) => state.user); const dispatch = useDispatch(); const [caption, setCaption] = useState(''); const [loading, setLoading] = useState(false); + const [taggedUsers, setTaggedUsers] = useState<ProfilePreviewType[]>([]); + + useEffect(() => { + setTaggedUsers(selectedUsers ? selectedUsers : []); + }, [route.params]); const navigateToProfile = () => { //Since the logged In User is navigating to own profile, useXId is not required @@ -118,6 +126,29 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => { onChange={setCaption} partTypes={mentionPartTypes('blue')} /> + <View style={{marginHorizontal: '5%', marginTop: '3%'}}> + <TouchableOpacity + style={{width: SCREEN_WIDTH}} + onPress={() => + navigation.navigate('TagSelectionScreen', { + selectedUsers: taggedUsers, + }) + }> + <Text style={styles.tagFriendsTitle}>Tag Friends</Text> + </TouchableOpacity> + <View style={styles.tagFriendsContainer}> + {taggedUsers.map((user) => ( + <View> + {/* TODO: Add Icon for Tag Friends */} + <ProfilePreview + profilePreview={user} + previewType={'Tag Selection'} + screenType={ScreenType.Profile} + /> + </View> + ))} + </View> + </View> </View> </KeyboardAvoidingView> </TouchableWithoutFeedback> @@ -162,6 +193,14 @@ const styles = StyleSheet.create({ flex: { flex: 1, }, + tagFriendsTitle: { + color: 'white', + fontSize: normalize(12), + lineHeight: normalize(16.71), + letterSpacing: normalize(0.3), + fontWeight: '600', + }, + tagFriendsContainer: {flexDirection: 'row', marginTop: '3%'}, }); export default CaptionScreen; diff --git a/src/screens/profile/InviteFriendsScreen.tsx b/src/screens/profile/InviteFriendsScreen.tsx index 4f6319f7..89f2e62f 100644 --- a/src/screens/profile/InviteFriendsScreen.tsx +++ b/src/screens/profile/InviteFriendsScreen.tsx @@ -9,14 +9,12 @@ import { StatusBar, StyleSheet, Text, - TextInput, TouchableWithoutFeedback, View, } from 'react-native'; import {checkPermission} from 'react-native-contacts'; -import Animated from 'react-native-reanimated'; -import Icon from 'react-native-vector-icons/Feather'; -import {TabsGradient} from '../../components'; +import {TAGG_LIGHT_BLUE} from '../../constants'; +import {SearchBar, TabsGradient} from '../../components'; import {InviteFriendTile} from '../../components/friends'; import {headerBarOptions} from '../../routes'; import { @@ -33,7 +31,6 @@ import { SCREEN_WIDTH, StatusBarHeight, } from '../../utils'; -const AnimatedIcon = Animated.createAnimatedComponent(Icon); export type InviteContactType = { firstName: string; @@ -193,32 +190,13 @@ const InviteFriendsScreen: React.FC = () => { </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.toLowerCase()); - }} - onBlur={() => { - Keyboard.dismiss(); - }} - onEndEditing={() => { - Keyboard.dismiss(); - }} - value={query} - placeholder={'Search'} - /> - </Animated.View> + <SearchBar + onChangeText={setQuery} + onBlur={() => { + Keyboard.dismiss(); + }} + value={query} + /> </View> <View style={[ @@ -278,43 +256,44 @@ const styles = StyleSheet.create({ marginBottom: '5%', }, container: { + width: '100%', + height: normalize(42), + marginBottom: '3%', + }, + ppContainer: { alignSelf: 'center', flexDirection: 'row', justifyContent: 'space-between', width: '100%', height: normalize(42), alignItems: 'center', - marginBottom: '3%', + 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: { + friend: { + alignSelf: 'center', height: '100%', - position: 'absolute', + }, + addFriendButton: { + alignSelf: 'center', justifyContent: 'center', - paddingHorizontal: 8, + alignItems: 'center', + width: 82, + height: 25, + borderColor: TAGG_LIGHT_BLUE, + borderWidth: 2, + borderRadius: 2, + padding: 0, + backgroundColor: TAGG_LIGHT_BLUE, }, - cancelText: { - color: '#818181', - fontWeight: '500', + addFriendButtonTitle: { + color: 'white', + padding: 0, + fontSize: normalize(11), + fontWeight: '700', + lineHeight: normalize(13.13), + letterSpacing: normalize(0.6), + paddingHorizontal: '3.8%', }, }); diff --git a/src/types/types.ts b/src/types/types.ts index e9975529..7bf5597f 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -142,7 +142,8 @@ export type PreviewType = | 'Discover Users' | 'Friend' | 'Suggested People Drawer' - | 'Suggested People Screen'; + | 'Suggested People Screen' + | 'Tag Selection'; export enum ScreenType { Profile, diff --git a/src/utils/search.ts b/src/utils/search.ts index 26f40b1b..789acbc3 100644 --- a/src/utils/search.ts +++ b/src/utils/search.ts @@ -1,6 +1,7 @@ import AsyncStorage from '@react-native-community/async-storage'; +import {loadSearchResults} from '../services'; -import {BADGE_DATA} from '../constants/badges'; +import {BADGE_DATA, SEARCH_ENDPOINT_SUGGESTED} from '../constants'; import { ProfilePreviewType, CategoryPreviewType, @@ -138,3 +139,13 @@ export const getRecentlySearchedCategories = async (): Promise< } return []; }; + +/* + * Retrieves and returns a list of suggested tagg users + */ +export const loadTaggUserSuggestions = async (): Promise< + ProfilePreviewType[] +> => { + const searchResults = await loadSearchResults(`${SEARCH_ENDPOINT_SUGGESTED}`); + return searchResults?.users; +}; |