import React from 'react' import { ActivityIndicator, Dimensions, StyleProp, View, ViewStyle, } from 'react-native' import {AppBskyActorDefs, AppBskyGraphDefs} from '@atproto/api' import {List, ListRef} from '../util/List' import {ProfileCardFeedLoadingPlaceholder} from '../util/LoadingPlaceholder' import {ErrorMessage} from '../util/error/ErrorMessage' import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn' import {ProfileCard} from '../profile/ProfileCard' import {Button} from '../util/forms/Button' import {useAnalytics} from 'lib/analytics/analytics' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useListMembersQuery} from '#/state/queries/list-members' import {logger} from '#/logger' import {useModalControls} from '#/state/modals' import {useSession} from '#/state/session' import {cleanError} from '#/lib/strings/errors' import {useLingui} from '@lingui/react' import {msg} from '@lingui/macro' const LOADING_ITEM = {_reactKey: '__loading__'} const EMPTY_ITEM = {_reactKey: '__empty__'} const ERROR_ITEM = {_reactKey: '__error__'} const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'} export function ListMembers({ list, style, scrollElRef, onScrolledDownChange, onPressTryAgain, renderHeader, renderEmptyState, testID, headerOffset = 0, desktopFixedHeightOffset, }: { list: string style?: StyleProp scrollElRef?: ListRef onScrolledDownChange: (isScrolledDown: boolean) => void onPressTryAgain?: () => void renderHeader: () => JSX.Element renderEmptyState: () => JSX.Element testID?: string headerOffset?: number desktopFixedHeightOffset?: number }) { const {track} = useAnalytics() const {_} = useLingui() const [isRefreshing, setIsRefreshing] = React.useState(false) const {isMobile} = useWebMediaQueries() const {openModal} = useModalControls() const {currentAccount} = useSession() const { data, isFetching, isFetched, isError, error, refetch, fetchNextPage, hasNextPage, } = useListMembersQuery(list) const isEmpty = !isFetching && !data?.pages[0].items.length const isOwner = currentAccount && data?.pages[0].list.creator.did === currentAccount.did const items = React.useMemo(() => { let items: any[] = [] if (isFetched) { if (isEmpty && isError) { items = items.concat([ERROR_ITEM]) } if (isEmpty) { items = items.concat([EMPTY_ITEM]) } else if (data) { for (const page of data.pages) { items = items.concat(page.items) } } if (!isEmpty && isError) { items = items.concat([LOAD_MORE_ERROR_ITEM]) } } else if (isFetching) { items = items.concat([LOADING_ITEM]) } return items }, [isFetched, isEmpty, isError, data, isFetching]) // events // = const onRefresh = React.useCallback(async () => { track('Lists:onRefresh') setIsRefreshing(true) try { await refetch() } catch (err) { logger.error('Failed to refresh lists', {message: err}) } setIsRefreshing(false) }, [refetch, track, setIsRefreshing]) const onEndReached = React.useCallback(async () => { if (isFetching || !hasNextPage || isError) return track('Lists:onEndReached') try { await fetchNextPage() } catch (err) { logger.error('Failed to load more lists', {message: err}) } }, [isFetching, hasNextPage, isError, fetchNextPage, track]) const onPressRetryLoadMore = React.useCallback(() => { fetchNextPage() }, [fetchNextPage]) const onPressEditMembership = React.useCallback( (profile: AppBskyActorDefs.ProfileViewBasic) => { openModal({ name: 'user-add-remove-lists', subject: profile.did, displayName: profile.displayName || profile.handle, handle: profile.handle, }) }, [openModal], ) // rendering // = const renderMemberButton = React.useCallback( (profile: AppBskyActorDefs.ProfileViewBasic) => { if (!isOwner) { return null } return (