From ad1718b5f9027819923145ac04fe66fc373c82fe Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 22 Jun 2023 23:17:40 -0500 Subject: [PATCH] Add useFollow, useChangeEntity hooks --- app/soapbox/api/hooks/accounts/useFollow.ts | 57 +++++++++++++++++++ app/soapbox/api/hooks/index.ts | 15 ++--- app/soapbox/entity-store/hooks/index.ts | 3 +- .../entity-store/hooks/useChangeEntity.ts | 24 ++++++++ 4 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 app/soapbox/api/hooks/accounts/useFollow.ts create mode 100644 app/soapbox/entity-store/hooks/useChangeEntity.ts diff --git a/app/soapbox/api/hooks/accounts/useFollow.ts b/app/soapbox/api/hooks/accounts/useFollow.ts new file mode 100644 index 000000000..fe2e7645d --- /dev/null +++ b/app/soapbox/api/hooks/accounts/useFollow.ts @@ -0,0 +1,57 @@ +import { Entities } from 'soapbox/entity-store/entities'; +import { useChangeEntity } from 'soapbox/entity-store/hooks'; +import { useApi } from 'soapbox/hooks/useApi'; +import { type Account } from 'soapbox/schemas'; + +function useChangeAccount() { + const { changeEntity: changeAccount } = useChangeEntity(Entities.ACCOUNTS); + return { changeAccount }; +} + +function useFollow() { + const api = useApi(); + const { changeAccount } = useChangeAccount(); + + function incrementFollowers(accountId: string) { + changeAccount(accountId, (account) => ({ + ...account, + followers_count: account.followers_count + 1, + })); + } + + function decrementFollowers(accountId: string) { + changeAccount(accountId, (account) => ({ + ...account, + followers_count: account.followers_count - 1, + })); + } + + async function follow(accountId: string, options = {}) { + incrementFollowers(accountId); + + try { + await api.post(`/api/v1/accounts/${accountId}/follow`, options); + } catch (e) { + decrementFollowers(accountId); + } + } + + async function unfollow(accountId: string, options = {}) { + decrementFollowers(accountId); + + try { + await api.post(`/api/v1/accounts/${accountId}/unfollow`, options); + } catch (e) { + incrementFollowers(accountId); + } + } + + return { + follow, + unfollow, + incrementFollowers, + decrementFollowers, + }; +} + +export { useFollow }; \ No newline at end of file diff --git a/app/soapbox/api/hooks/index.ts b/app/soapbox/api/hooks/index.ts index e411e2133..3e9d3151d 100644 --- a/app/soapbox/api/hooks/index.ts +++ b/app/soapbox/api/hooks/index.ts @@ -1,13 +1,11 @@ -/** - * Accounts - */ +// Accounts export { useAccount } from './accounts/useAccount'; +export { useFollow } from './accounts/useFollow'; +export { useRelationships } from './accounts/useRelationships'; export { usePatronUser } from './accounts/usePatronUser'; -/** - * Groups - */ +// Groups export { useBlockGroupMember } from './groups/useBlockGroupMember'; export { useCancelMembershipRequest } from './groups/useCancelMembershipRequest'; export { useCreateGroup, type CreateGroupParams } from './groups/useCreateGroup'; @@ -34,8 +32,3 @@ export { usePromoteGroupMember } from './groups/usePromoteGroupMember'; export { useSuggestedGroups } from './groups/useSuggestedGroups'; export { useUpdateGroup } from './groups/useUpdateGroup'; export { useUpdateGroupTag } from './groups/useUpdateGroupTag'; - -/** - * Relationships - */ -export { useRelationships } from './accounts/useRelationships'; \ No newline at end of file diff --git a/app/soapbox/entity-store/hooks/index.ts b/app/soapbox/entity-store/hooks/index.ts index b95d2d1af..de3ba0f1d 100644 --- a/app/soapbox/entity-store/hooks/index.ts +++ b/app/soapbox/entity-store/hooks/index.ts @@ -5,4 +5,5 @@ export { useEntityLookup } from './useEntityLookup'; export { useCreateEntity } from './useCreateEntity'; export { useDeleteEntity } from './useDeleteEntity'; export { useDismissEntity } from './useDismissEntity'; -export { useIncrementEntity } from './useIncrementEntity'; \ No newline at end of file +export { useIncrementEntity } from './useIncrementEntity'; +export { useChangeEntity } from './useChangeEntity'; \ No newline at end of file diff --git a/app/soapbox/entity-store/hooks/useChangeEntity.ts b/app/soapbox/entity-store/hooks/useChangeEntity.ts new file mode 100644 index 000000000..5276d4361 --- /dev/null +++ b/app/soapbox/entity-store/hooks/useChangeEntity.ts @@ -0,0 +1,24 @@ +import { importEntities } from 'soapbox/entity-store/actions'; +import { Entities } from 'soapbox/entity-store/entities'; +import { type Entity } from 'soapbox/entity-store/types'; +import { useAppDispatch, useGetState } from 'soapbox/hooks'; + +type ChangeEntityFn = (entity: TEntity) => TEntity + +function useChangeEntity(entityType: Entities) { + const getState = useGetState(); + const dispatch = useAppDispatch(); + + function changeEntity(entityId: string, change: ChangeEntityFn): void { + if (!entityId) return; + const entity = getState().entities[entityType]?.store[entityId] as TEntity | undefined; + if (entity) { + const newEntity = change(entity); + dispatch(importEntities([newEntity], entityType)); + } + } + + return { changeEntity }; +} + +export { useChangeEntity, type ChangeEntityFn }; \ No newline at end of file