Convert popular/suggested Groups to use Entities

develop^2
Chewbacca 2023-03-13 16:08:42 -04:00
rodzic 50dadeb1b8
commit 7be8218f0c
11 zmienionych plików z 104 dodań i 56 usunięć

Wyświetl plik

@ -1,3 +1,4 @@
export enum Entities {
GROUP_MEMBERSHIPS = 'GroupMemberships'
GROUP_MEMBERSHIPS = 'GroupMemberships',
POPULAR_GROUPS = 'PopularGroups'
}

Wyświetl plik

@ -31,6 +31,8 @@ interface UseEntitiesOpts<TEntity extends Entity> {
* It is 1 minute by default, and can be set to `Infinity` to opt-out of automatic fetching.
*/
staleTime?: number
/** A flag to potentially disable sending requests to the API. */
enabled?: boolean
}
/** A hook for fetching and displaying API entities. */
@ -51,8 +53,11 @@ function useEntities<TEntity extends Entity>(
const entities = useAppSelector(state => selectEntities<TEntity>(state, path));
const isEnabled = opts.enabled ?? true;
const isFetching = useListState(path, 'fetching');
const lastFetchedAt = useListState(path, 'lastFetchedAt');
const isFetched = useListState(path, 'fetched');
const isError = !!useListState(path, 'error');
const next = useListState(path, 'next');
const prev = useListState(path, 'prev');
@ -72,6 +77,7 @@ function useEntities<TEntity extends Entity>(
next: getNextLink(response),
prev: getPrevLink(response),
fetching: false,
fetched: true,
error: null,
lastFetchedAt: new Date(),
}));
@ -101,20 +107,22 @@ function useEntities<TEntity extends Entity>(
const staleTime = opts.staleTime ?? 60000;
useEffect(() => {
if (!isFetching && (!lastFetchedAt || lastFetchedAt.getTime() + staleTime <= Date.now())) {
if (isEnabled && !isFetching && (!lastFetchedAt || lastFetchedAt.getTime() + staleTime <= Date.now())) {
fetchEntities();
}
}, [endpoint]);
}, [endpoint, isEnabled]);
return {
entities,
fetchEntities,
isFetching,
isLoading: isFetching && entities.length === 0,
hasNextPage: !!next,
hasPreviousPage: !!prev,
fetchNextPage,
fetchPreviousPage,
hasNextPage: !!next,
hasPreviousPage: !!prev,
isError,
isFetched,
isFetching,
isLoading: isFetching && entities.length === 0,
};
}

Wyświetl plik

@ -25,6 +25,8 @@ interface EntityListState {
prev: string | undefined
/** Error returned from the API, if any. */
error: any
/** Whether data has already been fetched */
fetched: boolean
/** Whether data for this list is currently being fetched. */
fetching: boolean
/** Date of the last API fetch for this list. */

Wyświetl plik

@ -29,8 +29,9 @@ const createList = (): EntityList => ({
state: {
next: undefined,
prev: undefined,
fetching: false,
error: null,
fetched: false,
fetching: false,
lastFetchedAt: undefined,
},
});

Wyświetl plik

@ -3,7 +3,7 @@ import { FormattedMessage } from 'react-intl';
import { Carousel, Stack, Text } from 'soapbox/components/ui';
import PlaceholderGroupDiscover from 'soapbox/features/placeholder/components/placeholder-group-discover';
import { usePopularGroups } from 'soapbox/queries/groups';
import { usePopularGroups } from 'soapbox/hooks/api/usePopularGroups';
import GroupGridItem from './group-grid-item';

Wyświetl plik

@ -3,7 +3,7 @@ import { FormattedMessage } from 'react-intl';
import { Carousel, Stack, Text } from 'soapbox/components/ui';
import PlaceholderGroupDiscover from 'soapbox/features/placeholder/components/placeholder-group-discover';
import { useSuggestedGroups } from 'soapbox/queries/groups';
import { useSuggestedGroups } from 'soapbox/hooks/api/useSuggestedGroups';
import GroupGridItem from './group-grid-item';

Wyświetl plik

@ -3,7 +3,7 @@ import React from 'react';
import { Widget } from 'soapbox/components/ui';
import GroupListItem from 'soapbox/features/groups/components/discover/group-list-item';
import PlaceholderGroupSearch from 'soapbox/features/placeholder/components/placeholder-group-search';
import { useSuggestedGroups } from 'soapbox/queries/groups';
import { useSuggestedGroups } from 'soapbox/hooks/api/useSuggestedGroups';
const SuggestedGroupsPanel = () => {
const { groups, isFetching, isFetched, isError } = useSuggestedGroups();

Wyświetl plik

@ -0,0 +1,40 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { Group, groupSchema } from 'soapbox/schemas';
import { useFeatures } from '../useFeatures';
import { useGroupRelationships } from '../useGroups';
function usePopularGroups() {
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.POPULAR_GROUPS, ''],
'/api/mock/groups', // '/api/v1/truth/trends/groups'
{
parser: parseGroup,
enabled: features.groupsDiscovery,
},
);
const { relationships } = useGroupRelationships(entities.map(entity => entity.id));
const groups = entities.map((group) => ({
...group,
relationship: relationships[group.id] || null,
}));
return {
...result,
groups,
};
}
const parseGroup = (entity: unknown) => {
const result = groupSchema.safeParse(entity);
if (result.success) {
return result.data;
}
};
export { usePopularGroups };

