about summary refs log tree commit diff
path: root/src/view/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/screens')
-rw-r--r--src/view/screens/Feeds.tsx4
-rw-r--r--src/view/screens/Notifications.tsx25
-rw-r--r--src/view/screens/Profile.tsx82
-rw-r--r--src/view/screens/ProfileFeed.tsx46
-rw-r--r--src/view/screens/ProfileList.tsx63
-rw-r--r--src/view/screens/Search/Search.tsx9
6 files changed, 70 insertions, 159 deletions
diff --git a/src/view/screens/Feeds.tsx b/src/view/screens/Feeds.tsx
index f319fbc39..d2d0aafb8 100644
--- a/src/view/screens/Feeds.tsx
+++ b/src/view/screens/Feeds.tsx
@@ -19,7 +19,7 @@ import {
 import {ErrorMessage} from 'view/com/util/error/ErrorMessage'
 import debounce from 'lodash.debounce'
 import {Text} from 'view/com/util/text/Text'
-import {FlatList} from 'view/com/util/Views'
+import {List} from 'view/com/util/List'
 import {useFocusEffect} from '@react-navigation/native'
 import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
 import {Trans, msg} from '@lingui/macro'
@@ -481,7 +481,7 @@ export function FeedsScreen(_props: Props) {
 
       {preferences ? <View /> : <ActivityIndicator />}
 
-      <FlatList
+      <List
         style={[!isTabletOrDesktop && s.flex1, styles.list]}
         data={items}
         keyExtractor={item => item.key}
diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx
index fceaa60c2..e28a67e37 100644
--- a/src/view/screens/Notifications.tsx
+++ b/src/view/screens/Notifications.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import {FlatList, View} from 'react-native'
+import {View} from 'react-native'
 import {useFocusEffect} from '@react-navigation/native'
 import {useQueryClient} from '@tanstack/react-query'
 import {
@@ -9,8 +9,9 @@ import {
 import {ViewHeader} from '../com/util/ViewHeader'
 import {Feed} from '../com/notifications/Feed'
 import {TextLink} from 'view/com/util/Link'
+import {ListMethods} from 'view/com/util/List'
 import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
-import {useOnMainScroll} from 'lib/hooks/useOnMainScroll'
+import {MainScrollProvider} from '../com/util/MainScrollProvider'
 import {usePalette} from 'lib/hooks/usePalette'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {s, colors} from 'lib/styles'
@@ -35,8 +36,8 @@ type Props = NativeStackScreenProps<
 export function NotificationsScreen({}: Props) {
   const {_} = useLingui()
   const setMinimalShellMode = useSetMinimalShellMode()
-  const [onMainScroll, isScrolledDown, resetMainScroll] = useOnMainScroll()
-  const scrollElRef = React.useRef<FlatList>(null)
+  const [isScrolledDown, setIsScrolledDown] = React.useState(false)
+  const scrollElRef = React.useRef<ListMethods>(null)
   const checkLatestRef = React.useRef<() => void | null>()
   const {screen} = useAnalytics()
   const pal = usePalette('default')
@@ -50,8 +51,8 @@ export function NotificationsScreen({}: Props) {
   // =
   const scrollToTop = React.useCallback(() => {
     scrollElRef.current?.scrollToOffset({animated: isNative, offset: 0})
-    resetMainScroll()
-  }, [scrollElRef, resetMainScroll])
+    setMinimalShellMode(false)
+  }, [scrollElRef, setMinimalShellMode])
 
   const onPressLoadLatest = React.useCallback(() => {
     scrollToTop()
@@ -130,11 +131,13 @@ export function NotificationsScreen({}: Props) {
   return (
     <View testID="notificationsScreen" style={s.hContentRegion}>
       <ViewHeader title={_(msg`Notifications`)} canGoBack={false} />
-      <Feed
-        onScroll={onMainScroll}
-        scrollElRef={scrollElRef}
-        ListHeaderComponent={ListHeaderComponent}
-      />
+      <MainScrollProvider>
+        <Feed
+          onScrolledDownChange={setIsScrolledDown}
+          scrollElRef={scrollElRef}
+          ListHeaderComponent={ListHeaderComponent}
+        />
+      </MainScrollProvider>
       {(isScrolledDown || hasNew) && (
         <LoadLatestBtn
           onPress={onPressLoadLatest}
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index b7dac8c6d..3f2dd773e 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -5,7 +5,8 @@ import {AppBskyActorDefs, moderateProfile, ModerationOpts} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
-import {CenteredView, FlatList} from '../com/util/Views'
+import {CenteredView} from '../com/util/Views'
+import {ListRef} from '../com/util/List'
 import {ScreenHider} from 'view/com/util/moderation/ScreenHider'
 import {Feed} from 'view/com/posts/Feed'
 import {ProfileLists} from '../com/lists/ProfileLists'
@@ -20,7 +21,6 @@ import {useAnalytics} from 'lib/analytics/analytics'
 import {ComposeIcon2} from 'lib/icons'
 import {useSetTitle} from 'lib/hooks/useSetTitle'
 import {combinedDisplayName} from 'lib/strings/display-names'
-import {OnScrollHandler} from '#/lib/hooks/useOnMainScroll'
 import {FeedDescriptor} from '#/state/queries/post-feed'
 import {useResolveDidQuery} from '#/state/queries/resolve-uri'
 import {useProfileQuery} from '#/state/queries/profile'
@@ -277,103 +277,67 @@ function ProfileScreenLoaded({
         onPageSelected={onPageSelected}
         onCurrentPageSelected={onCurrentPageSelected}
         renderHeader={renderHeader}>
-        {({onScroll, headerHeight, isFocused, isScrolledDown, scrollElRef}) => (
+        {({headerHeight, isFocused, scrollElRef}) => (
           <FeedSection
             ref={postsSectionRef}
             feed={`author|${profile.did}|posts_and_author_threads`}
-            onScroll={onScroll}
             headerHeight={headerHeight}
             isFocused={isFocused}
-            isScrolledDown={isScrolledDown}
-            scrollElRef={
-              scrollElRef as React.MutableRefObject<FlatList<any> | null>
-            }
+            scrollElRef={scrollElRef as ListRef}
             ignoreFilterFor={profile.did}
           />
         )}
         {showRepliesTab
-          ? ({
-              onScroll,
-              headerHeight,
-              isFocused,
-              isScrolledDown,
-              scrollElRef,
-            }) => (
+          ? ({headerHeight, isFocused, scrollElRef}) => (
               <FeedSection
                 ref={repliesSectionRef}
                 feed={`author|${profile.did}|posts_with_replies`}
-                onScroll={onScroll}
                 headerHeight={headerHeight}
                 isFocused={isFocused}
-                isScrolledDown={isScrolledDown}
-                scrollElRef={
-                  scrollElRef as React.MutableRefObject<FlatList<any> | null>
-                }
+                scrollElRef={scrollElRef as ListRef}
                 ignoreFilterFor={profile.did}
               />
             )
           : null}
-        {({onScroll, headerHeight, isFocused, isScrolledDown, scrollElRef}) => (
+        {({headerHeight, isFocused, scrollElRef}) => (
           <FeedSection
             ref={mediaSectionRef}
             feed={`author|${profile.did}|posts_with_media`}
-            onScroll={onScroll}
             headerHeight={headerHeight}
             isFocused={isFocused}
-            isScrolledDown={isScrolledDown}
-            scrollElRef={
-              scrollElRef as React.MutableRefObject<FlatList<any> | null>
-            }
+            scrollElRef={scrollElRef as ListRef}
             ignoreFilterFor={profile.did}
           />
         )}
         {showLikesTab
-          ? ({
-              onScroll,
-              headerHeight,
-              isFocused,
-              isScrolledDown,
-              scrollElRef,
-            }) => (
+          ? ({headerHeight, isFocused, scrollElRef}) => (
               <FeedSection
                 ref={likesSectionRef}
                 feed={`likes|${profile.did}`}
-                onScroll={onScroll}
                 headerHeight={headerHeight}
                 isFocused={isFocused}
-                isScrolledDown={isScrolledDown}
-                scrollElRef={
-                  scrollElRef as React.MutableRefObject<FlatList<any> | null>
-                }
+                scrollElRef={scrollElRef as ListRef}
                 ignoreFilterFor={profile.did}
               />
             )
           : null}
         {showFeedsTab
-          ? ({onScroll, headerHeight, isFocused, scrollElRef}) => (
+          ? ({headerHeight, isFocused, scrollElRef}) => (
               <ProfileFeedgens
                 ref={feedsSectionRef}
                 did={profile.did}
-                scrollElRef={
-                  scrollElRef as React.MutableRefObject<FlatList<any> | null>
-                }
-                onScroll={onScroll}
-                scrollEventThrottle={1}
+                scrollElRef={scrollElRef as ListRef}
                 headerOffset={headerHeight}
                 enabled={isFocused}
               />
             )
           : null}
         {showListsTab
-          ? ({onScroll, headerHeight, isFocused, scrollElRef}) => (
+          ? ({headerHeight, isFocused, scrollElRef}) => (
               <ProfileLists
                 ref={listsSectionRef}
                 did={profile.did}
-                scrollElRef={
-                  scrollElRef as React.MutableRefObject<FlatList<any> | null>
-                }
-                onScroll={onScroll}
-                scrollEventThrottle={1}
+                scrollElRef={scrollElRef as ListRef}
                 headerOffset={headerHeight}
                 enabled={isFocused}
               />
@@ -396,28 +360,19 @@ function ProfileScreenLoaded({
 
 interface FeedSectionProps {
   feed: FeedDescriptor
-  onScroll: OnScrollHandler
   headerHeight: number
   isFocused: boolean
-  isScrolledDown: boolean
-  scrollElRef: React.MutableRefObject<FlatList<any> | null>
+  scrollElRef: ListRef
   ignoreFilterFor?: string
 }
 const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
   function FeedSectionImpl(
-    {
-      feed,
-      onScroll,
-      headerHeight,
-      isFocused,
-      isScrolledDown,
-      scrollElRef,
-      ignoreFilterFor,
-    },
+    {feed, headerHeight, isFocused, scrollElRef, ignoreFilterFor},
     ref,
   ) {
     const queryClient = useQueryClient()
     const [hasNew, setHasNew] = React.useState(false)
+    const [isScrolledDown, setIsScrolledDown] = React.useState(false)
 
     const onScrollToTop = React.useCallback(() => {
       scrollElRef.current?.scrollToOffset({
@@ -443,8 +398,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
           feed={feed}
           scrollElRef={scrollElRef}
           onHasNew={setHasNew}
-          onScroll={onScroll}
-          scrollEventThrottle={1}
+          onScrolledDownChange={setIsScrolledDown}
           renderEmptyState={renderPostsEmpty}
           headerOffset={headerHeight}
           renderEndOfFeed={ProfileEndOfFeed}
diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx
index 620b1814a..ea92ebab1 100644
--- a/src/view/screens/ProfileFeed.tsx
+++ b/src/view/screens/ProfileFeed.tsx
@@ -1,11 +1,5 @@
 import React, {useMemo, useCallback} from 'react'
-import {
-  Dimensions,
-  StyleSheet,
-  View,
-  ActivityIndicator,
-  FlatList,
-} from 'react-native'
+import {Dimensions, StyleSheet, View, ActivityIndicator} from 'react-native'
 import {NativeStackScreenProps} from '@react-navigation/native-stack'
 import {useNavigation} from '@react-navigation/native'
 import {useQueryClient} from '@tanstack/react-query'
@@ -20,6 +14,7 @@ import {PagerWithHeader} from 'view/com/pager/PagerWithHeader'
 import {ProfileSubpageHeader} from 'view/com/profile/ProfileSubpageHeader'
 import {Feed} from 'view/com/posts/Feed'
 import {TextLink} from 'view/com/util/Link'
+import {ListRef} from 'view/com/util/List'
 import {Button} from 'view/com/util/forms/Button'
 import {Text} from 'view/com/util/text/Text'
 import {RichText} from 'view/com/util/text/RichText'
@@ -29,12 +24,13 @@ import {EmptyState} from 'view/com/util/EmptyState'
 import * as Toast from 'view/com/util/Toast'
 import {useSetTitle} from 'lib/hooks/useSetTitle'
 import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
-import {OnScrollHandler} from 'lib/hooks/useOnMainScroll'
 import {shareUrl} from 'lib/sharing'
 import {toShareUrl} from 'lib/strings/url-helpers'
 import {Haptics} from 'lib/haptics'
 import {useAnalytics} from 'lib/analytics/analytics'
 import {NativeDropdown, DropdownItem} from 'view/com/util/forms/NativeDropdown'
+import {useScrollHandlers} from '#/lib/ScrollContext'
+import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
 import {makeCustomFeedLink} from 'lib/routes/links'
 import {pluralize} from 'lib/strings/helpers'
 import {CenteredView, ScrollView} from 'view/com/util/Views'
@@ -46,7 +42,6 @@ import {logger} from '#/logger'
 import {Trans, msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useModalControls} from '#/state/modals'
-import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
 import {
   useFeedSourceInfoQuery,
   FeedSourceFeedInfo,
@@ -403,17 +398,13 @@ export function ProfileFeedScreenInner({
         isHeaderReady={true}
         renderHeader={renderHeader}
         onCurrentPageSelected={onCurrentPageSelected}>
-        {({onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused}) =>
+        {({headerHeight, scrollElRef, isFocused}) =>
           isPublicResponse?.isPublic ? (
             <FeedSection
               ref={feedSectionRef}
               feed={`feedgen|${feedInfo.uri}`}
-              onScroll={onScroll}
               headerHeight={headerHeight}
-              isScrolledDown={isScrolledDown}
-              scrollElRef={
-                scrollElRef as React.MutableRefObject<FlatList<any> | null>
-              }
+              scrollElRef={scrollElRef as ListRef}
               isFocused={isFocused}
             />
           ) : (
@@ -422,13 +413,12 @@ export function ProfileFeedScreenInner({
             </CenteredView>
           )
         }
-        {({onScroll, headerHeight, scrollElRef}) => (
+        {({headerHeight, scrollElRef}) => (
           <AboutSection
             feedOwnerDid={feedInfo.creatorDid}
             feedRkey={feedInfo.route.params.rkey}
             feedInfo={feedInfo}
             headerHeight={headerHeight}
-            onScroll={onScroll}
             scrollElRef={
               scrollElRef as React.MutableRefObject<ScrollView | null>
             }
@@ -497,18 +487,14 @@ function NonPublicFeedMessage({rawError}: {rawError?: Error}) {
 
 interface FeedSectionProps {
   feed: FeedDescriptor
-  onScroll: OnScrollHandler
   headerHeight: number
-  isScrolledDown: boolean
-  scrollElRef: React.MutableRefObject<FlatList<any> | null>
+  scrollElRef: ListRef
   isFocused: boolean
 }
 const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
-  function FeedSectionImpl(
-    {feed, onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused},
-    ref,
-  ) {
+  function FeedSectionImpl({feed, headerHeight, scrollElRef, isFocused}, ref) {
     const [hasNew, setHasNew] = React.useState(false)
+    const [isScrolledDown, setIsScrolledDown] = React.useState(false)
     const queryClient = useQueryClient()
 
     const onScrollToTop = useCallback(() => {
@@ -536,8 +522,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
           pollInterval={30e3}
           scrollElRef={scrollElRef}
           onHasNew={setHasNew}
-          onScroll={onScroll}
-          scrollEventThrottle={5}
+          onScrolledDownChange={setIsScrolledDown}
           renderEmptyState={renderPostsEmpty}
           headerOffset={headerHeight}
         />
@@ -558,7 +543,6 @@ function AboutSection({
   feedRkey,
   feedInfo,
   headerHeight,
-  onScroll,
   scrollElRef,
   isOwner,
 }: {
@@ -566,13 +550,13 @@ function AboutSection({
   feedRkey: string
   feedInfo: FeedSourceFeedInfo
   headerHeight: number
-  onScroll: OnScrollHandler
   scrollElRef: React.MutableRefObject<ScrollView | null>
   isOwner: boolean
 }) {
   const pal = usePalette('default')
   const {_} = useLingui()
-  const scrollHandler = useAnimatedScrollHandler(onScroll)
+  const scrollHandlers = useScrollHandlers()
+  const onScroll = useAnimatedScrollHandler(scrollHandlers)
   const [likeUri, setLikeUri] = React.useState(feedInfo.likeUri)
   const {hasSession} = useSession()
   const {track} = useAnalytics()
@@ -608,12 +592,12 @@ function AboutSection({
   return (
     <ScrollView
       ref={scrollElRef}
+      onScroll={onScroll}
       scrollEventThrottle={1}
       contentContainerStyle={{
         paddingTop: headerHeight,
         minHeight: Dimensions.get('window').height * 1.5,
-      }}
-      onScroll={scrollHandler}>
+      }}>
       <View
         style={[
           {
diff --git a/src/view/screens/ProfileList.tsx b/src/view/screens/ProfileList.tsx
index 3dcc7121f..7f922e5b4 100644
--- a/src/view/screens/ProfileList.tsx
+++ b/src/view/screens/ProfileList.tsx
@@ -1,11 +1,5 @@
 import React, {useCallback, useMemo} from 'react'
-import {
-  ActivityIndicator,
-  FlatList,
-  Pressable,
-  StyleSheet,
-  View,
-} from 'react-native'
+import {ActivityIndicator, Pressable, StyleSheet, View} from 'react-native'
 import {useFocusEffect} from '@react-navigation/native'
 import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
 import {useNavigation} from '@react-navigation/native'
@@ -22,6 +16,7 @@ import {EmptyState} from 'view/com/util/EmptyState'
 import {RichText} from 'view/com/util/text/RichText'
 import {Button} from 'view/com/util/forms/Button'
 import {TextLink} from 'view/com/util/Link'
+import {ListRef} from 'view/com/util/List'
 import * as Toast from 'view/com/util/Toast'
 import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
 import {FAB} from 'view/com/util/fab/FAB'
@@ -31,7 +26,6 @@ import {usePalette} from 'lib/hooks/usePalette'
 import {useSetTitle} from 'lib/hooks/useSetTitle'
 import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
-import {OnScrollHandler} from 'lib/hooks/useOnMainScroll'
 import {NavigationProp} from 'lib/routes/types'
 import {toShareUrl} from 'lib/strings/url-helpers'
 import {shareUrl} from 'lib/sharing'
@@ -165,36 +159,22 @@ function ProfileListScreenLoaded({
           isHeaderReady={true}
           renderHeader={renderHeader}
           onCurrentPageSelected={onCurrentPageSelected}>
-          {({
-            onScroll,
-            headerHeight,
-            isScrolledDown,
-            scrollElRef,
-            isFocused,
-          }) => (
+          {({headerHeight, scrollElRef, isFocused}) => (
             <FeedSection
               ref={feedSectionRef}
               feed={`list|${uri}`}
-              scrollElRef={
-                scrollElRef as React.MutableRefObject<FlatList<any> | null>
-              }
-              onScroll={onScroll}
+              scrollElRef={scrollElRef as ListRef}
               headerHeight={headerHeight}
-              isScrolledDown={isScrolledDown}
               isFocused={isFocused}
             />
           )}
-          {({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
+          {({headerHeight, scrollElRef}) => (
             <AboutSection
               ref={aboutSectionRef}
-              scrollElRef={
-                scrollElRef as React.MutableRefObject<FlatList<any> | null>
-              }
+              scrollElRef={scrollElRef as ListRef}
               list={list}
               onPressAddUser={onPressAddUser}
-              onScroll={onScroll}
               headerHeight={headerHeight}
-              isScrolledDown={isScrolledDown}
             />
           )}
         </PagerWithHeader>
@@ -221,16 +201,12 @@ function ProfileListScreenLoaded({
         items={SECTION_TITLES_MOD}
         isHeaderReady={true}
         renderHeader={renderHeader}>
-        {({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
+        {({headerHeight, scrollElRef}) => (
           <AboutSection
             list={list}
-            scrollElRef={
-              scrollElRef as React.MutableRefObject<FlatList<any> | null>
-            }
+            scrollElRef={scrollElRef as ListRef}
             onPressAddUser={onPressAddUser}
-            onScroll={onScroll}
             headerHeight={headerHeight}
-            isScrolledDown={isScrolledDown}
           />
         )}
       </PagerWithHeader>
@@ -615,19 +591,15 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
 
 interface FeedSectionProps {
   feed: FeedDescriptor
-  onScroll: OnScrollHandler
   headerHeight: number
-  isScrolledDown: boolean
-  scrollElRef: React.MutableRefObject<FlatList<any> | null>
+  scrollElRef: ListRef
   isFocused: boolean
 }
 const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
-  function FeedSectionImpl(
-    {feed, scrollElRef, onScroll, headerHeight, isScrolledDown, isFocused},
-    ref,
-  ) {
+  function FeedSectionImpl({feed, scrollElRef, headerHeight, isFocused}, ref) {
     const queryClient = useQueryClient()
     const [hasNew, setHasNew] = React.useState(false)
+    const [isScrolledDown, setIsScrolledDown] = React.useState(false)
 
     const onScrollToTop = useCallback(() => {
       scrollElRef.current?.scrollToOffset({
@@ -654,8 +626,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
           pollInterval={30e3}
           scrollElRef={scrollElRef}
           onHasNew={setHasNew}
-          onScroll={onScroll}
-          scrollEventThrottle={1}
+          onScrolledDownChange={setIsScrolledDown}
           renderEmptyState={renderPostsEmpty}
           headerOffset={headerHeight}
         />
@@ -674,20 +645,19 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
 interface AboutSectionProps {
   list: AppBskyGraphDefs.ListView
   onPressAddUser: () => void
-  onScroll: OnScrollHandler
   headerHeight: number
-  isScrolledDown: boolean
-  scrollElRef: React.MutableRefObject<FlatList<any> | null>
+  scrollElRef: ListRef
 }
 const AboutSection = React.forwardRef<SectionRef, AboutSectionProps>(
   function AboutSectionImpl(
-    {list, onPressAddUser, onScroll, headerHeight, isScrolledDown, scrollElRef},
+    {list, onPressAddUser, headerHeight, scrollElRef},
     ref,
   ) {
     const pal = usePalette('default')
     const {_} = useLingui()
     const {isMobile} = useWebMediaQueries()
     const {currentAccount} = useSession()
+    const [isScrolledDown, setIsScrolledDown] = React.useState(false)
     const isCurateList = list.purpose === 'app.bsky.graph.defs#curatelist'
     const isOwner = list.creator.did === currentAccount?.did
 
@@ -817,8 +787,7 @@ const AboutSection = React.forwardRef<SectionRef, AboutSectionProps>(
           renderHeader={renderHeader}
           renderEmptyState={renderEmptyState}
           headerOffset={headerHeight}
-          onScroll={onScroll}
-          scrollEventThrottle={1}
+          onScrolledDownChange={setIsScrolledDown}
         />
         {isScrolledDown && (
           <LoadLatestBtn
diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx
index b4db270b3..7d7b4098f 100644
--- a/src/view/screens/Search/Search.tsx
+++ b/src/view/screens/Search/Search.tsx
@@ -8,7 +8,8 @@ import {
   Pressable,
   Platform,
 } from 'react-native'
-import {FlatList, ScrollView, CenteredView} from '#/view/com/util/Views'
+import {ScrollView, CenteredView} from '#/view/com/util/Views'
+import {List} from '#/view/com/util/List'
 import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
@@ -155,7 +156,7 @@ function SearchScreenSuggestedFollows() {
   }, [currentAccount, setSuggestions, getSuggestedFollowsByActor])
 
   return suggestions.length ? (
-    <FlatList
+    <List
       data={suggestions}
       renderItem={({item}) => <ProfileCardWithFollowBtn profile={item} noBg />}
       keyExtractor={item => item.did}
@@ -243,7 +244,7 @@ function SearchScreenPostResults({query}: {query: string}) {
       {isFetched ? (
         <>
           {posts.length ? (
-            <FlatList
+            <List
               data={items}
               renderItem={({item}) => {
                 if (item.type === 'post') {
@@ -284,7 +285,7 @@ function SearchScreenUserResults({query}: {query: string}) {
   return isFetched && results ? (
     <>
       {results.length ? (
-        <FlatList
+        <List
           data={results}
           renderItem={({item}) => (
             <ProfileCardWithFollowBtn profile={item} noBg />