From 268c93e705e3d3808ab5353497354f390230d29d Mon Sep 17 00:00:00 2001
From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com>
Date: Sat, 3 Apr 2021 15:29:56 -0400
Subject: Fix search bar animation & search screen styles

---
 src/screens/search/SearchScreen.tsx | 180 +++++++++++-------------------------
 1 file changed, 55 insertions(+), 125 deletions(-)

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

diff --git a/src/screens/search/SearchScreen.tsx b/src/screens/search/SearchScreen.tsx
index 4f0cabb4..f7e1c467 100644
--- a/src/screens/search/SearchScreen.tsx
+++ b/src/screens/search/SearchScreen.tsx
@@ -1,8 +1,19 @@
 import AsyncStorage from '@react-native-community/async-storage';
 import {useFocusEffect} from '@react-navigation/native';
 import React, {useEffect, useState} from 'react';
-import {Keyboard, ScrollView, StatusBar, StyleSheet} from 'react-native';
-import Animated, {Easing, timing} from 'react-native-reanimated';
+import {
+  Keyboard,
+  StatusBar,
+  StyleSheet,
+  LayoutChangeEvent,
+  SectionListData,
+} from 'react-native';
+import {
+  useSharedValue,
+  withTiming,
+  Easing,
+  runOnJS,
+} from 'react-native-reanimated';
 import {SafeAreaView} from 'react-native-safe-area-context';
 import {useDispatch, useSelector} from 'react-redux';
 import {
@@ -13,22 +24,14 @@ import {
   SearchResultsBackground,
   TabsGradient,
 } from '../../components';
-import {SEARCH_ENDPOINT, TAGG_LIGHT_BLUE} from '../../constants';
+import {SEARCH_ENDPOINT} from '../../constants';
 import {loadSearchResults} from '../../services';
 import {resetScreenType} from '../../store/actions';
 import {RootState} from '../../store/rootReducer';
-import {
-  CategoryPreviewType,
-  ProfilePreviewType,
-  ScreenType,
-  SearchCategoryType,
-} from '../../types';
+import {CategoryPreviewType, ProfilePreviewType, ScreenType} from '../../types';
 import {
   getRecentlySearchedCategories,
   getRecentlySearchedUsers,
-  normalize,
-  SCREEN_HEIGHT,
-  SCREEN_WIDTH,
 } from '../../utils';
 
 /**
@@ -38,11 +41,8 @@ import {
 
 const SearchScreen: React.FC = () => {
   const {recentSearches} = useSelector((state: RootState) => state.taggUsers);
-  const {
-    profile: {university = ''},
-  } = useSelector((state: RootState) => state.user);
   const [query, setQuery] = useState<string>('');
-  const [results, setResults] = useState<Array<any> | undefined>(undefined);
+  const [results, setResults] = useState<SectionListData<any>[] | undefined>();
   const [recents, setRecents] = useState<Array<ProfilePreviewType>>(
     recentSearches ?? [],
   );
@@ -50,26 +50,12 @@ const SearchScreen: React.FC = () => {
     CategoryPreviewType[]
   >([]);
   const [searching, setSearching] = useState(false);
-  const top = Animated.useValue(-SCREEN_HEIGHT);
-  const defaultButtons: SearchCategoryType[] = [21, 22, 23, 24].map((year) => ({
-    id: -1,
-    name: `${university.split(' ')[0]} '${year}`,
-    category: university,
-  }));
-  const [keyboardVisible, setKeyboardVisible] = React.useState(
-    'keyboardVisible',
-  );
-  useEffect(() => {
-    const showKeyboard = () => setKeyboardVisible('keyboardVisibleTrue');
-    Keyboard.addListener('keyboardWillShow', showKeyboard);
-    return () => Keyboard.removeListener('keyboardWillShow', showKeyboard);
-  }, []);
+  /*
+   * Animated value
+   */
+  const animationProgress = useSharedValue<number>(0);
+  const [searchBarHeight, setSearchBarHeight] = useState<number>(0);
 
-  useEffect(() => {
-    const hideKeyboard = () => setKeyboardVisible('keyboardVisibleFalse');
-    Keyboard.addListener('keyboardWillHide', hideKeyboard);
-    return () => Keyboard.removeListener('keyboardWillHide', hideKeyboard);
-  }, []);
   const dispatch = useDispatch();
 
   /*
@@ -122,12 +108,22 @@ const SearchScreen: React.FC = () => {
   useEffect(() => {
     if (searching) {
       loadRecentlySearched().then(() => {
-        timing(top, topInConfig).start();
+        animationProgress.value = withTiming(1, {
+          duration: 180,
+          easing: Easing.bezier(0.31, 0.14, 0.66, 0.82),
+        });
       });
     } else {
       setQuery('');
       handleBlur();
-      timing(top, topOutConfig).start(() => setResults(undefined));
+      animationProgress.value = withTiming(
+        0,
+        {duration: 180, easing: Easing.inOut(Easing.ease)},
+        () => {
+          'worklet';
+          runOnJS(setResults)(undefined);
+        },
+      );
     }
   }, [searching]);
 
@@ -153,16 +149,6 @@ const SearchScreen: React.FC = () => {
     }
   };
 
-  const topInConfig = {
-    duration: 180,
-    toValue: 0,
-    easing: Easing.bezier(0.31, 0.14, 0.66, 0.82),
-  };
-  const topOutConfig = {
-    duration: 180,
-    toValue: -SCREEN_HEIGHT,
-    easing: Easing.inOut(Easing.ease),
-  };
   const handleFocus = () => {
     setSearching(true);
   };
@@ -172,9 +158,12 @@ const SearchScreen: React.FC = () => {
   const handleCancel = () => {
     setSearching(false);
   };
+  const onSearchBarLayout = (e: LayoutChangeEvent) => {
+    setSearchBarHeight(e.nativeEvent.layout.height);
+  };
 
   return (
-    <SafeAreaView style={styles.screenContainer}>
+    <SafeAreaView style={styles.container}>
       <StatusBar barStyle="dark-content" />
       <SearchBar
         onCancel={handleCancel}
@@ -182,98 +171,39 @@ const SearchScreen: React.FC = () => {
         onBlur={handleBlur}
         onFocus={handleFocus}
         value={query}
-        {...{top, searching}}
+        onLayout={onSearchBarLayout}
+        {...{animationProgress, searching}}
       />
-      <ScrollView
-        scrollEnabled={!searching}
-        keyboardShouldPersistTaps={'always'}
-        stickyHeaderIndices={[4]}
-        contentContainerStyle={styles.contentContainer}
-        showsVerticalScrollIndicator={false}>
-        <SearchCategories defaultButtons={defaultButtons} />
-        <SearchResultsBackground {...{top}}>
-          {results === undefined &&
-          recents.length + recentCategories.length !== 0 ? (
+      <SearchCategories useSuggestions={false} />
+      <SearchResultsBackground
+        {...{searching, searchBarHeight, animationProgress}}>
+        {results === undefined ? (
+          recents.length + recentCategories.length > 0 && (
             <RecentSearches
               sectionTitle="Recent"
               onPress={clearRecentlySearched}
               screenType={ScreenType.Search}
               {...{recents, recentCategories}}
             />
-          ) : (
-            <SearchResultList
-              {...{results}}
-              keyboardVisible={keyboardVisible === 'keyboardVisibleTrue'}
-              previewType={'Search'}
-              screenType={ScreenType.Search}
-            />
-          )}
-        </SearchResultsBackground>
-      </ScrollView>
+          )
+        ) : (
+          <SearchResultList
+            {...{results}}
+            previewType={'Search'}
+            screenType={ScreenType.Search}
+          />
+        )}
+      </SearchResultsBackground>
       <TabsGradient />
     </SafeAreaView>
   );
 };
 
 const styles = StyleSheet.create({
-  screenContainer: {
+  container: {
+    flex: 1,
     paddingTop: 15,
     backgroundColor: '#fff',
   },
-  contentContainer: {
-    height: SCREEN_HEIGHT,
-    paddingTop: '2%',
-    paddingBottom: SCREEN_HEIGHT / 3,
-    paddingHorizontal: '3%',
-  },
-  header: {
-    marginVertical: 20,
-    zIndex: 1,
-  },
-  recentsHeaderContainer: {
-    flexDirection: 'row',
-  },
-  recentsHeader: {
-    fontSize: 17,
-    fontWeight: 'bold',
-    flexGrow: 1,
-  },
-  clear: {
-    fontSize: normalize(17),
-    fontWeight: 'bold',
-    color: TAGG_LIGHT_BLUE,
-  },
-  image: {
-    width: SCREEN_WIDTH,
-    height: SCREEN_WIDTH,
-  },
-  textContainer: {
-    marginTop: '10%',
-  },
-  headerText: {
-    color: '#fff',
-    fontSize: normalize(32),
-    fontWeight: '600',
-    textAlign: 'center',
-    marginBottom: '4%',
-    marginHorizontal: '10%',
-  },
-  subtext: {
-    color: '#fff',
-    fontSize: normalize(16),
-    fontWeight: '600',
-    textAlign: 'center',
-    marginHorizontal: '10%',
-  },
-  cancelButton: {
-    position: 'absolute',
-    height: '100%',
-    justifyContent: 'center',
-    paddingHorizontal: 5,
-  },
-  cancelText: {
-    color: '#818181',
-    fontWeight: '600',
-  },
 });
 export default SearchScreen;
-- 
cgit v1.2.3-70-g09d2