Wyświetl plik

@ -0,0 +1,40 @@
import { Entities } from 'soapbox/entity-store/entities';
import { useEntities } from 'soapbox/entity-store/hooks';
import { Group, groupSchema } from 'soapbox/schemas';
import { useFeatures } from '../useFeatures';
import { useGroupRelationships } from '../useGroups';
function useSuggestedGroups() {
const features = useFeatures();
const { entities, ...result } = useEntities<Group>(
[Entities.POPULAR_GROUPS, ''],
'/api/mock/groups', // '/api/v1/truth/suggestions/groups'
{
parser: parseGroup,
enabled: features.groupsDiscovery,
},
);
const { relationships } = useGroupRelationships(entities.map(entity => entity.id));
const groups = entities.map((group) => ({
...group,
relationship: relationships[group.id] || null,
}));
return {
...result,
groups,
};
}
const parseGroup = (entity: unknown) => {
const result = groupSchema.safeParse(entity);
if (result.success) {
return result.data;
}
};
export { useSuggestedGroups };

Wyświetl plik

@ -44,4 +44,4 @@ function useGroupRelationships(groupIds: string[]) {
};
}
export { useGroup, useGroups };
export { useGroup, useGroups, useGroupRelationships };

Wyświetl plik

@ -149,48 +149,6 @@ const usePendingGroups = () => {
};
};
const usePopularGroups = () => {
const features = useFeatures();
const { fetchGroups } = useGroupsApi();
const getQuery = async () => {
const { groups } = await fetchGroups('/api/v1/truth/trends/groups');
return groups;
};
const queryInfo = useQuery<Group[]>(GroupKeys.popularGroups, getQuery, {
enabled: features.groupsDiscovery,
placeholderData: [],
});
return {
groups: queryInfo.data || [],
...queryInfo,
};
};
const useSuggestedGroups = () => {
const features = useFeatures();
const { fetchGroups } = useGroupsApi();
const getQuery = async () => {
const { groups } = await fetchGroups('/api/v1/truth/suggestions/groups');
return groups;
};
const queryInfo = useQuery<Group[]>(GroupKeys.suggestedGroups, getQuery, {
enabled: features.groupsDiscovery,
placeholderData: [],
});
return {
groups: queryInfo.data || [],
...queryInfo,
};
};
const useGroup = (id: string) => {
const features = useFeatures();
const { fetchGroups } = useGroupsApi();
@ -256,6 +214,4 @@ export {
useJoinGroup,
useLeaveGroup,
usePendingGroups,
usePopularGroups,
useSuggestedGroups,
};