Reduce account overfetching when displaying collection lists (#39220)
This commit is contained in:
parent
8e15e49e87
commit
0caf334891
@ -3,6 +3,7 @@ import { createAction } from '@reduxjs/toolkit';
|
|||||||
import {
|
import {
|
||||||
apiRemoveAccountFromFollowers,
|
apiRemoveAccountFromFollowers,
|
||||||
apiGetEndorsedAccounts,
|
apiGetEndorsedAccounts,
|
||||||
|
apiGetAccounts,
|
||||||
} from 'mastodon/api/accounts';
|
} from 'mastodon/api/accounts';
|
||||||
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
|
import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships';
|
||||||
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
||||||
@ -113,3 +114,12 @@ export const fetchEndorsedAccounts = createDataLoadingThunk(
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const fetchAccounts = createDataLoadingThunk(
|
||||||
|
'accounts/multi_accounts',
|
||||||
|
({ accountIds }: { accountIds: string[] }) => apiGetAccounts(accountIds),
|
||||||
|
(data, { dispatch }) => {
|
||||||
|
dispatch(importFetchedAccounts(data));
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|||||||
@ -19,6 +19,11 @@ import type {
|
|||||||
ApiProfileUpdateParams,
|
ApiProfileUpdateParams,
|
||||||
} from '../api_types/profile';
|
} from '../api_types/profile';
|
||||||
|
|
||||||
|
export const apiGetAccounts = (ids: string[]) =>
|
||||||
|
apiRequestGet<ApiAccountJSON[]>('v1/accounts', {
|
||||||
|
id: ids,
|
||||||
|
});
|
||||||
|
|
||||||
export const apiSubmitAccountNote = (id: string, value: string) =>
|
export const apiSubmitAccountNote = (id: string, value: string) =>
|
||||||
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
apiRequestPost<ApiRelationshipJSON>(`v1/accounts/${id}/note`, {
|
||||||
comment: value,
|
comment: value,
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export const apiUpdate = (list: Partial<ApiListJSON>) =>
|
|||||||
|
|
||||||
export const apiGetLists = () => apiRequestGet<ApiListJSON[]>('v1/lists');
|
export const apiGetLists = () => apiRequestGet<ApiListJSON[]>('v1/lists');
|
||||||
|
|
||||||
export const apiGetAccounts = (listId: string) =>
|
export const apiGetListAccounts = (listId: string) =>
|
||||||
apiRequestGet<ApiAccountJSON[]>(`v1/lists/${listId}/accounts`, {
|
apiRequestGet<ApiAccountJSON[]>(`v1/lists/${listId}/accounts`, {
|
||||||
limit: 0,
|
limit: 0,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import { fetchList } from 'mastodon/actions/lists';
|
|||||||
import { openModal } from 'mastodon/actions/modal';
|
import { openModal } from 'mastodon/actions/modal';
|
||||||
import { apiFollowAccount } from 'mastodon/api/accounts';
|
import { apiFollowAccount } from 'mastodon/api/accounts';
|
||||||
import {
|
import {
|
||||||
apiGetAccounts,
|
apiGetListAccounts,
|
||||||
apiAddAccountToList,
|
apiAddAccountToList,
|
||||||
apiRemoveAccountFromList,
|
apiRemoveAccountFromList,
|
||||||
} from 'mastodon/api/lists';
|
} from 'mastodon/api/lists';
|
||||||
@ -184,7 +184,7 @@ const ListMembers: React.FC<{
|
|||||||
if (id) {
|
if (id) {
|
||||||
dispatch(fetchList(id));
|
dispatch(fetchList(id));
|
||||||
|
|
||||||
void apiGetAccounts(id)
|
void apiGetListAccounts(id)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
dispatch(importFetchedAccounts(data));
|
dispatch(importFetchedAccounts(data));
|
||||||
setAccountIds(data.map((a) => a.id));
|
setAccountIds(data.map((a) => a.id));
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'
|
|||||||
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react';
|
||||||
import { fetchList } from 'mastodon/actions/lists';
|
import { fetchList } from 'mastodon/actions/lists';
|
||||||
import { createList, updateList } from 'mastodon/actions/lists_typed';
|
import { createList, updateList } from 'mastodon/actions/lists_typed';
|
||||||
import { apiGetAccounts } from 'mastodon/api/lists';
|
import { apiGetListAccounts } from 'mastodon/api/lists';
|
||||||
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
||||||
import type { RepliesPolicyType } from 'mastodon/api_types/lists';
|
import type { RepliesPolicyType } from 'mastodon/api_types/lists';
|
||||||
import { Avatar } from 'mastodon/components/avatar';
|
import { Avatar } from 'mastodon/components/avatar';
|
||||||
@ -44,7 +44,7 @@ const MembersLink: React.FC<{
|
|||||||
const [avatarAccounts, setAvatarAccounts] = useState<ApiAccountJSON[]>([]);
|
const [avatarAccounts, setAvatarAccounts] = useState<ApiAccountJSON[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void apiGetAccounts(id)
|
void apiGetListAccounts(id)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setAvatarCount(data.length);
|
setAvatarCount(data.length);
|
||||||
setAvatarAccounts(data.slice(0, 3));
|
setAvatarAccounts(data.slice(0, 3));
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import { fetchAccounts } from '@/mastodon/actions/accounts_typed';
|
||||||
import { importFetchedAccounts } from '@/mastodon/actions/importer';
|
import { importFetchedAccounts } from '@/mastodon/actions/importer';
|
||||||
import {
|
import {
|
||||||
apiCreateCollection,
|
apiCreateCollection,
|
||||||
@ -20,6 +21,7 @@ import type {
|
|||||||
CollectionAccountItem,
|
CollectionAccountItem,
|
||||||
} from '@/mastodon/api_types/collections';
|
} from '@/mastodon/api_types/collections';
|
||||||
import { initialState, me } from '@/mastodon/initial_state';
|
import { initialState, me } from '@/mastodon/initial_state';
|
||||||
|
import type { AppDispatch } from '@/mastodon/store';
|
||||||
import {
|
import {
|
||||||
createAppAsyncThunk,
|
createAppAsyncThunk,
|
||||||
createAppSelector,
|
createAppSelector,
|
||||||
@ -322,16 +324,42 @@ const collectionSlice = createSlice({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefetch accounts whose avatars will be displayed in the collection list
|
||||||
|
*/
|
||||||
|
async function importAccountsForPreviewCard(
|
||||||
|
collections: ApiCollectionJSON[],
|
||||||
|
dispatch: AppDispatch,
|
||||||
|
) {
|
||||||
|
const previewAccountIds = collections
|
||||||
|
.flatMap((collection) =>
|
||||||
|
collection.items.slice(0, 3).map((item) => item.account_id),
|
||||||
|
)
|
||||||
|
.filter((id): id is string => !!id);
|
||||||
|
|
||||||
|
await dispatch(
|
||||||
|
fetchAccounts({
|
||||||
|
accountIds: previewAccountIds,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const fetchCollectionsCreatedByAccount = createDataLoadingThunk(
|
export const fetchCollectionsCreatedByAccount = createDataLoadingThunk(
|
||||||
`${collectionSlice.name}/fetchCollectionsCreatedByAccount`,
|
`${collectionSlice.name}/fetchCollectionsCreatedByAccount`,
|
||||||
({ accountId }: { accountId: string }) =>
|
({ accountId }: { accountId: string }) =>
|
||||||
apiGetCollectionsCreatedByAccount(accountId),
|
apiGetCollectionsCreatedByAccount(accountId),
|
||||||
|
async ({ collections }, { dispatch }) => {
|
||||||
|
await importAccountsForPreviewCard(collections, dispatch);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchCollectionsFeaturingAccount = createDataLoadingThunk(
|
export const fetchCollectionsFeaturingAccount = createDataLoadingThunk(
|
||||||
`${collectionSlice.name}/fetchCollectionsFeaturingAccount`,
|
`${collectionSlice.name}/fetchCollectionsFeaturingAccount`,
|
||||||
({ accountId }: { accountId: string }) =>
|
({ accountId }: { accountId: string }) =>
|
||||||
apiGetCollectionsFeaturingAccount(accountId),
|
apiGetCollectionsFeaturingAccount(accountId),
|
||||||
|
async ({ collections }, { dispatch }) => {
|
||||||
|
await importAccountsForPreviewCard(collections, dispatch);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchCollection = createDataLoadingThunk(
|
export const fetchCollection = createDataLoadingThunk(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user