diff options
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/search/SearchBar.tsx | 78 | ||||
| -rw-r--r-- | src/components/search/SearchResultCell.tsx | 14 | ||||
| -rw-r--r-- | src/components/search/SearchResultList.tsx | 6 | ||||
| -rw-r--r-- | src/components/search/SearchResults.tsx | 34 |
4 files changed, 107 insertions, 25 deletions
diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx index 5e3a1e64..1a855f20 100644 --- a/src/components/search/SearchBar.tsx +++ b/src/components/search/SearchBar.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, {useState, useEffect} from 'react'; import { StyleSheet, TextInput, @@ -13,13 +13,14 @@ import { import Animated, {interpolate} from 'react-native-reanimated'; import Icon from 'react-native-vector-icons/Feather'; import {normalize} from 'react-native-elements'; -import {SCREEN_HEIGHT} from '../../utils'; +import {SCREEN_HEIGHT, getSearchSuggestions} from '../../utils'; const AnimatedIcon = Animated.createAnimatedComponent(Icon); interface SearchBarProps extends TextInputProps { onCancel: () => void; top: Animated.Value<number>; + searching: boolean; } const SearchBar: React.FC<SearchBarProps> = ({ onFocus, @@ -27,6 +28,7 @@ const SearchBar: React.FC<SearchBarProps> = ({ onChangeText, value, onCancel, + searching, top, }) => { const handleSubmit = ( @@ -35,9 +37,76 @@ const SearchBar: React.FC<SearchBarProps> = ({ e.preventDefault(); Keyboard.dismiss(); }; + const DEFAULT_PLACEHOLDER: string = 'Search'; + // the list of suggestions to cycle through. TODO: get this from the backend + const SEARCH_SUGGESTIONS: string[] = getSearchSuggestions(); + /* + * index & id of current placeholder, used in selecting next placeholder. -1 + * indicates DEFAULT_PLACEHOLDER. TODO: make it appear more random by tracking + * last 3-5 ids & use longer list of placeholders + */ + const [placeholderId, setPlaceholderId] = useState<number>(-1); + // the current placeholder + const [placeholder, setPlaceholder] = useState<string>(DEFAULT_PLACEHOLDER); + + /* + * Utility function that generates a random integer in [0, xCeil). + * + * @param xCeil - the exclusive ceiling (getRandomInt(2) => 0 or 1, not 2) + * @returns a random integer in the range [0, xCeil) + */ + const getRandomInt = (xCeil: number): number => { + return Math.floor(Math.random() * Math.floor(xCeil)); + }; + + /* + * Handler for `placeholderChangeInterval` that sets the next placeholderId. + */ + const updatePlaceholder = () => { + let nextId: number = getRandomInt(SEARCH_SUGGESTIONS.length); + while (nextId === placeholderId) { + nextId = getRandomInt(SEARCH_SUGGESTIONS.length); + } + // 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); + }; + + /* + * Update `placeholder` when `placeholderId` is updated by the interval handler. + */ + useEffect(() => { + if (placeholderId === -1) { + setPlaceholder(DEFAULT_PLACEHOLDER); + return; + } + setPlaceholder( + DEFAULT_PLACEHOLDER.concat(` '${SEARCH_SUGGESTIONS[placeholderId]}'`), + ); + }, [placeholderId]); + + /* + * Sets the interval when the user begins searching and clears it when the user is done. + */ + useEffect(() => { + if (!searching) { + return; + } + updatePlaceholder(); + const updateInterval = setInterval(() => { + updatePlaceholder(); + }, 4000); + return () => { + clearInterval(updateInterval); + setPlaceholderId(-1); + }; + }, [searching]); /* - * CSS properties for width change animation. + * Animated nodes used in search bar activation animation. */ const marginRight: Animated.Node<number> = interpolate(top, { inputRange: [-SCREEN_HEIGHT, 0], @@ -59,13 +128,12 @@ const SearchBar: React.FC<SearchBarProps> = ({ /> <TextInput style={[styles.input]} - placeholder={'Search'} placeholderTextColor={'#828282'} onSubmitEditing={handleSubmit} clearButtonMode="while-editing" autoCapitalize="none" autoCorrect={false} - {...{value, onChangeText, onFocus, onBlur}} + {...{placeholder, value, onChangeText, onFocus, onBlur}} /> </Animated.View> <Animated.View style={{marginRight, opacity}}> diff --git a/src/components/search/SearchResultCell.tsx b/src/components/search/SearchResultCell.tsx index e0351d96..9a8216e5 100644 --- a/src/components/search/SearchResultCell.tsx +++ b/src/components/search/SearchResultCell.tsx @@ -7,19 +7,22 @@ import {ERROR_UNABLE_TO_VIEW_PROFILE} from '../../constants/strings'; import {loadImageFromURL} from '../../services'; import {RootState} from '../../store/rootReducer'; import { + CategoryPreviewType, ProfilePreviewType, ScreenType, UserType, - CategoryPreviewType, } from '../../types'; -import {normalize, SCREEN_WIDTH} from '../../utils'; import { - addUserToRecentlyViewed, + addCategoryToRecentlySearched, + addUserToRecentlySearched, + normalize, + SCREEN_WIDTH, +} from '../../utils'; +import { checkIfUserIsBlocked, defaultUserProfile, fetchUserX, userXInStore, - addCategoryToRecentlySearched, } from '../../utils/users'; interface SearchResults { @@ -72,7 +75,7 @@ const SearchResultsCell: React.FC<SearchResults> = ({ return; } - addUserToRecentlyViewed({ + addUserToRecentlySearched({ id, first_name, last_name, @@ -169,6 +172,7 @@ const styles = StyleSheet.create({ flexDirection: 'row', paddingHorizontal: 25, paddingVertical: 15, + width: SCREEN_WIDTH, }, imageContainer: { width: SCREEN_WIDTH * 0.112, diff --git a/src/components/search/SearchResultList.tsx b/src/components/search/SearchResultList.tsx index 704e4192..687b2285 100644 --- a/src/components/search/SearchResultList.tsx +++ b/src/components/search/SearchResultList.tsx @@ -51,7 +51,7 @@ const SearchResultList: React.FC<SearchResultsProps> = ({ {width: SCREEN_WIDTH}, keyboardVisible ? styles.keyboardOpen : {}, ]} - contentContainerStyle={{paddingBottom: SCREEN_HEIGHT * 0.1}} + contentContainerStyle={styles.sectionListContentContainer} sections={results} keyExtractor={(item, index) => item.id + index} renderItem={({section, item}) => { @@ -76,6 +76,10 @@ const styles = StyleSheet.create({ height: SCREEN_HEIGHT, paddingBottom: SCREEN_HEIGHT * 0.1, }, + sectionListContentContainer: { + paddingBottom: SCREEN_HEIGHT * 0.15, + width: SCREEN_WIDTH, + }, sectionHeaderStyle: { width: '100%', height: 0.5, diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx index 277b3454..ef518d8b 100644 --- a/src/components/search/SearchResults.tsx +++ b/src/components/search/SearchResults.tsx @@ -23,20 +23,26 @@ const SearchResults: React.FC<SearchResultsProps> = ({results, categories}) => { const {user: loggedInUser} = useSelector((state: RootState) => state.user); return ( <View> - {categories.map((category: CategoryPreviewType) => ( - <SearchResultsCell - key={category.name} - profileData={category} - {...{loggedInUser}} - /> - ))} - {results.map((profile: ProfilePreviewType) => ( - <SearchResultsCell - key={profile.id} - profileData={profile} - {...{loggedInUser}} - /> - ))} + {categories + .slice(0) + .reverse() + .map((category: CategoryPreviewType) => ( + <SearchResultsCell + key={category.name} + profileData={category} + {...{loggedInUser}} + /> + ))} + {results + .slice(0) + .reverse() + .map((profile: ProfilePreviewType) => ( + <SearchResultsCell + key={profile.id} + profileData={profile} + {...{loggedInUser}} + /> + ))} </View> ); }; |
