import React, {MutableRefObject} from 'react' import { ActivityIndicator, RefreshControl, StyleProp, StyleSheet, View, ViewStyle, FlatList, } from 'react-native' import {AppBskyActorDefs, AppBskyGraphDefs, RichText} from '@atproto/api' import {observer} from 'mobx-react-lite' 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 {Text} from '../util/text/Text' import {RichText as RichTextCom} from '../util/text/RichText' import {UserAvatar} from '../util/UserAvatar' import {TextLink} from '../util/Link' import {ListModel} from 'state/models/content/list' import {useAnalytics} from 'lib/analytics/analytics' import {usePalette} from 'lib/hooks/usePalette' import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries' import {useStores} from 'state/index' import {s} from 'lib/styles' import {ListActions} from './ListActions' import {makeProfileLink} from 'lib/routes/links' import {sanitizeHandle} from 'lib/strings/handles' const LOADING_ITEM = {_reactKey: '__loading__'} const HEADER_ITEM = {_reactKey: '__header__'} const EMPTY_ITEM = {_reactKey: '__empty__'} const ERROR_ITEM = {_reactKey: '__error__'} const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'} export const ListItems = observer(function ListItemsImpl({ list, style, scrollElRef, onPressTryAgain, onToggleSubscribed, onPressEditList, onPressDeleteList, onPressShareList, onPressReportList, renderEmptyState, testID, headerOffset = 0, }: { list: ListModel style?: StyleProp scrollElRef?: MutableRefObject | null> onPressTryAgain?: () => void onToggleSubscribed: () => void onPressEditList: () => void onPressDeleteList: () => void onPressShareList: () => void onPressReportList: () => void renderEmptyState?: () => JSX.Element testID?: string headerOffset?: number }) { const pal = usePalette('default') const store = useStores() const {track} = useAnalytics() const [isRefreshing, setIsRefreshing] = React.useState(false) const data = React.useMemo(() => { let items: any[] = [HEADER_ITEM] if (list.hasLoaded) { if (list.hasError) { items = items.concat([ERROR_ITEM]) } if (list.isEmpty) { items = items.concat([EMPTY_ITEM]) } else { items = items.concat(list.items) } if (list.loadMoreError) { items = items.concat([LOAD_MORE_ERROR_ITEM]) } } else if (list.isLoading) { items = items.concat([LOADING_ITEM]) } return items }, [ list.hasError, list.hasLoaded, list.isLoading, list.isEmpty, list.items, list.loadMoreError, ]) // events // = const onRefresh = React.useCallback(async () => { track('Lists:onRefresh') setIsRefreshing(true) try { await list.refresh() } catch (err) { list.rootStore.log.error('Failed to refresh lists', err) } setIsRefreshing(false) }, [list, track, setIsRefreshing]) const onEndReached = React.useCallback(async () => { track('Lists:onEndReached') try { await list.loadMore() } catch (err) { list.rootStore.log.error('Failed to load more lists', err) } }, [list, track]) const onPressRetryLoadMore = React.useCallback(() => { list.retryLoadMore() }, [list]) const onPressEditMembership = React.useCallback( (profile: AppBskyActorDefs.ProfileViewBasic) => { store.shell.openModal({ name: 'list-add-remove-user', subject: profile.did, displayName: profile.displayName || profile.handle, onUpdate() { list.refresh() }, }) }, [store, list], ) // rendering // = const renderMemberButton = React.useCallback( (profile: AppBskyActorDefs.ProfileViewBasic) => { if (!list.isOwner) { return null } return (