pl-fe: move profile directory to tanstack query
Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
parent
2053998732
commit
ae77b678b4
4 changed files with 40 additions and 133 deletions
|
@ -1,87 +0,0 @@
|
|||
import { getClient } from '../api';
|
||||
|
||||
import { fetchRelationships } from './accounts';
|
||||
import { importEntities } from './importer';
|
||||
|
||||
import type { Account, ProfileDirectoryParams } from 'pl-api';
|
||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
||||
|
||||
const DIRECTORY_FETCH_REQUEST = 'DIRECTORY_FETCH_REQUEST' as const;
|
||||
const DIRECTORY_FETCH_SUCCESS = 'DIRECTORY_FETCH_SUCCESS' as const;
|
||||
const DIRECTORY_FETCH_FAIL = 'DIRECTORY_FETCH_FAIL' as const;
|
||||
|
||||
const DIRECTORY_EXPAND_REQUEST = 'DIRECTORY_EXPAND_REQUEST' as const;
|
||||
const DIRECTORY_EXPAND_SUCCESS = 'DIRECTORY_EXPAND_SUCCESS' as const;
|
||||
const DIRECTORY_EXPAND_FAIL = 'DIRECTORY_EXPAND_FAIL' as const;
|
||||
|
||||
const fetchDirectory = (params: ProfileDirectoryParams) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch(fetchDirectoryRequest());
|
||||
|
||||
return getClient(getState()).instance.profileDirectory({ ...params, limit: 20 }).then((data) => {
|
||||
dispatch(importEntities({ accounts: data }));
|
||||
dispatch(fetchDirectorySuccess(data));
|
||||
dispatch(fetchRelationships(data.map((x) => x.id)));
|
||||
}).catch(error => dispatch(fetchDirectoryFail(error)));
|
||||
};
|
||||
|
||||
const fetchDirectoryRequest = () => ({
|
||||
type: DIRECTORY_FETCH_REQUEST,
|
||||
});
|
||||
|
||||
const fetchDirectorySuccess = (accounts: Array<Account>) => ({
|
||||
type: DIRECTORY_FETCH_SUCCESS,
|
||||
accounts,
|
||||
});
|
||||
|
||||
const fetchDirectoryFail = (error: unknown) => ({
|
||||
type: DIRECTORY_FETCH_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
const expandDirectory = (params: Record<string, any>) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
dispatch(expandDirectoryRequest());
|
||||
|
||||
const loadedItems = getState().user_lists.directory.items.length;
|
||||
|
||||
return getClient(getState()).instance.profileDirectory({ ...params, offset: loadedItems, limit: 20 }).then((data) => {
|
||||
dispatch(importEntities({ accounts: data }));
|
||||
dispatch(expandDirectorySuccess(data));
|
||||
dispatch(fetchRelationships(data.map((x) => x.id)));
|
||||
}).catch(error => dispatch(expandDirectoryFail(error)));
|
||||
};
|
||||
|
||||
const expandDirectoryRequest = () => ({
|
||||
type: DIRECTORY_EXPAND_REQUEST,
|
||||
});
|
||||
|
||||
const expandDirectorySuccess = (accounts: Array<Account>) => ({
|
||||
type: DIRECTORY_EXPAND_SUCCESS,
|
||||
accounts,
|
||||
});
|
||||
|
||||
const expandDirectoryFail = (error: unknown) => ({
|
||||
type: DIRECTORY_EXPAND_FAIL,
|
||||
error,
|
||||
});
|
||||
|
||||
type DirectoryAction =
|
||||
| ReturnType<typeof fetchDirectoryRequest>
|
||||
| ReturnType<typeof fetchDirectorySuccess>
|
||||
| ReturnType<typeof fetchDirectoryFail>
|
||||
| ReturnType<typeof expandDirectoryRequest>
|
||||
| ReturnType<typeof expandDirectorySuccess>
|
||||
| ReturnType<typeof expandDirectoryFail>;
|
||||
|
||||
export {
|
||||
DIRECTORY_FETCH_REQUEST,
|
||||
DIRECTORY_FETCH_SUCCESS,
|
||||
DIRECTORY_FETCH_FAIL,
|
||||
DIRECTORY_EXPAND_REQUEST,
|
||||
DIRECTORY_EXPAND_SUCCESS,
|
||||
DIRECTORY_EXPAND_FAIL,
|
||||
fetchDirectory,
|
||||
expandDirectory,
|
||||
type DirectoryAction,
|
||||
};
|
27
packages/pl-fe/src/api/hooks/account-lists/use-directory.ts
Normal file
27
packages/pl-fe/src/api/hooks/account-lists/use-directory.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||
|
||||
import { importEntities } from 'pl-fe/actions/importer';
|
||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||
import { useClient } from 'pl-fe/hooks/use-client';
|
||||
|
||||
const useDirectory = (order: 'active' | 'new', local: boolean = false) => {
|
||||
const client = useClient();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
return useInfiniteQuery({
|
||||
queryKey: ['accountsLists', 'directory', order, local],
|
||||
queryFn: ({ pageParam: offset }) => client.instance.profileDirectory({
|
||||
order,
|
||||
local,
|
||||
offset,
|
||||
}).then((accounts) => {
|
||||
dispatch(importEntities({ accounts }));
|
||||
return accounts.map(({ id }) => id);
|
||||
}),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (_, allPages) => allPages.at(-1)?.length === 0 ? undefined : allPages.flat().length,
|
||||
select: (data) => data?.pages.flat(),
|
||||
});
|
||||
};
|
||||
|
||||
export { useDirectory };
|
|
@ -1,16 +1,14 @@
|
|||
import clsx from 'clsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useSearchParams } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { fetchDirectory, expandDirectory } from 'pl-fe/actions/directory';
|
||||
import { useDirectory } from 'pl-fe/api/hooks/account-lists/use-directory';
|
||||
import LoadMore from 'pl-fe/components/load-more';
|
||||
import { RadioGroup, RadioItem } from 'pl-fe/components/radio';
|
||||
import { CardTitle } from 'pl-fe/components/ui/card';
|
||||
import Column from 'pl-fe/components/ui/column';
|
||||
import Stack from 'pl-fe/components/ui/stack';
|
||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
||||
import { useFeatures } from 'pl-fe/hooks/use-features';
|
||||
import { useInstance } from 'pl-fe/hooks/use-instance';
|
||||
|
||||
|
@ -26,32 +24,25 @@ const messages = defineMessages({
|
|||
|
||||
const Directory = () => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const { search } = useLocation();
|
||||
const params = new URLSearchParams(search);
|
||||
const [params, setParams] = useSearchParams();
|
||||
const instance = useInstance();
|
||||
const features = useFeatures();
|
||||
|
||||
const accountIds = useAppSelector((state) => state.user_lists.directory.items);
|
||||
const isLoading = useAppSelector((state) => state.user_lists.directory.isLoading);
|
||||
const order = (params.get('order') || 'active') as 'active' | 'new';
|
||||
const local = !!params.get('local');
|
||||
|
||||
const [order, setOrder] = useState(params.get('order') || 'active');
|
||||
const [local, setLocal] = useState(!!params.get('local'));
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchDirectory({ order: order || 'active', local: local || false }));
|
||||
}, [order, local]);
|
||||
const { data: accountIds = [], isLoading, hasNextPage, fetchNextPage } = useDirectory(order, local);
|
||||
|
||||
const handleChangeOrder: React.ChangeEventHandler<HTMLInputElement> = e => {
|
||||
setOrder(e.target.value);
|
||||
setParams({ local: local ? 'true' : '', order: e.target.value });
|
||||
};
|
||||
|
||||
const handleChangeLocal: React.ChangeEventHandler<HTMLInputElement> = e => {
|
||||
setLocal(e.target.value === '1');
|
||||
setParams({ local: e.target.value === '1' ? 'true' : '', order });
|
||||
};
|
||||
|
||||
const handleLoadMore = () => {
|
||||
dispatch(expandDirectory({ order: order || 'active', local: local || false }));
|
||||
fetchNextPage({ cancelRefetch: false });
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -108,7 +99,7 @@ const Directory = () => {
|
|||
)}
|
||||
</div>
|
||||
|
||||
<LoadMore onClick={handleLoadMore} disabled={isLoading} />
|
||||
{hasNextPage && <LoadMore onClick={handleLoadMore} disabled={isLoading} />}
|
||||
</Stack>
|
||||
</Column>
|
||||
);
|
||||
|
|
|
@ -9,15 +9,6 @@ import {
|
|||
BIRTHDAY_REMINDERS_FETCH_SUCCESS,
|
||||
type AccountsAction,
|
||||
} from 'pl-fe/actions/accounts';
|
||||
import {
|
||||
DIRECTORY_FETCH_REQUEST,
|
||||
DIRECTORY_FETCH_SUCCESS,
|
||||
DIRECTORY_FETCH_FAIL,
|
||||
DIRECTORY_EXPAND_REQUEST,
|
||||
DIRECTORY_EXPAND_SUCCESS,
|
||||
DIRECTORY_EXPAND_FAIL,
|
||||
type DirectoryAction,
|
||||
} from 'pl-fe/actions/directory';
|
||||
import {
|
||||
EVENT_PARTICIPATIONS_EXPAND_SUCCESS,
|
||||
EVENT_PARTICIPATIONS_FETCH_SUCCESS,
|
||||
|
@ -78,7 +69,7 @@ interface ParticipationRequestList {
|
|||
isLoading: boolean;
|
||||
}
|
||||
|
||||
type ListKey = 'follow_requests' | 'directory';
|
||||
type ListKey = 'follow_requests';
|
||||
type NestedListKey = 'reblogged_by' | 'favourited_by' | 'disliked_by' | 'pinned' | 'birthday_reminders' | 'familiar_followers' | 'event_participations' | 'membership_requests' | 'group_blocks';
|
||||
|
||||
type State = Record<ListKey, List> & Record<NestedListKey, Record<string, List>> & {
|
||||
|
@ -92,7 +83,6 @@ const initialState: State = {
|
|||
disliked_by: {},
|
||||
reactions: {},
|
||||
follow_requests: { next: null, items: [], isLoading: false },
|
||||
directory: { next: null, items: [], isLoading: true },
|
||||
pinned: {},
|
||||
birthday_reminders: {},
|
||||
familiar_followers: {},
|
||||
|
@ -157,7 +147,7 @@ const normalizeFollowRequest = (state: State, notification: NotificationGroup) =
|
|||
draft.follow_requests.items = [...new Set([...notification.sample_account_ids, ...draft.follow_requests.items])];
|
||||
});
|
||||
|
||||
const userLists = (state = initialState, action: AccountsAction | DirectoryAction | EventsAction | FamiliarFollowersAction | GroupsAction | InteractionsAction | NotificationsAction): State => {
|
||||
const userLists = (state = initialState, action: AccountsAction | EventsAction | FamiliarFollowersAction | GroupsAction | InteractionsAction | NotificationsAction): State => {
|
||||
switch (action.type) {
|
||||
case REBLOGS_FETCH_SUCCESS:
|
||||
return normalizeList(state, ['reblogged_by', action.statusId], action.accounts, action.next);
|
||||
|
@ -186,20 +176,6 @@ const userLists = (state = initialState, action: AccountsAction | DirectoryActio
|
|||
case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
|
||||
case FOLLOW_REQUEST_REJECT_SUCCESS:
|
||||
return removeFromList(state, ['follow_requests'], action.accountId);
|
||||
case DIRECTORY_FETCH_SUCCESS:
|
||||
return normalizeList(state, ['directory'], action.accounts);
|
||||
case DIRECTORY_EXPAND_SUCCESS:
|
||||
return appendToList(state, ['directory'], action.accounts, null);
|
||||
case DIRECTORY_FETCH_REQUEST:
|
||||
case DIRECTORY_EXPAND_REQUEST:
|
||||
return create(state, (draft) => {
|
||||
draft.directory.isLoading = true;
|
||||
});
|
||||
case DIRECTORY_FETCH_FAIL:
|
||||
case DIRECTORY_EXPAND_FAIL:
|
||||
return create(state, (draft) => {
|
||||
draft.directory.isLoading = false;
|
||||
});
|
||||
case PINNED_ACCOUNTS_FETCH_SUCCESS:
|
||||
return normalizeList(state, ['pinned', action.accountId], action.accounts, action.next);
|
||||
case BIRTHDAY_REMINDERS_FETCH_SUCCESS:
|
||||
|
|
Loading…
Reference in a new issue