Update followers/following pages

This commit is contained in:
Alex Gleason 2023-06-25 16:21:27 -05:00
parent bfe6ab3c26
commit 9c9c790a5f
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 21 additions and 63 deletions

View file

@ -5,17 +5,17 @@ import { Account, accountSchema } from 'soapbox/schemas';
import { useRelationships } from './useRelationships'; import { useRelationships } from './useRelationships';
function useFollowing(accountId: string | undefined) { function useFollowing(accountId: string | undefined, type: 'followers' | 'following') {
const api = useApi(); const api = useApi();
const { entities, ...rest } = useEntities( const { entities, ...rest } = useEntities(
[Entities.ACCOUNTS, accountId!, 'following'], [Entities.ACCOUNTS, accountId!, type],
() => api.get(`/api/v1/accounts/${accountId}/following`), () => api.get(`/api/v1/accounts/${accountId}/${type}`),
{ schema: accountSchema, enabled: !!accountId }, { schema: accountSchema, enabled: !!accountId },
); );
const { relationships } = useRelationships( const { relationships } = useRelationships(
[accountId!, 'following'], [accountId!, type],
entities.map(({ id }) => id), entities.map(({ id }) => id),
); );

View file

@ -1,20 +1,12 @@
import { OrderedSet as ImmutableOrderedSet } from 'immutable'; import React from 'react';
import debounce from 'lodash/debounce';
import React, { useCallback, useEffect, useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import {
fetchAccount,
fetchFollowers,
expandFollowers,
fetchAccountByUsername,
} from 'soapbox/actions/accounts';
import { useAccountLookup } from 'soapbox/api/hooks'; import { useAccountLookup } from 'soapbox/api/hooks';
import { useFollowing } from 'soapbox/api/hooks/accounts/useFollowing';
import Account from 'soapbox/components/account';
import MissingIndicator from 'soapbox/components/missing-indicator'; import MissingIndicator from 'soapbox/components/missing-indicator';
import ScrollableList from 'soapbox/components/scrollable-list'; import ScrollableList from 'soapbox/components/scrollable-list';
import { Column, Spinner } from 'soapbox/components/ui'; import { Column, Spinner } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account-container';
import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount } from 'soapbox/hooks';
const messages = defineMessages({ const messages = defineMessages({
heading: { id: 'column.followers', defaultMessage: 'Followers' }, heading: { id: 'column.followers', defaultMessage: 'Followers' },
@ -27,53 +19,19 @@ interface IFollowers {
} }
/** Displays a list of accounts who follow the given account. */ /** Displays a list of accounts who follow the given account. */
const Followers: React.FC<IFollowers> = (props) => { const Followers: React.FC<IFollowers> = ({ params }) => {
const intl = useIntl(); const intl = useIntl();
const dispatch = useAppDispatch();
const features = useFeatures();
const { account: ownAccount } = useOwnAccount();
const [loading, setLoading] = useState(true); const { account, isUnavailable } = useAccountLookup(params?.username);
const username = props.params?.username || ''; const {
const { account } = useAccountLookup(username); accounts,
const isOwnAccount = username.toLowerCase() === ownAccount?.username?.toLowerCase(); hasNextPage,
fetchNextPage,
isLoading,
} = useFollowing(account?.id, 'followers');
const accountIds = useAppSelector(state => state.user_lists.followers.get(account!?.id)?.items || ImmutableOrderedSet<string>()); if (isLoading) {
const hasMore = useAppSelector(state => !!state.user_lists.followers.get(account!?.id)?.next);
const isUnavailable = useAppSelector(state => {
const blockedBy = state.relationships.getIn([account?.id, 'blocked_by']) === true;
return isOwnAccount ? false : (blockedBy && !features.blockersVisible);
});
const handleLoadMore = useCallback(debounce(() => {
if (account) {
dispatch(expandFollowers(account.id));
}
}, 300, { leading: true }), [account?.id]);
useEffect(() => {
let promises = [];
if (account) {
promises = [
dispatch(fetchAccount(account.id)),
dispatch(fetchFollowers(account.id)),
];
} else {
promises = [
dispatch(fetchAccountByUsername(username)),
];
}
Promise.all(promises)
.then(() => setLoading(false))
.catch(() => setLoading(false));
}, [account?.id, username]);
if (loading && accountIds.isEmpty()) {
return ( return (
<Spinner /> <Spinner />
); );
@ -97,13 +55,13 @@ const Followers: React.FC<IFollowers> = (props) => {
<Column label={intl.formatMessage(messages.heading)} transparent> <Column label={intl.formatMessage(messages.heading)} transparent>
<ScrollableList <ScrollableList
scrollKey='followers' scrollKey='followers'
hasMore={hasMore} hasMore={hasNextPage}
onLoadMore={handleLoadMore} onLoadMore={fetchNextPage}
emptyMessage={<FormattedMessage id='account.followers.empty' defaultMessage='No one follows this user yet.' />} emptyMessage={<FormattedMessage id='account.followers.empty' defaultMessage='No one follows this user yet.' />}
itemClassName='pb-4' itemClassName='pb-4'
> >
{accountIds.map(id => {accounts.map((account) =>
<AccountContainer key={id} id={id} />, <Account key={account.id} account={account} />,
)} )}
</ScrollableList> </ScrollableList>
</Column> </Column>

View file

@ -29,7 +29,7 @@ const Following: React.FC<IFollowing> = ({ params }) => {
hasNextPage, hasNextPage,
fetchNextPage, fetchNextPage,
isLoading, isLoading,
} = useFollowing(account?.id); } = useFollowing(account?.id, 'following');
if (isLoading) { if (isLoading) {
return ( return (