From 318b29d3fd7d22895ed6ba9a8daff6f296d7dd58 Mon Sep 17 00:00:00 2001
From: Samuel Newman <mozzius@protonmail.com>
Date: Wed, 2 Apr 2025 00:19:59 +0300
Subject: Fix loading jumps and footer on feeds tab (#8063)

* Fix loading jumps and footer on feeds tab

* same for lists/starter packs
---
 src/view/com/lists/ProfileLists.tsx | 55 ++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 28 deletions(-)

(limited to 'src/view/com/lists/ProfileLists.tsx')

diff --git a/src/view/com/lists/ProfileLists.tsx b/src/view/com/lists/ProfileLists.tsx
index 3a0b0b198..437648c62 100644
--- a/src/view/com/lists/ProfileLists.tsx
+++ b/src/view/com/lists/ProfileLists.tsx
@@ -1,29 +1,27 @@
 import React from 'react'
 import {
-  ActivityIndicator,
   findNodeHandle,
-  ListRenderItemInfo,
-  StyleProp,
-  StyleSheet,
+  type ListRenderItemInfo,
+  type StyleProp,
   View,
-  ViewStyle,
+  type ViewStyle,
 } from 'react-native'
 import {msg} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {useQueryClient} from '@tanstack/react-query'
 
-import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
 import {cleanError} from '#/lib/strings/errors'
 import {logger} from '#/logger'
 import {isNative, isWeb} from '#/platform/detection'
 import {RQKEY, useProfileListsQuery} from '#/state/queries/profile-lists'
 import {EmptyState} from '#/view/com/util/EmptyState'
+import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
+import {List, type ListRef} from '#/view/com/util/List'
 import {FeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
+import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn'
 import {atoms as a, ios, useTheme} from '#/alf'
 import * as ListCard from '#/components/ListCard'
-import {ErrorMessage} from '../util/error/ErrorMessage'
-import {List, ListRef} from '../util/List'
-import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
+import {ListFooter} from '#/components/Lists'
 
 const LOADING = {_reactKey: '__loading__'}
 const EMPTY = {_reactKey: '__empty__'}
@@ -55,8 +53,7 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
     const opts = React.useMemo(() => ({enabled}), [enabled])
     const {
       data,
-      isFetching,
-      isFetched,
+      isPending,
       hasNextPage,
       fetchNextPage,
       isFetchingNextPage,
@@ -64,15 +61,14 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
       error,
       refetch,
     } = useProfileListsQuery(did, opts)
-    const {isMobile} = useWebMediaQueries()
-    const isEmpty = !isFetching && !data?.pages[0]?.lists.length
+    const isEmpty = !isPending && !data?.pages[0]?.lists.length
 
     const items = React.useMemo(() => {
       let items: any[] = []
       if (isError && isEmpty) {
         items = items.concat([ERROR_ITEM])
       }
-      if (!isFetched || isFetching) {
+      if (isPending) {
         items = items.concat([LOADING])
       } else if (isEmpty) {
         items = items.concat([EMPTY])
@@ -85,7 +81,7 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
         items = items.concat([LOAD_MORE_ERROR_ITEM])
       }
       return items
-    }, [isError, isEmpty, isFetched, isFetching, data])
+    }, [isError, isEmpty, isPending, data])
 
     // events
     // =
@@ -115,13 +111,13 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
     }, [refetch, setIsPTRing])
 
     const onEndReached = React.useCallback(async () => {
-      if (isFetching || !hasNextPage || isError) return
+      if (isFetchingNextPage || !hasNextPage || isError) return
       try {
         await fetchNextPage()
       } catch (err) {
         logger.error('Failed to load more lists', {message: err})
       }
-    }, [isFetching, hasNextPage, isError, fetchNextPage])
+    }, [isFetchingNextPage, hasNextPage, isError, fetchNextPage])
 
     const onPressRetryLoadMore = React.useCallback(() => {
       fetchNextPage()
@@ -182,10 +178,16 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
     }, [enabled, scrollElRef, setScrollViewTag])
 
     const ProfileListsFooter = React.useCallback(() => {
-      return isFetchingNextPage ? (
-        <ActivityIndicator style={[styles.footer]} />
-      ) : null
-    }, [isFetchingNextPage])
+      return (
+        <ListFooter
+          hasNextPage={hasNextPage}
+          isFetchingNextPage={isFetchingNextPage}
+          onRetry={fetchNextPage}
+          error={cleanError(error)}
+          height={180 + headerOffset}
+        />
+      )
+    }, [hasNextPage, error, isFetchingNextPage, headerOffset, fetchNextPage])
 
     return (
       <View testID={testID} style={style}>
@@ -193,16 +195,13 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
           testID={testID ? `${testID}-flatlist` : undefined}
           ref={scrollElRef}
           data={items}
-          keyExtractor={(item: any) => item._reactKey || item.uri}
+          keyExtractor={keyExtractor}
           renderItem={renderItemInner}
           ListFooterComponent={ProfileListsFooter}
           refreshing={isPTRing}
           onRefresh={onRefresh}
           headerOffset={headerOffset}
           progressViewOffset={ios(0)}
-          contentContainerStyle={
-            isMobile && {paddingBottom: headerOffset + 100}
-          }
           removeClippedSubviews={true}
           desktopFixedHeight
           onEndReached={onEndReached}
@@ -212,6 +211,6 @@ export const ProfileLists = React.forwardRef<SectionRef, ProfileListsProps>(
   },
 )
 
-const styles = StyleSheet.create({
-  footer: {paddingTop: 20},
-})
+function keyExtractor(item: any) {
+  return item._reactKey || item.uri
+}
-- 
cgit 1.4.1

