From ef253a5516bdcaeddceb71637cf99225e97cf1d4 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 10 Sep 2025 19:59:26 +0300 Subject: [PATCH] use ListFooter for notifications feed --- .../com/notifications/NotificationFeed.tsx | 97 +++++++------------ 1 file changed, 33 insertions(+), 64 deletions(-) diff --git a/src/view/com/notifications/NotificationFeed.tsx b/src/view/com/notifications/NotificationFeed.tsx index ca4ba98146..0e34afd504 100644 --- a/src/view/com/notifications/NotificationFeed.tsx +++ b/src/view/com/notifications/NotificationFeed.tsx @@ -1,35 +1,31 @@ -import React from 'react' -import { - ActivityIndicator, - type ListRenderItemInfo, - StyleSheet, - View, -} from 'react-native' +import {useCallback, useMemo, useState} from 'react' +import {type ListRenderItemInfo, View} from 'react-native' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' import {cleanError} from '#/lib/strings/errors' -import {s} from '#/lib/styles' import {logger} from '#/logger' import {useModerationOpts} from '#/state/preferences/moderation-opts' -import {useNotificationFeedQuery} from '#/state/queries/notifications/feed' +import { + type FeedNotification, + useNotificationFeedQuery, +} from '#/state/queries/notifications/feed' import {EmptyState} from '#/view/com/util/EmptyState' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {List, type ListProps, type ListRef} from '#/view/com/util/List' import {NotificationFeedLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' -import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn' +import {atoms as a} from '#/alf' +import {ListFooter} from '#/components/Lists' import {NotificationFeedItem} from './NotificationFeedItem' const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} -const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'} const LOADING_ITEM = {_reactKey: '__loading__'} export function NotificationFeed({ filter, enabled, scrollElRef, - onPressTryAgain, onScrolledDownChange, ListHeaderComponent, refreshNotifications, @@ -37,13 +33,12 @@ export function NotificationFeed({ filter: 'all' | 'mentions' enabled: boolean scrollElRef?: ListRef - onPressTryAgain?: () => void onScrolledDownChange: (isScrolledDown: boolean) => void ListHeaderComponent?: ListProps['ListHeaderComponent'] refreshNotifications: () => Promise }) { const initialNumToRender = useInitialNumToRender() - const [isPTRing, setIsPTRing] = React.useState(false) + const [isPTRing, setIsPTRing] = useState(false) const {_} = useLingui() const moderationOpts = useModerationOpts() const { @@ -55,6 +50,7 @@ export function NotificationFeed({ hasNextPage, isFetchingNextPage, fetchNextPage, + refetch, } = useNotificationFeedQuery({ enabled: enabled && !!moderationOpts, filter, @@ -67,8 +63,8 @@ export function NotificationFeed({ const isEmpty = !isFetching && !data?.pages.find(page => page.items.length > 0) - const items = React.useMemo(() => { - let arr: any[] = [] + const items = useMemo(() => { + let arr: (FeedNotification | {_reactKey: string})[] = [] if (isFetched) { if (isEmpty) { arr = arr.concat([EMPTY_FEED_ITEM]) @@ -77,16 +73,13 @@ export function NotificationFeed({ arr = arr.concat(page.items) } } - if (isError && !isEmpty) { - arr = arr.concat([LOAD_MORE_ERROR_ITEM]) - } } else { arr.push(LOADING_ITEM) } return arr - }, [isFetched, isError, isEmpty, data]) + }, [isFetched, isEmpty, data]) - const onRefresh = React.useCallback(async () => { + const onRefresh = useCallback(async () => { try { setIsPTRing(true) await refreshNotifications() @@ -99,7 +92,7 @@ export function NotificationFeed({ } }, [refreshNotifications, setIsPTRing]) - const onEndReached = React.useCallback(async () => { + const onEndReached = useCallback(async () => { if (isFetching || !hasNextPage || isError) return try { @@ -109,27 +102,14 @@ export function NotificationFeed({ } }, [isFetching, hasNextPage, isError, fetchNextPage]) - const onPressRetryLoadMore = React.useCallback(() => { - fetchNextPage() - }, [fetchNextPage]) - - const renderItem = React.useCallback( - ({item, index}: ListRenderItemInfo) => { + const renderItem = useCallback( + ({item, index}: ListRenderItemInfo) => { if (item === EMPTY_FEED_ITEM) { return ( - ) - } else if (item === LOAD_MORE_ERROR_ITEM) { - return ( - ) } else if (item === LOADING_ITEM) { @@ -144,28 +124,13 @@ export function NotificationFeed({ /> ) }, - [moderationOpts, _, onPressRetryLoadMore, filter], - ) - - const FeedFooter = React.useCallback( - () => - isFetchingNextPage ? ( - - - - ) : ( - - ), - [isFetchingNextPage], + [moderationOpts, _, filter], ) return ( - - {error && ( - + + {error && isEmpty && ( + )} item._reactKey} renderItem={renderItem} ListHeaderComponent={ListHeaderComponent} - ListFooterComponent={FeedFooter} + ListFooterComponent={ + isFetched && !isEmpty ? ( + + ) : null + } refreshing={isPTRing} onRefresh={onRefresh} onEndReached={onEndReached} onEndReachedThreshold={2} onScrolledDownChange={onScrolledDownChange} - contentContainerStyle={s.contentContainer} desktopFixedHeight initialNumToRender={initialNumToRender} windowSize={11} @@ -190,8 +164,3 @@ export function NotificationFeed({ ) } - -const styles = StyleSheet.create({ - feedFooter: {paddingTop: 20}, - emptyState: {paddingVertical: 40}, -})