diff options
author | Leon Jiang <35908040+leonyjiang@users.noreply.github.com> | 2021-03-10 19:02:29 -0500 |
---|---|---|
committer | Leon Jiang <35908040+leonyjiang@users.noreply.github.com> | 2021-03-10 19:02:29 -0500 |
commit | 5fdfc0b83e7ccdb75d047d13691fc70753a875af (patch) | |
tree | 7189080052bcc91a24171a4d2b13ef781227ad9b /src | |
parent | 594de4668248bac9b744e6882329183c95ac339c (diff) |
Add simple, non-animated dynamic placeholder
Diffstat (limited to 'src')
-rw-r--r-- | src/components/search/SearchBar.tsx | 79 | ||||
-rw-r--r-- | src/screens/search/SearchScreen.tsx | 2 |
2 files changed, 76 insertions, 5 deletions
diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx index 5e3a1e64..c0c228fe 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, @@ -20,6 +20,7 @@ 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,79 @@ const SearchBar: React.FC<SearchBarProps> = ({ e.preventDefault(); Keyboard.dismiss(); }; + // the search bar's default placeholder + const DEFAULT_PLACEHOLDER: string = 'Search'; + // the list of suggestions to cycle through. TODO: get this from the backend + const PLACEHOLDERS: string[] = [ + "Brown '21", + "Brown '22", + "Brown '23", + "Brown '24", + 'Trending on Tagg', + 'New to Tagg', + ]; + /* + * index & id of current placeholder, used in selecting next placeholder. -1 + * indicates no suggestion, i.e. DEFAULT_PLACEHOLDER. TODO: make it seem more + * random by tracking last 3-5 ids + */ + const [placeholderId, setPlaceholderId] = useState<number>(-1); + /* + * the current placeholder, i.e. DEFAULT_PLACEHOLDER.concat(` ${PLACEHOLDERS[placeholderId]}`) + */ + 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 nextPlaceholderId = getRandomInt(PLACEHOLDERS.length); + while (nextPlaceholderId === placeholderId) { + nextPlaceholderId = getRandomInt(PLACEHOLDERS.length); + } + setPlaceholderId(nextPlaceholderId); + }; + + /* + * Update `placeholder` when `placeholderId` is updated by the interval handler. + */ + useEffect(() => { + if (placeholderId === -1) { + setPlaceholder(DEFAULT_PLACEHOLDER); + return; + } + setPlaceholder( + DEFAULT_PLACEHOLDER.concat(` '${PLACEHOLDERS[placeholderId]}'`), + ); + }, [placeholderId]); + + /* + * Sets the interval when the user begins searching and clears it when the user is done. + */ + useEffect(() => { + if (!searching) return; + updatePlaceholder(); + const placeholderChangeInterval = setInterval(() => { + updatePlaceholder(); + }, 4500); + return () => { + clearInterval(placeholderChangeInterval); + 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 +131,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/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx index 089e0d27..59b17f57 100644 --- a/src/screens/search/SearchScreen.tsx +++ b/src/screens/search/SearchScreen.tsx @@ -167,7 +167,7 @@ const SearchScreen: React.FC = () => { onBlur={handleBlur} onFocus={handleFocus} value={query} - {...{top}} + {...{top, searching}} /> <ScrollView scrollEnabled={!searching} |