diff options
author | Samuel Newman <mozzius@protonmail.com> | 2025-04-02 00:19:59 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-01 14:19:59 -0700 |
commit | 318b29d3fd7d22895ed6ba9a8daff6f296d7dd58 (patch) | |
tree | b8bc10dc22c9cafc8b06531019c9045446552b9b /src/view/com | |
parent | 4db3ccbec7bbe9659911ce09db23320d3f0ab2eb (diff) | |
download | voidsky-318b29d3fd7d22895ed6ba9a8daff6f296d7dd58.tar.zst |
Fix loading jumps and footer on feeds tab (#8063)
* Fix loading jumps and footer on feeds tab * same for lists/starter packs
Diffstat (limited to 'src/view/com')
-rw-r--r-- | src/view/com/feeds/ProfileFeedgens.tsx | 53 | ||||
-rw-r--r-- | src/view/com/lists/ProfileLists.tsx | 55 |
2 files changed, 54 insertions, 54 deletions
diff --git a/src/view/com/feeds/ProfileFeedgens.tsx b/src/view/com/feeds/ProfileFeedgens.tsx index b55c6b9bd..2bf95de48 100644 --- a/src/view/com/feeds/ProfileFeedgens.tsx +++ b/src/view/com/feeds/ProfileFeedgens.tsx @@ -1,30 +1,28 @@ 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 {usePreferencesQuery} from '#/state/queries/preferences' import {RQKEY, useProfileFeedgensQuery} from '#/state/queries/profile-feedgens' 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 FeedCard from '#/components/FeedCard' -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__'} @@ -58,8 +56,7 @@ export const ProfileFeedgens = React.forwardRef< const opts = React.useMemo(() => ({enabled}), [enabled]) const { data, - isFetching, - isFetched, + isPending, isFetchingNextPage, hasNextPage, fetchNextPage, @@ -67,16 +64,15 @@ export const ProfileFeedgens = React.forwardRef< error, refetch, } = useProfileFeedgensQuery(did, opts) - const isEmpty = !isFetching && !data?.pages[0]?.feeds.length + const isEmpty = !isPending && !data?.pages[0]?.feeds.length const {data: preferences} = usePreferencesQuery() - const {isMobile} = useWebMediaQueries() 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]) @@ -88,7 +84,7 @@ export const ProfileFeedgens = React.forwardRef< items = items.concat([LOAD_MORE_ERROR_ITEM]) } return items - }, [isError, isEmpty, isFetched, isFetching, data]) + }, [isError, isEmpty, isPending, data]) // events // = @@ -118,14 +114,14 @@ export const ProfileFeedgens = React.forwardRef< }, [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 feeds', {message: err}) } - }, [isFetching, hasNextPage, isError, fetchNextPage]) + }, [isFetchingNextPage, hasNextPage, isError, fetchNextPage]) const onPressRetryLoadMore = React.useCallback(() => { fetchNextPage() @@ -186,10 +182,16 @@ export const ProfileFeedgens = React.forwardRef< }, [enabled, scrollElRef, setScrollViewTag]) const ProfileFeedgensFooter = 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}> @@ -197,14 +199,13 @@ export const ProfileFeedgens = React.forwardRef< testID={testID ? `${testID}-flatlist` : undefined} ref={scrollElRef} data={items} - keyExtractor={(item: any) => item._reactKey || item.uri} + keyExtractor={keyExtractor} renderItem={renderItem} ListFooterComponent={ProfileFeedgensFooter} refreshing={isPTRing} onRefresh={onRefresh} headerOffset={headerOffset} progressViewOffset={ios(0)} - contentContainerStyle={isMobile && {paddingBottom: headerOffset + 100}} removeClippedSubviews={true} desktopFixedHeight onEndReached={onEndReached} @@ -213,6 +214,6 @@ export const ProfileFeedgens = React.forwardRef< ) }) -const styles = StyleSheet.create({ - footer: {paddingTop: 20}, -}) +function keyExtractor(item: any) { + return item._reactKey || item.uri +} 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 +} |