From 14a84e557c16eb293d56a15ffbe66a1053722641 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Thu, 9 Mar 2023 15:05:54 -0600 Subject: [PATCH] Update useGroups queries with EntityStore improvements --- app/soapbox/hooks/useGroups.ts | 70 +++++++++--------------------- app/soapbox/hooks/useGroupsPath.ts | 2 +- 2 files changed, 21 insertions(+), 51 deletions(-) diff --git a/app/soapbox/hooks/useGroups.ts b/app/soapbox/hooks/useGroups.ts index 7af1fa024..a8e61b9af 100644 --- a/app/soapbox/hooks/useGroups.ts +++ b/app/soapbox/hooks/useGroups.ts @@ -1,36 +1,13 @@ -import { useEffect } from 'react'; - import { useEntities, useEntity } from 'soapbox/entity-store/hooks'; import { normalizeGroup, normalizeGroupRelationship } from 'soapbox/normalizers'; import type { Group, GroupRelationship } from 'soapbox/types/entities'; -// HACK: normalizers currently don't have the desired API. -// TODO: rewrite normalizers as Zod parsers. -const parseGroup = (entity: unknown) => normalizeGroup(entity as Record); -const parseGroupRelationship = (entity: unknown) => normalizeGroupRelationship(entity as Record); - function useGroups() { - const result = useEntities(['Group', ''], '/api/v1/groups', { parser: parseGroup }); - const { entities, isLoading, fetchEntities } = result; - const { entities: relationships } = useGroupRelationships(entities.map(entity => entity.id)); + const { entities, ...result } = useEntities(['Group', ''], '/api/v1/groups', { parser: parseGroup }); + const { relationships } = useGroupRelationships(entities.map(entity => entity.id)); - // Note: we have to fetch them in the hook right now because I haven't implemented - // max-age or cache expiry in the entity store yet. It's planned. - useEffect(() => { - if (!isLoading) { - fetchEntities(); - } - }, []); - - const groups = entities.map((group) => { - // TODO: a generalistic useRelationships() hook that returns a map of values (would be faster). - const relationship = relationships.find(r => r.id === group.id); - if (relationship) { - return group.set('relationship', relationship); - } - return group; - }); + const groups = entities.map((group) => group.set('relationship', relationships[group.id] || null)); return { ...result, @@ -38,46 +15,39 @@ function useGroups() { }; } -function useGroup(groupId: string) { - const result = useEntity(['Group', groupId], `/api/v1/groups/${groupId}`, { parser: parseGroup }); - const { entity, isLoading, fetchEntity } = result; - const { relationship } = useGroupRelationship(groupId); - - useEffect(() => { - if (!isLoading) { - fetchEntity(); - } - }, []); +function useGroup(groupId: string, refetch = true) { + const { entity: group, ...result } = useEntity(['Group', groupId], `/api/v1/groups/${groupId}`, { parser: parseGroup, refetch }); + const { entity: relationship } = useGroupRelationship(groupId); return { ...result, - group: entity?.set('relationship', relationship), + group: group?.set('relationship', relationship || null), }; } function useGroupRelationship(groupId: string) { - const { relationships, ...rest } = useGroupRelationships([groupId]); - return { - ...rest, - relationship: relationships[0], - }; + return useEntity(['GroupRelationship', groupId], `/api/v1/groups/relationships?id[]=${groupId}`, { parser: parseGroupRelationship }); } function useGroupRelationships(groupIds: string[]) { const q = groupIds.map(id => `id[]=${id}`).join('&'); - const result = useEntities(['GroupRelationship', ''], `/api/v1/groups/relationships?${q}`, { parser: parseGroupRelationship }); - const { entities, isLoading, fetchEntities } = result; + const endpoint = groupIds.length ? `/api/v1/groups/relationships?${q}` : undefined; + const { entities, ...result } = useEntities(['GroupRelationship', ''], endpoint, { parser: parseGroupRelationship }); - useEffect(() => { - if (!isLoading) { - fetchEntities(); - } - }, groupIds); + const relationships = entities.reduce>((map, relationship) => { + map[relationship.id] = relationship; + return map; + }, {}); return { ...result, - relationships: entities, + relationships, }; } +// HACK: normalizers currently don't have the desired API. +// TODO: rewrite normalizers as Zod parsers. +const parseGroup = (entity: unknown) => normalizeGroup(entity as Record); +const parseGroupRelationship = (entity: unknown) => normalizeGroupRelationship(entity as Record); + export { useGroup, useGroups }; \ No newline at end of file diff --git a/app/soapbox/hooks/useGroupsPath.ts b/app/soapbox/hooks/useGroupsPath.ts index 8a4759f32..b855ec0a6 100644 --- a/app/soapbox/hooks/useGroupsPath.ts +++ b/app/soapbox/hooks/useGroupsPath.ts @@ -1,4 +1,4 @@ -import { useGroups } from 'soapbox/queries/groups'; +import { useGroups } from 'soapbox/hooks'; import { useFeatures } from './useFeatures';