2023-02-27 05:25:59 -08:00
|
|
|
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
|
|
|
|
|
|
|
import { fetchGroupRelationships } from 'soapbox/actions/groups';
|
|
|
|
import { importFetchedGroups } from 'soapbox/actions/importer';
|
|
|
|
import { getNextLink } from 'soapbox/api';
|
|
|
|
import { useApi, useAppDispatch, useFeatures, useOwnAccount } from 'soapbox/hooks';
|
|
|
|
import { normalizeGroup } from 'soapbox/normalizers';
|
|
|
|
import { Group } from 'soapbox/types/entities';
|
|
|
|
import { flattenPages, PaginatedResult } from 'soapbox/utils/queries';
|
|
|
|
|
|
|
|
const GroupKeys = {
|
2023-03-02 11:40:36 -08:00
|
|
|
group: (id: string) => ['groups', 'group', id] as const,
|
2023-02-27 05:25:59 -08:00
|
|
|
myGroups: (userId: string) => ['groups', userId] as const,
|
|
|
|
popularGroups: ['groups', 'popular'] as const,
|
|
|
|
suggestedGroups: ['groups', 'suggested'] as const,
|
|
|
|
};
|
|
|
|
|
|
|
|
const useGroups = () => {
|
|
|
|
const api = useApi();
|
|
|
|
const account = useOwnAccount();
|
|
|
|
const dispatch = useAppDispatch();
|
2023-03-01 08:16:34 -08:00
|
|
|
const features = useFeatures();
|
2023-02-27 05:25:59 -08:00
|
|
|
|
|
|
|
const getGroups = async (pageParam?: any): Promise<PaginatedResult<Group>> => {
|
2023-03-01 08:16:34 -08:00
|
|
|
const endpoint = '/api/v1/groups';
|
2023-02-27 05:25:59 -08:00
|
|
|
const nextPageLink = pageParam?.link;
|
|
|
|
const uri = nextPageLink || endpoint;
|
|
|
|
const response = await api.get<Group[]>(uri);
|
|
|
|
const { data } = response;
|
|
|
|
|
|
|
|
const link = getNextLink(response);
|
|
|
|
const hasMore = !!link;
|
|
|
|
const result = data.map(normalizeGroup);
|
|
|
|
|
|
|
|
// Note: Temporary while part of Groups is using Redux
|
|
|
|
dispatch(importFetchedGroups(result));
|
|
|
|
dispatch(fetchGroupRelationships(result.map((item) => item.id)));
|
|
|
|
|
|
|
|
return {
|
|
|
|
result,
|
|
|
|
hasMore,
|
|
|
|
link,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const queryInfo = useInfiniteQuery(
|
|
|
|
GroupKeys.myGroups(account?.id as string),
|
|
|
|
({ pageParam }: any) => getGroups(pageParam),
|
|
|
|
{
|
2023-03-01 08:16:34 -08:00
|
|
|
enabled: !!account && features.groups,
|
2023-02-27 05:25:59 -08:00
|
|
|
keepPreviousData: true,
|
|
|
|
getNextPageParam: (config) => {
|
|
|
|
if (config?.hasMore) {
|
|
|
|
return { nextLink: config?.link };
|
|
|
|
}
|
|
|
|
|
|
|
|
return undefined;
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const data = flattenPages(queryInfo.data);
|
|
|
|
|
|
|
|
return {
|
|
|
|
...queryInfo,
|
|
|
|
groups: data || [],
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const usePopularGroups = () => {
|
|
|
|
const api = useApi();
|
|
|
|
const features = useFeatures();
|
|
|
|
|
|
|
|
const getQuery = async () => {
|
2023-03-02 11:40:36 -08:00
|
|
|
const { data } = await api.get<Group[]>('/api/v1/groups/search?q=group'); // '/api/v1/truth/trends/groups'
|
2023-02-27 05:25:59 -08:00
|
|
|
const result = data.map(normalizeGroup);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
const queryInfo = useQuery<Group[]>(GroupKeys.popularGroups, getQuery, {
|
|
|
|
enabled: features.groupsDiscovery,
|
|
|
|
placeholderData: [],
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
groups: queryInfo.data || [],
|
|
|
|
...queryInfo,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
const useSuggestedGroups = () => {
|
|
|
|
const api = useApi();
|
|
|
|
const features = useFeatures();
|
|
|
|
|
|
|
|
const getQuery = async () => {
|
|
|
|
const { data } = await api.get<Group[]>('/api/mock/groups'); // /api/v1/truth/suggestions/groups
|
|
|
|
const result = data.map(normalizeGroup);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
const queryInfo = useQuery<Group[]>(GroupKeys.suggestedGroups, getQuery, {
|
|
|
|
enabled: features.groupsDiscovery,
|
|
|
|
placeholderData: [],
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
groups: queryInfo.data || [],
|
|
|
|
...queryInfo,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-03-02 11:40:36 -08:00
|
|
|
const useGroup = (id: string) => {
|
|
|
|
const api = useApi();
|
|
|
|
const features = useFeatures();
|
|
|
|
|
|
|
|
const getGroup = async () => {
|
|
|
|
const { data } = await api.get(`/api/v1/groups/${id}`);
|
|
|
|
return normalizeGroup(data);
|
|
|
|
};
|
|
|
|
|
|
|
|
const queryInfo = useQuery(GroupKeys.group(id), getGroup, {
|
|
|
|
enabled: features.groups && !!id,
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
...queryInfo,
|
|
|
|
group: queryInfo.data,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export { useGroups, useGroup, usePopularGroups, useSuggestedGroups };
|