From 594de4668248bac9b744e6882329183c95ac339c Mon Sep 17 00:00:00 2001
From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com>
Date: Wed, 10 Mar 2021 18:15:26 -0500
Subject: Add utils, fix ordering of recent searches

---
 src/screens/search/SearchScreen.tsx | 52 ++++++++++++++++---------------------
 1 file changed, 23 insertions(+), 29 deletions(-)

(limited to 'src/screens/search/SearchScreen.tsx')

diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx
index 728510c5..089e0d27 100644
--- a/src/screens/search/SearchScreen.tsx
+++ b/src/screens/search/SearchScreen.tsx
@@ -18,7 +18,13 @@ import {loadSearchResults} from '../../services';
 import {resetScreenType} from '../../store/actions';
 import {RootState} from '../../store/rootReducer';
 import {ProfilePreviewType, ScreenType, CategoryPreviewType} from '../../types';
-import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {
+  normalize,
+  SCREEN_HEIGHT,
+  SCREEN_WIDTH,
+  getRecentlySearchedCategories,
+  getRecentlySearchedUsers,
+} from '../../utils';
 
 /**
  * Search Screen for user recommendations and a search
@@ -58,9 +64,8 @@ const SearchScreen: React.FC = () => {
    */
   useEffect(() => {
     if (!searching) return;
-    if (!query.length) loadRecentSearches();
     if (query.length < 3) {
-      setResults(undefined);
+      loadRecentlySearched().then(() => setResults(undefined));
       return;
     }
     (async () => {
@@ -101,7 +106,9 @@ const SearchScreen: React.FC = () => {
   // when searching state changes, run animation and reset query accordingly
   useEffect(() => {
     if (searching) {
-      timing(top, topInConfig).start();
+      loadRecentlySearched().then(() => {
+        timing(top, topInConfig).start();
+      });
     } else {
       setQuery('');
       handleBlur();
@@ -109,36 +116,23 @@ const SearchScreen: React.FC = () => {
     }
   }, [searching]);
 
-  const loadRecentlySearchedUsers = async () => {
-    try {
-      const asyncCache = await AsyncStorage.getItem('@recently_searched_users');
-      asyncCache != null ? setRecents(JSON.parse(asyncCache)) : setRecents([]);
-    } catch (e) {
-      console.log(e);
-    }
-  };
-  const loadRecentlySearchedCategories = async () => {
-    try {
-      const recentCategoriesJSON = await AsyncStorage.getItem(
-        '@recently_searched_categories',
-      );
-      setRecentCategories(
-        recentCategoriesJSON ? JSON.parse(recentCategoriesJSON) : [],
-      );
-    } catch (e) {
-      console.log(e);
-    }
-  };
-  const loadRecentSearches = () => {
-    loadRecentlySearchedUsers();
-    loadRecentlySearchedCategories();
+  // loads recent searches (users & categories) from AsyncStorage
+  const loadRecentlySearched = async () => {
+    return Promise.all([
+      getRecentlySearchedUsers(),
+      getRecentlySearchedCategories(),
+    ]).then(
+      ([users, categories]: [ProfilePreviewType[], CategoryPreviewType[]]) => {
+        setRecents(users);
+        setRecentCategories(categories);
+      },
+    );
   };
   const clearRecentlySearched = async () => {
     try {
       AsyncStorage.removeItem('@recently_searched_users');
       AsyncStorage.removeItem('@recently_searched_categories');
-      loadRecentlySearchedUsers();
-      loadRecentlySearchedCategories();
+      loadRecentlySearched();
     } catch (e) {
       console.log(e);
     }
-- 
cgit v1.2.3-70-g09d2


From f7557073cc3a5a70b8514c7cb041952d54aa31a1 Mon Sep 17 00:00:00 2001
From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com>
Date: Wed, 10 Mar 2021 19:02:29 -0500
Subject: Add simple, non-animated dynamic placeholder

---
 src/components/search/SearchBar.tsx | 83 +++++++++++++++++++++++++++++++++++--
 src/screens/search/SearchScreen.tsx |  2 +-
 2 files changed, 80 insertions(+), 5 deletions(-)

(limited to 'src/screens/search/SearchScreen.tsx')

diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx
index 5e3a1e64..61d7582f 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,83 @@ 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[] = [
+    "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 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 +135,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}
-- 
cgit v1.2.3-70-g09d2

