refactor: move the remaining tail-only lists onto ListTail
4 unmodified lines567899111011121314155 unmodified lines21222324252526272828293031323334353637303132334 unmodified lines383940415042434445461 unmodified line484950516052535455646566676869565758596061626364656632 unmodified lines4 unmodified linesimport { useModerationOpts } from '#/state/moderation/moderation-opts';import { useMyBlockedAccountsQuery } from '#/state/queries/my-blocked-accounts';import { useTitle } from '#/state/use-title';
import { ErrorScreen } from '#/components/ErrorScreen';import { List } from '#/components/List/List';import { ListFooter } from '#/components/Lists';import { ListError } from '#/components/List/ListError';import * as ListTail from '#/components/List/ListTail';import { Text } from '#/components/Text';import * as Layout from '#/components/web/Layout';import * as ProfileCard from '#/components/web/ProfileCard';
5 unmodified lines
export function ModerationBlockedAccounts() { useTitle(m['common.block.accountsTitle']());
const { data, isFetching, isError, error, refetch, hasNextPage, fetchNextPage, isFetchingNextPage } = const { data, isPending, isError, error, refetch, fetchNextPage, isFetchingNextPage } = useMyBlockedAccountsQuery(); const profiles = data?.pages ? data.pages.flatMap((page) => page.blocks) : []; const isEmpty = !isFetching && profiles.length === 0; const isEmpty = !isPending && profiles.length === 0;
const onEndReached = () => { if (isFetching || !hasNextPage || isError) { return; }
void fetchNextPage(); };
return ( <Layout.Screen> <Layout.Header.Outer> <Layout.Header.BackButton />4 unmodified lines {isEmpty ? ( <div> <Info /> {isError ? ( <ErrorScreen title="Oops!" message={cleanError(error)} onPressTryAgain={() => void refetch()} /> <ListError hideBackButton message={cleanError(error)} onRetry={() => void refetch()} /> ) : ( <Empty /> )} </div>1 unmodified line <List data={profiles} estimateHeight={PROFILE_ITEM_HEIGHT_ESTIMATE} keyExtractor={(item: ActorDefs.ProfileView) => item.did} onEndReached={onEndReached} onEndReached={() => void fetchNextPage()} renderItem={({ item, index }) => <BlockedRow index={index} profile={item} />} ListHeaderComponent={<Info />} ListFooterComponent={ <ListFooter isFetchingNextPage={isFetchingNextPage} hasNextPage={hasNextPage} error={cleanError(error)} onRetry={fetchNextPage} /> <ListTail.Frame> {isFetchingNextPage ? ( <ListTail.Pending /> ) : isError ? ( <ListTail.Error message={cleanError(error)} onRetry={() => void fetchNextPage()} /> ) : null} </ListTail.Frame> } /> )} </Layout.Screen>32 unmodified lines4 unmodified lines567899111011121314156 unmodified lines22232425262627282929303132333435363738313233344 unmodified lines394041425143444546471 unmodified line495051526153545556656667686970575859606162636465666743 unmodified lines4 unmodified linesimport { useModerationOpts } from '#/state/moderation/moderation-opts';import { useMyMutedAccountsQuery } from '#/state/queries/my-muted-accounts';import { useTitle } from '#/state/use-title';
import { ErrorScreen } from '#/components/ErrorScreen';import { List } from '#/components/List/List';import { ListFooter } from '#/components/Lists';import { ListError } from '#/components/List/ListError';import * as ListTail from '#/components/List/ListTail';import { Text } from '#/components/Text';import * as Layout from '#/components/web/Layout';import * as ProfileCard from '#/components/web/ProfileCard';import * as profileCardCss from '#/components/web/ProfileCard.css';6 unmodified lines
export function ModerationMutedAccounts() { useTitle(m['common.mute.accountsTitle']());
const { data, isFetching, isError, error, refetch, hasNextPage, fetchNextPage, isFetchingNextPage } = const { data, isPending, isError, error, refetch, fetchNextPage, isFetchingNextPage } = useMyMutedAccountsQuery(); const profiles = data?.pages ? data.pages.flatMap((page) => page.mutes) : []; const isEmpty = !isFetching && profiles.length === 0; const isEmpty = !isPending && profiles.length === 0;
const onEndReached = () => { if (isFetching || !hasNextPage || isError) { return; }
void fetchNextPage(); };
return ( <Layout.Screen> <Layout.Header.Outer> <Layout.Header.BackButton />4 unmodified lines {isEmpty ? ( <div> <Info /> {isError ? ( <ErrorScreen title="Oops!" message={cleanError(error)} onPressTryAgain={() => void refetch()} /> <ListError hideBackButton message={cleanError(error)} onRetry={() => void refetch()} /> ) : ( <Empty /> )} </div>1 unmodified line <List data={profiles} estimateHeight={PROFILE_ITEM_HEIGHT_ESTIMATE} keyExtractor={(item) => item.did} onEndReached={onEndReached} onEndReached={() => void fetchNextPage()} renderItem={({ item, index }) => <MutedRow index={index} profile={item} />} ListHeaderComponent={<Info />} ListFooterComponent={ <ListFooter isFetchingNextPage={isFetchingNextPage} hasNextPage={hasNextPage} error={cleanError(error)} onRetry={fetchNextPage} /> <ListTail.Frame> {isFetchingNextPage ? ( <ListTail.Pending /> ) : isError ? ( <ListTail.Error message={cleanError(error)} onRetry={() => void fetchNextPage()} /> ) : null} </ListTail.Frame> } /> )} </Layout.Screen>43 unmodified lines18 unmodified lines19202122232324252627208 unmodified linesExpand all23623723823924024024124224324424524643 unmodified lines29029129229329229429529629729845 unmodified lines34434534634734634834935035135235335436 unmodified lines3913923933943913953963973983994004012 unmodified lines18 unmodified linesimport { CenteredSpinner } from '#/components/CenteredSpinner';import { signinDialogHandle } from '#/components/dialogs/handles';import * as FeedCard from '#/components/FeedCard';import { List } from '#/components/List/List';import { ListFooter } from '#/components/Lists';import * as ListTail from '#/components/List/ListTail';import { Post } from '#/components/Post/Post';import { SearchError } from '#/components/SearchError';import * as StarterPackCard from '#/components/StarterPack/StarterPackCard';import { type Section, Tabs } from '#/components/Tabs';208 unmodified linesExpand all <List data={items} estimateHeight={POST_ITEM_HEIGHT_ESTIMATE} keyExtractor={(item) => item.uri} ListFooterComponent={<ListFooter hasNextPage={hasNextPage} isFetchingNextPage={isFetchingNextPage} />} ListFooterComponent={ <ListTail.Frame>{isFetchingNextPage ? <ListTail.Pending /> : null}</ListTail.Frame> } onEndReached={onEndReached} renderItem={({ index, item }) => <SearchPost position={index} post={item} />} /> );43 unmodified lines data={profiles} estimateHeight={PROFILE_ITEM_HEIGHT_ESTIMATE} keyExtractor={(item) => item.did} ListFooterComponent={ <ListFooter hasNextPage={hasNextPage && hasSession} isFetchingNextPage={isFetchingNextPage} /> <ListTail.Frame>{isFetchingNextPage ? <ListTail.Pending /> : null}</ListTail.Frame> } onEndReached={onEndReached} // the sticky tab bar already draws the divider above the first row renderItem={({ index, item }) => <SearchProfileCard profile={item} topBorder={index !== 0} />}45 unmodified lines <List data={starterPacks} estimateHeight={STARTER_PACK_ITEM_HEIGHT_ESTIMATE} keyExtractor={(item) => item.uri} ListFooterComponent={<ListFooter hasNextPage={hasNextPage} isFetchingNextPage={isFetchingNextPage} />} ListFooterComponent={ <ListTail.Frame>{isFetchingNextPage ? <ListTail.Pending /> : null}</ListTail.Frame> } onEndReached={onEndReached} // the sticky tab bar already draws the divider above the first row renderItem={({ index, item }) => <StarterPackCard.Default starterPack={item} topBorder={index !== 0} />} />36 unmodified lines <List data={feeds} estimateHeight={FEED_ITEM_HEIGHT_ESTIMATE} keyExtractor={(item) => item.uri} ListFooterComponent={<ListFooter hasNextPage={hasNextPage} isFetchingNextPage={isFetchingNextPage} />} ListFooterComponent={ <ListTail.Frame>{isFetchingNextPage ? <ListTail.Pending /> : null}</ListTail.Frame> } onEndReached={onEndReached} // the sticky tab bar already draws the divider above the first row renderItem={({ index, item }) => <FeedCard.Default topBorder={index !== 0} view={item} />} />2 unmodified lines123455678910 unmodified lines202122232424252627import type { AppBskyFeedDefs } from '@atcute/bluesky';
import * as FeedCard from '#/components/FeedCard';import { List } from '#/components/List/List';import { ListFooter } from '#/components/Lists';import * as ListTail from '#/components/List/ListTail';
const FEED_ITEM_HEIGHT_ESTIMATE = 164;
function keyExtractor(item: AppBskyFeedDefs.GeneratorView) {10 unmodified lines data={feeds} estimateHeight={FEED_ITEM_HEIGHT_ESTIMATE} renderItem={({ index, item }) => <FeedCard.Default view={item} topBorder={index !== 0} />} keyExtractor={keyExtractor} ListFooterComponent={<ListFooter />} ListFooterComponent={<ListTail.Frame />} /> );}15 unmodified lines1617181920202122232480 unmodified lines10510610710810911011111211311410911011111211311411511611711811994 unmodified lines15 unmodified lines
import { SubscribeProfileDialog } from '#/components/activity-notifications/SubscribeProfileDialog';import * as Dialog from '#/components/Dialog';import { List } from '#/components/List/List';import { ListFooter } from '#/components/Lists';import * as ListTail from '#/components/List/ListTail';import * as Settings from '#/components/SettingsCards';import { Text } from '#/components/Text';import { Admonition } from '#/components/web/Admonition';import { Button, ButtonText } from '#/components/web/Button';80 unmodified lines </> } ListEmptyComponent={isPending || error ? null : <EmptyHint />} ListFooterComponent={ <ListFooter error={cleanError(error)} hasNextPage={hasNextPage} isFetchingNextPage={isFetchingNextPage} onRetry={fetchNextPage} /> <ListTail.Frame> {isFetchingNextPage ? ( <ListTail.Pending /> ) : error ? ( <ListTail.Error message={cleanError(error)} onRetry={() => void fetchNextPage()} /> ) : null} </ListTail.Frame> } onEndReached={onEndReached} onEndReachedThreshold={2} renderItem={({ item }) =>94 unmodified lines