import {useCallback, useEffect, useImperativeHandle, useState} from 'react' import {findNodeHandle, View} from 'react-native' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {Trans} from '@lingui/react/macro' import {useQueryClient} from '@tanstack/react-query' import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' import { type FeedDescriptor, RQKEY as FEED_RQKEY, } from '#/state/queries/post-feed' import {truncateAndInvalidate} from '#/state/queries/util' import {PostFeed} from '#/view/com/posts/PostFeed' import { EmptyState, type EmptyStateButtonProps, } from '#/view/com/util/EmptyState' import {type ListRef} from '#/view/com/util/List' import {LoadLatestBtn} from '#/view/com/util/load-latest/LoadLatestBtn' import {atoms as a, ios, useTheme} from '#/alf' import {EditBig_Stroke1_Corner0_Rounded as EditIcon} from '#/components/icons/EditBig' import {Text} from '#/components/Typography' import {IS_IOS, IS_NATIVE} from '#/env' import {type SectionRef} from './types' interface FeedSectionProps { ref?: React.Ref feed: FeedDescriptor headerHeight: number collapsedHeaderHeight: number isFocused: boolean scrollElRef: ListRef ignoreFilterFor?: string setScrollViewTag: (tag: number | null) => void emptyStateMessage?: string emptyStateButton?: EmptyStateButtonProps emptyStateIcon?: React.ComponentType | React.ReactElement } export function ProfileFeedSection({ ref, feed, headerHeight, collapsedHeaderHeight, isFocused, scrollElRef, ignoreFilterFor, setScrollViewTag, emptyStateMessage, emptyStateButton, emptyStateIcon, }: FeedSectionProps) { const {_} = useLingui() const queryClient = useQueryClient() const [hasNew, setHasNew] = useState(false) const [isScrolledDown, setIsScrolledDown] = useState(false) const shouldUseAdjustedNumToRender = feed.endsWith('posts_and_author_threads') const isVideoFeed = IS_NATIVE && feed.endsWith('posts_with_video') const adjustedInitialNumToRender = useInitialNumToRender({ screenHeightOffset: headerHeight, }) const onScrollToTop = useCallback(() => { scrollElRef.current?.scrollToOffset({ animated: IS_NATIVE, offset: -headerHeight, }) truncateAndInvalidate(queryClient, FEED_RQKEY(feed)) setHasNew(false) }, [scrollElRef, headerHeight, queryClient, feed, setHasNew]) useImperativeHandle(ref, () => ({ scrollToTop: onScrollToTop, })) const renderPostsEmpty = useCallback(() => { return ( ) }, [_, emptyStateButton, emptyStateIcon, emptyStateMessage]) useEffect(() => { if (IS_IOS && isFocused && scrollElRef.current) { const nativeTag = findNodeHandle(scrollElRef.current) setScrollViewTag(nativeTag) } }, [isFocused, scrollElRef, setScrollViewTag]) return ( {(isScrolledDown || hasNew) && ( )} ) } function ProfileEndOfFeed() { const t = useTheme() return ( End of feed ) }