diff --git a/app/soapbox/api/hooks/accounts/useAccount.ts b/app/soapbox/api/hooks/accounts/useAccount.ts index 1bfb06ab7..f50190134 100644 --- a/app/soapbox/api/hooks/accounts/useAccount.ts +++ b/app/soapbox/api/hooks/accounts/useAccount.ts @@ -3,10 +3,15 @@ import { useEntity } from 'soapbox/entity-store/hooks'; import { useApi } from 'soapbox/hooks/useApi'; import { type Account, accountSchema } from 'soapbox/schemas'; -import { useRelationships } from './useRelationships'; +import { useRelationship } from './useRelationship'; -function useAccount(accountId?: string) { +interface UseAccountOpts { + withRelationship?: boolean +} + +function useAccount(accountId?: string, opts: UseAccountOpts = {}) { const api = useApi(); + const { withRelationship } = opts; const { entity: account, ...result } = useEntity( [Entities.ACCOUNTS, accountId!], @@ -15,15 +20,15 @@ function useAccount(accountId?: string) { ); const { - relationships, + relationship, isLoading: isRelationshipLoading, - } = useRelationships(accountId ? [accountId] : []); + } = useRelationship(accountId, { enabled: withRelationship }); return { ...result, isLoading: result.isLoading, isRelationshipLoading, - account: account ? { ...account, relationship: relationships[0] || null } : undefined, + account: account ? { ...account, relationship } : undefined, }; } diff --git a/app/soapbox/api/hooks/accounts/useAccountLookup.ts b/app/soapbox/api/hooks/accounts/useAccountLookup.ts index 22753e180..d26e17b64 100644 --- a/app/soapbox/api/hooks/accounts/useAccountLookup.ts +++ b/app/soapbox/api/hooks/accounts/useAccountLookup.ts @@ -3,10 +3,15 @@ import { useEntityLookup } from 'soapbox/entity-store/hooks'; import { useApi } from 'soapbox/hooks/useApi'; import { type Account, accountSchema } from 'soapbox/schemas'; -import { useRelationships } from './useRelationships'; +import { useRelationship } from './useRelationship'; -function useAccountLookup(acct?: string) { +interface UseAccountLookupOpts { + withRelationship?: boolean +} + +function useAccountLookup(acct: string | undefined, opts: UseAccountLookupOpts = {}) { const api = useApi(); + const { withRelationship } = opts; const { entity: account, ...result } = useEntityLookup( Entities.ACCOUNTS, @@ -16,15 +21,15 @@ function useAccountLookup(acct?: string) { ); const { - relationships, + relationship, isLoading: isRelationshipLoading, - } = useRelationships(account ? [account.id] : []); + } = useRelationship(account?.id, { enabled: withRelationship }); return { ...result, isLoading: result.isLoading, isRelationshipLoading, - account: account ? { ...account, relationship: relationships[0] || null } : undefined, + account: account ? { ...account, relationship } : undefined, }; } diff --git a/app/soapbox/api/hooks/accounts/useRelationship.ts b/app/soapbox/api/hooks/accounts/useRelationship.ts new file mode 100644 index 000000000..e0793108b --- /dev/null +++ b/app/soapbox/api/hooks/accounts/useRelationship.ts @@ -0,0 +1,28 @@ +import { z } from 'zod'; + +import { Entities } from 'soapbox/entity-store/entities'; +import { useEntity } from 'soapbox/entity-store/hooks'; +import { useApi } from 'soapbox/hooks'; +import { type Relationship, relationshipSchema } from 'soapbox/schemas'; + +interface UseRelationshipOpts { + enabled?: boolean +} + +function useRelationship(accountId: string | undefined, opts: UseRelationshipOpts = {}) { + const api = useApi(); + const { enabled = false } = opts; + + const { entity: relationship, ...result } = useEntity( + [Entities.RELATIONSHIPS, accountId!], + () => api.get(`/api/v1/accounts/relationships?id[]=${accountId}`), + { + enabled: enabled && !!accountId, + schema: z.array(relationshipSchema).nonempty().transform(arr => arr[0]), + }, + ); + + return { relationship, ...result }; +} + +export { useRelationship }; \ No newline at end of file diff --git a/app/soapbox/api/hooks/groups/useGroupRelationship.ts b/app/soapbox/api/hooks/groups/useGroupRelationship.ts index 21d8d3efd..c6e51d869 100644 --- a/app/soapbox/api/hooks/groups/useGroupRelationship.ts +++ b/app/soapbox/api/hooks/groups/useGroupRelationship.ts @@ -16,7 +16,7 @@ function useGroupRelationship(groupId: string | undefined) { () => api.get(`/api/v1/groups/relationships?id[]=${groupId}`), { enabled: !!groupId, - schema: z.array(groupRelationshipSchema).transform(arr => arr[0]), + schema: z.array(groupRelationshipSchema).nonempty().transform(arr => arr[0]), }, ); diff --git a/app/soapbox/components/profile-hover-card.tsx b/app/soapbox/components/profile-hover-card.tsx index 98487f4ac..842844ec1 100644 --- a/app/soapbox/components/profile-hover-card.tsx +++ b/app/soapbox/components/profile-hover-card.tsx @@ -23,7 +23,10 @@ import { Card, CardBody, HStack, Icon, Stack, Text } from './ui'; import type { Account, PatronUser } from 'soapbox/schemas'; import type { AppDispatch } from 'soapbox/store'; -const getBadges = (account?: Account, patronUser?: PatronUser): JSX.Element[] => { +const getBadges = ( + account?: Pick, + patronUser?: Pick, +): JSX.Element[] => { const badges = []; if (account?.admin) { @@ -65,7 +68,7 @@ export const ProfileHoverCard: React.FC = ({ visible = true } const me = useAppSelector(state => state.me); const accountId: string | undefined = useAppSelector(state => state.profile_hover_card.accountId || undefined); - const { account } = useAccount(accountId); + const { account } = useAccount(accountId, { withRelationship: true }); const { patronUser } = usePatronUser(account?.url); const targetRef = useAppSelector(state => state.profile_hover_card.ref?.current); const badges = getBadges(account, patronUser);