Add pagination to favourited_by dialog

environments/review-develop-3zknud/deployments/3536^2
oakes 1 year ago
parent b96828ad23
commit 500ac3eefe

@ -3,7 +3,7 @@ import { defineMessages } from 'react-intl';
import toast from 'soapbox/toast';
import { isLoggedIn } from 'soapbox/utils/auth';
import api from '../api';
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts, importFetchedStatus } from './importer';
@ -73,6 +73,9 @@ const REMOTE_INTERACTION_REQUEST = 'REMOTE_INTERACTION_REQUEST';
const REMOTE_INTERACTION_SUCCESS = 'REMOTE_INTERACTION_SUCCESS';
const REMOTE_INTERACTION_FAIL = 'REMOTE_INTERACTION_FAIL';
const FAVOURITES_EXPAND_SUCCESS = 'FAVOURITES_EXPAND_SUCCESS';
const FAVOURITES_EXPAND_FAIL = 'FAVOURITES_EXPAND_FAIL';
const messages = defineMessages({
bookmarkAdded: { id: 'status.bookmarked', defaultMessage: 'Bookmark added.' },
bookmarkRemoved: { id: 'status.unbookmarked', defaultMessage: 'Bookmark removed.' },
@ -412,9 +415,10 @@ const fetchFavourites = (id: string) =>
dispatch(fetchFavouritesRequest(id));
api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
dispatch(fetchFavouritesSuccess(id, response.data));
dispatch(fetchFavouritesSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchFavouritesFail(id, error));
});
@ -425,10 +429,11 @@ const fetchFavouritesRequest = (id: string) => ({
id,
});
const fetchFavouritesSuccess = (id: string, accounts: APIEntity[]) => ({
const fetchFavouritesSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: FAVOURITES_FETCH_SUCCESS,
id,
accounts,
next,
});
const fetchFavouritesFail = (id: string, error: AxiosError) => ({
@ -437,6 +442,31 @@ const fetchFavouritesFail = (id: string, error: AxiosError) => ({
error,
});
const expandFavourites = (id: string, path: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
api(getState).get(path).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedAccounts(response.data));
dispatch(fetchRelationships(response.data.map((item: APIEntity) => item.id)));
dispatch(expandFavouritesSuccess(id, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandFavouritesFail(id, error));
});
};
const expandFavouritesSuccess = (id: string, accounts: APIEntity[], next: string | null) => ({
type: FAVOURITES_EXPAND_SUCCESS,
id,
accounts,
next,
});
const expandFavouritesFail = (id: string, error: AxiosError) => ({
type: FAVOURITES_EXPAND_FAIL,
id,
error,
});
const fetchDislikes = (id: string) =>
(dispatch: AppDispatch, getState: () => RootState) => {
if (!isLoggedIn(getState)) return;
@ -669,6 +699,8 @@ export {
REMOTE_INTERACTION_REQUEST,
REMOTE_INTERACTION_SUCCESS,
REMOTE_INTERACTION_FAIL,
FAVOURITES_EXPAND_SUCCESS,
FAVOURITES_EXPAND_FAIL,
reblog,
unreblog,
toggleReblog,
@ -713,6 +745,7 @@ export {
fetchFavouritesRequest,
fetchFavouritesSuccess,
fetchFavouritesFail,
expandFavourites,
fetchDislikes,
fetchDislikesRequest,
fetchDislikesSuccess,

@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { FormattedMessage } from 'react-intl';
import { fetchFavourites } from 'soapbox/actions/interactions';
import { fetchFavourites, expandFavourites } from 'soapbox/actions/interactions';
import ScrollableList from 'soapbox/components/scrollable-list';
import { Modal, Spinner } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account-container';
@ -16,6 +16,7 @@ const FavouritesModal: React.FC<IFavouritesModal> = ({ onClose, statusId }) => {
const dispatch = useAppDispatch();
const accountIds = useAppSelector((state) => state.user_lists.favourited_by.get(statusId)?.items);
const next = useAppSelector((state) => state.user_lists.favourited_by.get(statusId)?.next);
const fetchData = () => {
dispatch(fetchFavourites(statusId));
@ -29,6 +30,12 @@ const FavouritesModal: React.FC<IFavouritesModal> = ({ onClose, statusId }) => {
onClose('FAVOURITES');
};
const handleLoadMore = () => {
if (next) {
dispatch(expandFavourites(statusId, next!));
}
};
let body;
if (!accountIds) {
@ -44,6 +51,8 @@ const FavouritesModal: React.FC<IFavouritesModal> = ({ onClose, statusId }) => {
itemClassName='pb-3'
style={{ height: '80vh' }}
useWindowScroll={false}
onLoadMore={handleLoadMore}
hasMore={!!next}
>
{accountIds.map(id =>
<AccountContainer key={id} id={id} />,

@ -60,6 +60,7 @@ import {
import {
REBLOGS_FETCH_SUCCESS,
FAVOURITES_FETCH_SUCCESS,
FAVOURITES_EXPAND_SUCCESS,
DISLIKES_FETCH_SUCCESS,
REACTIONS_FETCH_SUCCESS,
} from 'soapbox/actions/interactions';
@ -174,7 +175,9 @@ export default function userLists(state = ReducerRecord(), action: AnyAction) {
case REBLOGS_FETCH_SUCCESS:
return normalizeList(state, ['reblogged_by', action.id], action.accounts);
case FAVOURITES_FETCH_SUCCESS:
return normalizeList(state, ['favourited_by', action.id], action.accounts);
return normalizeList(state, ['favourited_by', action.id], action.accounts, action.next);
case FAVOURITES_EXPAND_SUCCESS:
return appendToList(state, ['favourited_by', action.id], action.accounts, action.next);
case DISLIKES_FETCH_SUCCESS:
return normalizeList(state, ['disliked_by', action.id], action.accounts);
case REACTIONS_FETCH_SUCCESS:

Loading…
Cancel
Save