From b6a31427f784c2e88ad6fe0178e5fd873b4a1099 Mon Sep 17 00:00:00 2001
From: Leon Jiang <35908040+leonyjiang@users.noreply.github.com>
Date: Thu, 1 Apr 2021 23:58:02 -0400
Subject: Improve position of overlaid tutorial

---
 src/components/profile/PublicProfile.tsx | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
index 88e0ecd1..eceb2fc3 100644
--- a/src/components/profile/PublicProfile.tsx
+++ b/src/components/profile/PublicProfile.tsx
@@ -35,6 +35,7 @@ const PublicProfile: React.FC<ContentProps> = ({
   screenType,
   setScrollEnabled,
   profileBodyHeight,
+  socialsBarHeight,
   scrollViewRef,
 }) => {
   const dispatch = useDispatch();
@@ -104,6 +105,7 @@ const PublicProfile: React.FC<ContentProps> = ({
                 screenType,
                 momentCategory: momentCategories[0],
                 profileBodyHeight,
+                socialsBarHeight,
               });
               setIsStageOnePromptClosed(true);
             }
@@ -133,6 +135,7 @@ const PublicProfile: React.FC<ContentProps> = ({
       navigation,
       screenType,
       profileBodyHeight,
+      socialsBarHeight,
       scrollViewRef,
     ]),
   );
-- 
cgit v1.2.3-70-g09d2


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/components/common/GradientBorderButton.tsx    |   2 +-
 src/components/common/TabsGradient.tsx            |   2 +-
 src/components/profile/PublicProfile.tsx          |   2 +-
 src/components/search/RecentSearches.tsx          |  31 ++--
 src/components/search/SearchBar.tsx               |  37 ++---
 src/components/search/SearchCategories.tsx        |  68 ++++----
 src/components/search/SearchResultList.tsx        |  85 +++++-----
 src/components/search/SearchResults.tsx           |  14 +-
 src/components/search/SearchResultsBackground.tsx |  69 ++++++---
 src/screens/search/DiscoverUsers.tsx              |   2 +-
 src/screens/search/SearchScreen.tsx               | 180 +++++++---------------
 11 files changed, 211 insertions(+), 281 deletions(-)

(limited to 'src/components/profile/PublicProfile.tsx')

