diff --git a/app/soapbox/api/hooks/accounts/useBlocks.ts b/app/soapbox/api/hooks/accounts/useBlocks.ts new file mode 100644 index 000000000..d9867e50c --- /dev/null +++ b/app/soapbox/api/hooks/accounts/useBlocks.ts @@ -0,0 +1,31 @@ +import { Entities } from 'soapbox/entity-store/entities'; +import { useEntities } from 'soapbox/entity-store/hooks'; +import { useApi, useLoggedIn } from 'soapbox/hooks'; +import { Account, accountSchema } from 'soapbox/schemas'; + +import { useRelationships } from './useRelationships'; + +function useBlocks(type: 'blocks' | 'mutes' = 'blocks') { + const api = useApi(); + const { isLoggedIn } = useLoggedIn(); + + const { entities, ...rest } = useEntities( + [Entities.ACCOUNTS, type], + () => api.get(`/api/v1/${type}`), + { schema: accountSchema, enabled: isLoggedIn }, + ); + + const { relationships } = useRelationships( + [type], + entities.map(({ id }) => id), + ); + + const accounts: Account[] = entities.map((account) => ({ + ...account, + relationship: relationships[account.id], + })); + + return { accounts, ...rest }; +} + +export { useBlocks }; \ No newline at end of file diff --git a/app/soapbox/api/hooks/index.ts b/app/soapbox/api/hooks/index.ts index 6da6de49e..da7a77ef6 100644 --- a/app/soapbox/api/hooks/index.ts +++ b/app/soapbox/api/hooks/index.ts @@ -2,6 +2,7 @@ // Accounts export { useAccount } from './accounts/useAccount'; export { useAccountLookup } from './accounts/useAccountLookup'; +export { useBlocks } from './accounts/useBlocks'; export { useFollow } from './accounts/useFollow'; export { useFollowing } from './accounts/useFollowing'; export { useRelationships } from './accounts/useRelationships'; diff --git a/app/soapbox/features/blocks/index.tsx b/app/soapbox/features/blocks/index.tsx index c9d8a50c5..cc3f2ab50 100644 --- a/app/soapbox/features/blocks/index.tsx +++ b/app/soapbox/features/blocks/index.tsx @@ -1,33 +1,26 @@ -import debounce from 'lodash/debounce'; import React from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { fetchBlocks, expandBlocks } from 'soapbox/actions/blocks'; +import { useBlocks } from 'soapbox/api/hooks'; +import Account from 'soapbox/components/account'; import ScrollableList from 'soapbox/components/scrollable-list'; import { Column, Spinner } from 'soapbox/components/ui'; -import AccountContainer from 'soapbox/containers/account-container'; -import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; const messages = defineMessages({ heading: { id: 'column.blocks', defaultMessage: 'Blocked users' }, }); -const handleLoadMore = debounce((dispatch) => { - dispatch(expandBlocks()); -}, 300, { leading: true }); - const Blocks: React.FC = () => { - const dispatch = useAppDispatch(); const intl = useIntl(); - const accountIds = useAppSelector((state) => state.user_lists.blocks.items); - const hasMore = useAppSelector((state) => !!state.user_lists.blocks.next); + const { + accounts, + hasNextPage, + fetchNextPage, + isLoading, + } = useBlocks(); - React.useEffect(() => { - dispatch(fetchBlocks()); - }, []); - - if (!accountIds) { + if (isLoading) { return ( @@ -41,14 +34,14 @@ const Blocks: React.FC = () => { handleLoadMore(dispatch)} - hasMore={hasMore} + onLoadMore={fetchNextPage} + hasMore={hasNextPage} emptyMessage={emptyMessage} itemClassName='pb-4' > - {accountIds.map((id) => - , - )} + {accounts.map((account) => ( + + ))} ); diff --git a/app/soapbox/features/mutes/index.tsx b/app/soapbox/features/mutes/index.tsx index 818fdec57..618a219d4 100644 --- a/app/soapbox/features/mutes/index.tsx +++ b/app/soapbox/features/mutes/index.tsx @@ -1,33 +1,26 @@ -import debounce from 'lodash/debounce'; import React from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { fetchMutes, expandMutes } from 'soapbox/actions/mutes'; +import { useBlocks } from 'soapbox/api/hooks'; +import Account from 'soapbox/components/account'; import ScrollableList from 'soapbox/components/scrollable-list'; import { Column, Spinner } from 'soapbox/components/ui'; -import AccountContainer from 'soapbox/containers/account-container'; -import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; const messages = defineMessages({ heading: { id: 'column.mutes', defaultMessage: 'Muted users' }, }); -const handleLoadMore = debounce((dispatch) => { - dispatch(expandMutes()); -}, 300, { leading: true }); - const Mutes: React.FC = () => { - const dispatch = useAppDispatch(); const intl = useIntl(); - const accountIds = useAppSelector((state) => state.user_lists.mutes.items); - const hasMore = useAppSelector((state) => !!state.user_lists.mutes.next); + const { + accounts, + hasNextPage, + fetchNextPage, + isLoading, + } = useBlocks('mutes'); - React.useEffect(() => { - dispatch(fetchMutes()); - }, []); - - if (!accountIds) { + if (isLoading) { return ( @@ -41,14 +34,14 @@ const Mutes: React.FC = () => { handleLoadMore(dispatch)} - hasMore={hasMore} + onLoadMore={fetchNextPage} + hasMore={hasNextPage} emptyMessage={emptyMessage} itemClassName='pb-4' > - {accountIds.map((id) => - , - )} + {accounts.map((account) => ( + + ))} );