Update followers/following pages
This commit is contained in:
parent
bfe6ab3c26
commit
9c9c790a5f
3 changed files with 21 additions and 63 deletions
|
@ -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),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
Loading…
Reference in a new issue