diff --git a/src/components/common/GradientBorderButton.tsx b/src/components/common/GradientBorderButton.tsx
index 32ac5c52..a5dbde9d 100644
--- a/src/components/common/GradientBorderButton.tsx
+++ b/src/components/common/GradientBorderButton.tsx
@@ -42,7 +42,7 @@ const GradientBorderButton: React.FC<GradientBorderButtonProps> = ({
 };
 const styles = StyleSheet.create({
   container: {
-    marginVertical: 15,
+    marginVertical: 10,
   },
   gradientContainer: {
     width: SCREEN_WIDTH / 2 - 40,
diff --git a/src/components/common/TabsGradient.tsx b/src/components/common/TabsGradient.tsx
index a95e8bc3..07c55042 100644
--- a/src/components/common/TabsGradient.tsx
+++ b/src/components/common/TabsGradient.tsx
@@ -14,7 +14,7 @@ const TabsGradient: React.FC = () => {
 };
 const styles = StyleSheet.create({
   gradient: {
-    position: 'absolute',
+    ...StyleSheet.absoluteFillObject,
     top: (SCREEN_HEIGHT / 10) * 9,
     height: SCREEN_HEIGHT / 10,
     width: SCREEN_WIDTH,
diff --git a/src/components/profile/PublicProfile.tsx b/src/components/profile/PublicProfile.tsx
index 88e0ecd1..5f9b0b99 100644
--- a/src/components/profile/PublicProfile.tsx
+++ b/src/components/profile/PublicProfile.tsx
@@ -99,7 +99,7 @@ const PublicProfile: React.FC<ContentProps> = ({
               scrollViewRef.current
             ) {
               setScrollEnabled(false);
-              scrollViewRef.current.getNode().scrollTo({y: 0});
+              scrollViewRef.current.scrollTo({y: 0});
               navigation.navigate('MomentUploadPrompt', {
                 screenType,
                 momentCategory: momentCategories[0],
diff --git a/src/components/search/RecentSearches.tsx b/src/components/search/RecentSearches.tsx
index 84d35cac..6cea9338 100644
--- a/src/components/search/RecentSearches.tsx
+++ b/src/components/search/RecentSearches.tsx
@@ -6,6 +6,7 @@ import {
   StyleSheet,
   TouchableOpacityProps,
   ScrollView,
+  Keyboard,
 } from 'react-native';
 import {
   PreviewType,
@@ -15,7 +16,7 @@ import {
 } from '../../types';
 import {TAGG_LIGHT_BLUE} from '../../constants';
 import SearchResults from './SearchResults';
-import {SCREEN_HEIGHT} from '../../utils';
+import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs';
 
 interface RecentSearchesProps extends TouchableOpacityProps {
   sectionTitle: PreviewType;
@@ -25,35 +26,25 @@ interface RecentSearchesProps extends TouchableOpacityProps {
 }
 
 const RecentSearches: React.FC<RecentSearchesProps> = (props) => {
-  const {sectionTitle, recents, recentCategories, screenType} = props;
+  const {recents, recentCategories} = props;
   return (
-    <ScrollView
-      style={styles.mainContainer}
-      contentContainerStyle={styles.contentContainer}>
+    <>
       <View style={styles.header}>
-        <Text style={styles.title}>{sectionTitle}</Text>
+        <Text style={styles.title}>Recent</Text>
         <TouchableOpacity {...props}>
           <Text style={styles.clear}>Clear all</Text>
         </TouchableOpacity>
       </View>
-      <SearchResults
-        results={recents}
-        categories={recentCategories}
-        previewType={sectionTitle}
-        screenType={screenType}
-      />
-    </ScrollView>
+      <ScrollView
+        onScrollBeginDrag={Keyboard.dismiss}
+        contentContainerStyle={{paddingBottom: useBottomTabBarHeight()}}>
+        <SearchResults results={recents} categories={recentCategories} />
+      </ScrollView>
+    </>
   );
 };
 
 const styles = StyleSheet.create({
-  mainContainer: {
-    flex: 1,
-  },
-  contentContainer: {
-    paddingBottom: SCREEN_HEIGHT * 0.1,
-    flex: 1,
-  },
   header: {
     paddingHorizontal: 25,
     paddingVertical: 5,
diff --git a/src/components/search/SearchBar.tsx b/src/components/search/SearchBar.tsx
index 7b833406..d441b07b 100644
--- a/src/components/search/SearchBar.tsx
+++ b/src/components/search/SearchBar.tsx
@@ -9,20 +9,23 @@ import {
   TextInputSubmitEditingEventData,
   TouchableOpacity,
   View,
+  ViewStyle,
+  LayoutChangeEvent,
 } from 'react-native';
 import {normalize} from 'react-native-elements';
-import Animated, {interpolate} from 'react-native-reanimated';
+import Animated, {useAnimatedStyle} from 'react-native-reanimated';
 import Icon from 'react-native-vector-icons/Feather';
 import {useSelector} from 'react-redux';
 import {RootState} from '../../store/rootReducer';
-import {getSearchSuggestions, SCREEN_HEIGHT} from '../../utils';
+import {getSearchSuggestions} from '../../utils';
 
 const AnimatedIcon = Animated.createAnimatedComponent(Icon);
 
 interface SearchBarProps extends TextInputProps {
   onCancel: () => void;
-  top: Animated.Value<number>;
+  animationProgress: Animated.SharedValue<number>;
   searching: boolean;
+  onLayout: (e: LayoutChangeEvent) => void;
 }
 const SearchBar: React.FC<SearchBarProps> = ({
   onFocus,
@@ -31,7 +34,8 @@ const SearchBar: React.FC<SearchBarProps> = ({
   value,
   onCancel,
   searching,
-  top,
+  animationProgress,
+  onLayout,
 }) => {
   const handleSubmit = (
     e: NativeSyntheticEvent<TextInputSubmitEditingEventData>,
@@ -107,23 +111,15 @@ const SearchBar: React.FC<SearchBarProps> = ({
   }, [searching]);
 
   /*
-   * Animated nodes used in search bar activation animation.
+   * On-search marginRight style ("cancel" button slides and fades in).
    */
-  // TODO: (Leon) use reanimated v2
-  const marginRight = 0;
-  // const marginRight: Animated.Node<number> = interpolate(top, {
-  //   inputRange: [-SCREEN_HEIGHT, 0],
-  //   outputRange: [0, 58],
-  // });
-  // TODO: (Leon) use reanimated v2
-  const opacity = 0;
-  // const opacity: Animated.Node<number> = interpolate(top, {
-  //   inputRange: [-SCREEN_HEIGHT, 0],
-  //   outputRange: [0, 1],
-  // });
+  const animatedStyles = useAnimatedStyle<ViewStyle>(() => ({
+    marginRight: animationProgress.value * 58,
+    opacity: animationProgress.value,
+  }));
 
   return (
-    <View style={styles.container}>
+    <View style={styles.container} onLayout={onLayout}>
       <Animated.View style={styles.inputContainer}>
         <AnimatedIcon
           name="search"
@@ -135,13 +131,13 @@ const SearchBar: React.FC<SearchBarProps> = ({
           style={[styles.input]}
           placeholderTextColor={'#828282'}
           onSubmitEditing={handleSubmit}
-          clearButtonMode="while-editing"
+          clearButtonMode="always"
           autoCapitalize="none"
           autoCorrect={false}
           {...{placeholder, value, onChangeText, onFocus, onBlur}}
         />
       </Animated.View>
-      <Animated.View style={{marginRight, opacity}}>
+      <Animated.View style={animatedStyles}>
         <TouchableOpacity style={styles.cancelButton} onPress={onCancel}>
           <Text style={styles.cancelText}>Cancel</Text>
         </TouchableOpacity>
@@ -155,6 +151,7 @@ const styles = StyleSheet.create({
     height: 40,
     paddingHorizontal: 20,
     flexDirection: 'row',
+    zIndex: 2,
   },
   inputContainer: {
     flexGrow: 1,
diff --git a/src/components/search/SearchCategories.tsx b/src/components/search/SearchCategories.tsx
index c747b34f..3d142981 100644
--- a/src/components/search/SearchCategories.tsx
+++ b/src/components/search/SearchCategories.tsx
@@ -3,29 +3,40 @@ import React, {useEffect, useState} from 'react';
 import {StyleSheet, View} from 'react-native';
 import {getSuggestedSearchBubbleSuggestions} from '../../services/ExploreService';
 import {SearchCategoryType} from '../../types';
-import {SCREEN_WIDTH} from '../../utils';
 import GradientBorderButton from '../common/GradientBorderButton';
+import {useSelector} from 'react-redux';
+import {RootState} from 'src/store/rootReducer';
 
 interface SearchCategoriesProps {
   darkStyle?: boolean;
-  defaultButtons?: SearchCategoryType[];
+  useSuggestions: boolean;
 }
 
 const SearchCategories: React.FC<SearchCategoriesProps> = ({
   darkStyle = false,
-  defaultButtons,
+  useSuggestions,
 }) => {
   const navigation = useNavigation();
-  const mtSearchCategory: (key: number) => SearchCategoryType = (key) => ({
+  const {
+    profile: {university = ''},
+  } = useSelector((state: RootState) => state.user);
+  const defaultButtons: SearchCategoryType[] = [21, 22, 23, 24].map(
+    (year, index) => ({
+      id: index * -1,
+      name: `${university.split(' ')[0]} '${year}`,
+      category: university,
+    }),
+  );
+  const createloadingCategory: (key: number) => SearchCategoryType = (key) => ({
     id: key,
     name: '...',
     category: '...',
   });
   const [buttons, setButtons] = useState<SearchCategoryType[]>([
-    mtSearchCategory(-1),
-    mtSearchCategory(-2),
-    mtSearchCategory(-3),
-    mtSearchCategory(-4),
+    createloadingCategory(1),
+    createloadingCategory(2),
+    createloadingCategory(3),
+    createloadingCategory(4),
   ]);
 
   useEffect(() => {
@@ -36,7 +47,7 @@ const SearchCategories: React.FC<SearchCategoriesProps> = ({
         setButtons(localButtons);
       }
     };
-    if (!defaultButtons) {
+    if (useSuggestions) {
       loadButtons();
     } else {
       setButtons(defaultButtons);
@@ -45,33 +56,34 @@ const SearchCategories: React.FC<SearchCategoriesProps> = ({
 
   return (
     <View style={styles.container}>
-      {buttons.map((searchCategory) => (
-        <GradientBorderButton
-          key={searchCategory.id}
-          text={searchCategory.name}
-          darkStyle={darkStyle}
-          onPress={() => {
-            if (searchCategory.name !== '...') {
-              navigation.push('DiscoverUsers', {
-                searchCategory,
-              });
-            }
-          }}
-        />
-      ))}
+      <View style={styles.categoryContainer}>
+        {buttons.map((searchCategory, index) => (
+          <GradientBorderButton
+            key={index}
+            text={searchCategory.name}
+            darkStyle={darkStyle}
+            onPress={() => {
+              if (searchCategory.name !== '...') {
+                navigation.push('DiscoverUsers', {
+                  searchCategory,
+                });
+              }
+            }}
+          />
+        ))}
+      </View>
     </View>
   );
 };
 
 const styles = StyleSheet.create({
   container: {
-    zIndex: 0,
-    top: '3%',
-    alignSelf: 'center',
+    paddingVertical: 20,
+  },
+  categoryContainer: {
     flexDirection: 'row',
-    width: SCREEN_WIDTH * 0.9,
-    flexWrap: 'wrap',
     justifyContent: 'space-evenly',
+    flexWrap: 'wrap',
   },
 });
 export default SearchCategories;
diff --git a/src/components/search/SearchResultList.tsx b/src/components/search/SearchResultList.tsx
index 687b2285..a32760e1 100644
--- a/src/components/search/SearchResultList.tsx
+++ b/src/components/search/SearchResultList.tsx
@@ -1,15 +1,23 @@
 import React, {useEffect, useState} from 'react';
-import {SectionList, StyleSheet, Text, View} from 'react-native';
+import {
+  SectionList,
+  StyleSheet,
+  Text,
+  View,
+  Keyboard,
+  SectionListData,
+} from 'react-native';
 import {useSelector} from 'react-redux';
 import {RootState} from '../../store/rootreducer';
 import {NO_RESULTS_FOUND} from '../../constants/strings';
 import {PreviewType, ScreenType} from '../../types';
-import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {normalize, SCREEN_WIDTH} from '../../utils';
 import SearchResultsCell from './SearchResultCell';
+import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs';
 
 interface SearchResultsProps {
-  results: Array<any> | undefined;
-  keyboardVisible: boolean;
+  // TODO: make sure results come in as same type, regardless of profile, category, badges
+  results: SectionListData<any>[];
   previewType: PreviewType;
   screenType: ScreenType;
 }
@@ -21,11 +29,8 @@ const sectionHeader: React.FC<Boolean> = (showBorder: Boolean) => {
   return null;
 };
 
-const SearchResultList: React.FC<SearchResultsProps> = ({
-  results,
-  keyboardVisible,
-}) => {
-  const [showEmptyView, setshowEmptyView] = useState(false);
+const SearchResultList: React.FC<SearchResultsProps> = ({results}) => {
+  const [showEmptyView, setshowEmptyView] = useState<boolean>(false);
   const {user: loggedInUser} = useSelector((state: RootState) => state.user);
 
   useEffect(() => {
@@ -38,57 +43,41 @@ const SearchResultList: React.FC<SearchResultsProps> = ({
     }
   }, [results]);
 
-  return (
-    <View style={styles.container}>
-      {showEmptyView && (
-        <View style={styles.noResultsTextContainer}>
-          <Text style={styles.noResultsTextStyle}>{NO_RESULTS_FOUND}</Text>
-        </View>
-      )}
-      {!showEmptyView && (
-        <SectionList
-          style={[
-            {width: SCREEN_WIDTH},
-            keyboardVisible ? styles.keyboardOpen : {},
-          ]}
-          contentContainerStyle={styles.sectionListContentContainer}
-          sections={results}
-          keyExtractor={(item, index) => item.id + index}
-          renderItem={({section, item}) => {
-            return (
-              <SearchResultsCell
-                profileData={item}
-                loggedInUser={loggedInUser}
-              />
-            );
-          }}
-          renderSectionHeader={({section: {data}}) =>
-            sectionHeader(data.length !== 0)
-          }
-        />
-      )}
+  return showEmptyView ? (
+    <View style={styles.container} onTouchStart={Keyboard.dismiss}>
+      <Text style={styles.noResultsTextStyle}>{NO_RESULTS_FOUND}</Text>
     </View>
+  ) : (
+    <SectionList
+      onScrollBeginDrag={Keyboard.dismiss}
+      contentContainerStyle={[{paddingBottom: useBottomTabBarHeight()}]}
+      sections={results}
+      keyExtractor={(item, index) => item.id + index}
+      renderItem={({item}) => {
+        return (
+          <SearchResultsCell profileData={item} loggedInUser={loggedInUser} />
+        );
+      }}
+      renderSectionHeader={({section: {data}}) =>
+        sectionHeader(data.length !== 0)
+      }
+      stickySectionHeadersEnabled={false}
+    />
   );
 };
 
 const styles = StyleSheet.create({
   container: {
-    height: SCREEN_HEIGHT,
-    paddingBottom: SCREEN_HEIGHT * 0.1,
-  },
-  sectionListContentContainer: {
-    paddingBottom: SCREEN_HEIGHT * 0.15,
-    width: SCREEN_WIDTH,
+    flex: 1,
+    marginTop: 30,
+    alignItems: 'center',
   },
   sectionHeaderStyle: {
     width: '100%',
     height: 0.5,
-    marginBottom: normalize(24),
+    marginVertical: 5,
     backgroundColor: '#C4C4C4',
   },
-  keyboardOpen: {
-    marginBottom: SCREEN_HEIGHT * 0.35,
-  },
   noResultsTextContainer: {
     justifyContent: 'center',
     flexDirection: 'row',
diff --git a/src/components/search/SearchResults.tsx b/src/components/search/SearchResults.tsx
index ef518d8b..a73d0b40 100644
--- a/src/components/search/SearchResults.tsx
+++ b/src/components/search/SearchResults.tsx
@@ -1,18 +1,10 @@
 import React from 'react';
-import {
-  ProfilePreviewType,
-  PreviewType,
-  ScreenType,
-  CategoryPreviewType,
-} from '../../types';
-import {View} from 'react-native';
+import {ProfilePreviewType, CategoryPreviewType} from '../../types';
 import SearchResultsCell from './SearchResultCell';
 import {useSelector} from 'react-redux';
 import {RootState} from '../../store/rootReducer';
 interface SearchResultsProps {
   results: ProfilePreviewType[];
-  previewType: PreviewType;
-  screenType: ScreenType;
   categories: CategoryPreviewType[];
 }
 const SearchResults: React.FC<SearchResultsProps> = ({results, categories}) => {
@@ -22,7 +14,7 @@ const SearchResults: React.FC<SearchResultsProps> = ({results, categories}) => {
    */
   const {user: loggedInUser} = useSelector((state: RootState) => state.user);
   return (
-    <View>
+    <>
       {categories
         .slice(0)
         .reverse()
@@ -43,7 +35,7 @@ const SearchResults: React.FC<SearchResultsProps> = ({results, categories}) => {
             {...{loggedInUser}}
           />
         ))}
-    </View>
+    </>
   );
 };
 
diff --git a/src/components/search/SearchResultsBackground.tsx b/src/components/search/SearchResultsBackground.tsx
index 3d7fab4e..e5236295 100644
--- a/src/components/search/SearchResultsBackground.tsx
+++ b/src/components/search/SearchResultsBackground.tsx
@@ -1,32 +1,55 @@
 import React from 'react';
-import {StyleSheet} from 'react-native';
-import Animated, {interpolate} from 'react-native-reanimated';
-import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
+import {StyleSheet, ViewStyle} from 'react-native';
+import Animated, {
+  useAnimatedStyle,
+  useDerivedValue,
+  interpolate,
+  Extrapolate,
+} from 'react-native-reanimated';
+import {useSafeAreaInsets} from 'react-native-safe-area-context';
 
 interface SearchResultsBackgroundProps {
-  top: Animated.Value<number>;
+  animationProgress: Animated.SharedValue<number>;
+  searchBarHeight: number;
+  searching: boolean;
 }
 const SearchResultsBackground: React.FC<SearchResultsBackgroundProps> = ({
-  top,
+  animationProgress,
+  searchBarHeight,
+  searching,
   children,
 }) => {
-  // TODO: (Leon) use reanimated v2
-  const opacityBackground = 0;
-  // const opacityBackground: Animated.Node<number> = interpolate(top, {
-  //   inputRange: [-SCREEN_HEIGHT, 0],
-  //   outputRange: [0, 1],
-  // });
-  // TODO: (Leon) use reanimated v2
-  const opacityContent = 0;
-  // const opacityContent: Animated.Node<number> = interpolate(top, {
-  //   inputRange: [-SCREEN_HEIGHT / 40, 0],
-  //   outputRange: [0, 1],
-  // });
+  const {top: topInset} = useSafeAreaInsets();
+  /*
+   * On-search container style (opacity fade-in).
+   */
+  const backgroundAnimatedStyles = useAnimatedStyle<ViewStyle>(() => ({
+    opacity: animationProgress.value,
+  }));
+  /*
+   * Derived animation value for contentAnimatedStyles.
+   */
+  const contentAnimationProgress = useDerivedValue<number>(() =>
+    interpolate(animationProgress.value, [0.9, 1], [0, 1], Extrapolate.CLAMP),
+  );
+  /*
+   * On-search content style (delayed opacity fade-in).
+   */
+  const contentAnimatedStyles = useAnimatedStyle<ViewStyle>(() => ({
+    opacity: contentAnimationProgress.value,
+  }));
   return (
     <Animated.View
-      style={[styles.container, {opacity: opacityBackground, top}]}>
-      <Animated.View
-        style={[styles.contentContainer, {opacity: opacityContent}]}>
+      style={[
+        styles.container,
+        backgroundAnimatedStyles,
+        {
+          // absolute: inset + search screen paddingTop + searchBar + padding
+          paddingTop: topInset + 15 + searchBarHeight + 10,
+        },
+      ]}
+      pointerEvents={searching ? 'auto' : 'none'}>
+      <Animated.View style={[styles.contentContainer, contentAnimatedStyles]}>
         {children}
       </Animated.View>
     </Animated.View>
@@ -34,15 +57,11 @@ const SearchResultsBackground: React.FC<SearchResultsBackgroundProps> = ({
 };
 const styles = StyleSheet.create({
   container: {
-    height: SCREEN_HEIGHT,
-    width: SCREEN_WIDTH,
-    position: 'absolute',
+    ...StyleSheet.absoluteFillObject,
     backgroundColor: 'white',
   },
   contentContainer: {
     flex: 1,
-    paddingVertical: 10,
-    paddingBottom: SCREEN_HEIGHT / 15,
   },
 });
 export default SearchResultsBackground;
diff --git a/src/screens/search/DiscoverUsers.tsx b/src/screens/search/DiscoverUsers.tsx
index b87bfc37..f67585f2 100644
--- a/src/screens/search/DiscoverUsers.tsx
+++ b/src/screens/search/DiscoverUsers.tsx
@@ -126,7 +126,7 @@ const DiscoverUsers: React.FC<DiscoverUsersProps> = ({route}) => {
           ListFooterComponent={() => (
             <>
               <Text style={styles.otherGroups}>Other Groups</Text>
-              <SearchCategories darkStyle={true} />
+              <SearchCategories useSuggestions={true} darkStyle={true} />
             </>
           )}
         />
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

