Files
mastodon/app/javascript/flavours/glitch/features/followers/index.tsx
2026-03-26 18:29:11 +01:00

110 lines
3.0 KiB
TypeScript

import { useEffect } from 'react';
import type { FC } from 'react';
import { defineMessage, FormattedMessage } from 'react-intl';
import { useDebouncedCallback } from 'use-debounce';
import {
expandFollowers,
fetchFollowers,
} from '@/flavours/glitch/actions/accounts';
import { useAccount } from '@/flavours/glitch/hooks/useAccount';
import { useAccountId } from '@/flavours/glitch/hooks/useAccountId';
import { useRelationship } from '@/flavours/glitch/hooks/useRelationship';
import { selectUserListWithoutMe } from '@/flavours/glitch/selectors/user_lists';
import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store';
import type { EmptyMessageProps } from './components/empty';
import { BaseEmptyMessage } from './components/empty';
import { AccountListHeader } from './components/header';
import { AccountList } from './components/list';
const titleText = defineMessage({
id: 'followers.title',
defaultMessage: 'Following {name}',
});
const Followers: FC = () => {
const accountId = useAccountId();
const account = useAccount(accountId);
const currentAccountId = useAppSelector(
(state) => (state.meta.get('me') as string | null) ?? null,
);
const followerList = useAppSelector((state) =>
selectUserListWithoutMe(state, 'followers', accountId),
);
const dispatch = useAppDispatch();
useEffect(() => {
if (!followerList && accountId) {
dispatch(fetchFollowers(accountId));
}
}, [accountId, dispatch, followerList]);
const loadMore = useDebouncedCallback(
() => {
if (accountId) {
dispatch(expandFollowers(accountId));
}
},
300,
{ leading: true },
);
const relationship = useRelationship(accountId);
const followerId = relationship?.following ? currentAccountId : null;
const followersExceptMeHidden = !!(
account?.hide_collections &&
followerList?.items.length === 0 &&
followerId
);
const footer = followersExceptMeHidden && (
<div className='empty-column-indicator'>
<FormattedMessage
id='followers.hide_other_followers'
defaultMessage='This user has chosen to not make their other followers visible'
tagName='span'
/>
</div>
);
return (
<AccountList
accountId={accountId}
header={
accountId && (
<AccountListHeader
accountId={accountId}
titleText={titleText}
total={account?.followers_count}
/>
)
}
footer={footer}
emptyMessage={<EmptyMessage account={account} />}
list={followerList}
loadMore={loadMore}
prependAccountId={followerId}
scrollKey='followers'
/>
);
};
const EmptyMessage: FC<EmptyMessageProps> = (props) => (
<BaseEmptyMessage
{...props}
defaultMessage={
<FormattedMessage
id='account.followers.empty'
defaultMessage='No one follows this user yet.'
/>
}
/>
);
// eslint-disable-next-line import/no-default-export -- Used by async components.
export default Followers;