Prefetch collection accounts for statuses and notifications (#39291)

This commit is contained in:
diondiondion 2026-06-05 10:34:39 +02:00 committed by GitHub
parent 20c535acc4
commit 906ae955fb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 14 deletions

View File

@ -4,6 +4,7 @@ import { importAccounts } from './accounts';
import { importCustomEmoji } from './emoji';
import { normalizeStatus } from './normalizer';
import { importPolls } from './polls';
import { fetchAccountsForCollectionPreview } from '@/mastodon/reducers/slices/collections';
export const STATUS_IMPORT = 'STATUS_IMPORT';
export const STATUSES_IMPORT = 'STATUSES_IMPORT';
@ -61,6 +62,7 @@ export function importFetchedStatuses(statuses, options = {}) {
const normalStatuses = [];
const polls = [];
const filters = [];
const collections = [];
function processStatus(status) {
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id]), options));
@ -82,6 +84,10 @@ export function importFetchedStatuses(statuses, options = {}) {
pushUnique(polls, createPollFromServerJSON(status.poll, getState().polls[status.poll.id]));
}
if (status.tagged_collections.length) {
status.tagged_collections.forEach(collection => pushUnique(collections, collection));
}
if (status.card) {
status.card.authors.forEach(author => author.account && pushUnique(accounts, author.account));
}
@ -97,5 +103,6 @@ export function importFetchedStatuses(statuses, options = {}) {
dispatch(importFetchedAccounts(accounts));
dispatch(importStatuses(normalStatuses));
dispatch(importFilters(filters));
fetchAccountsForCollectionPreview(collections, dispatch);
};
}

View File

@ -5,6 +5,7 @@ import {
apiFetchNotificationGroups,
} from 'mastodon/api/notifications';
import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
import type { ApiCollectionJSON } from 'mastodon/api_types/collections';
import type {
ApiNotificationGroupJSON,
ApiNotificationJSON,
@ -26,6 +27,8 @@ import {
createDataLoadingThunk,
} from 'mastodon/store/typed_functions';
import { fetchAccountsForCollectionPreview } from '../reducers/slices/collections';
import { importFetchedAccounts, importFetchedStatuses } from './importer';
import { NOTIFICATIONS_FILTER_SET } from './notifications';
import { saveSettings } from './settings';
@ -70,6 +73,7 @@ function dispatchAssociatedRecords(
) {
const fetchedAccounts: ApiAccountJSON[] = [];
const fetchedStatuses: ApiStatusJSON[] = [];
const collections: ApiCollectionJSON[] = [];
notifications.forEach((notification) => {
if (notification.type === 'admin.report') {
@ -83,6 +87,10 @@ function dispatchAssociatedRecords(
if ('status' in notification && notification.status) {
fetchedStatuses.push(notification.status);
}
if ('collection' in notification) {
collections.push(notification.collection);
}
});
if (fetchedAccounts.length > 0)
@ -90,6 +98,9 @@ function dispatchAssociatedRecords(
if (fetchedStatuses.length > 0)
dispatch(importFetchedStatuses(fetchedStatuses));
if (collections.length > 0)
void fetchAccountsForCollectionPreview(collections, dispatch);
}
function selectNotificationGroupedTypes(state: RootState) {

View File

@ -13,7 +13,7 @@ import {
} from 'mastodon/store/typed_functions';
import {
importAccountsForPreviewCard,
fetchAccountsForCollectionPreview,
importFetchedCollections,
} from '../reducers/slices/collections';
@ -46,7 +46,7 @@ export const submitSearch = createDataLoadingThunk(
if (data.collections.length > 0) {
dispatch(importFetchedCollections(data.collections));
await importAccountsForPreviewCard(data.collections, dispatch);
await fetchAccountsForCollectionPreview(data.collections, dispatch);
}
return data;
@ -82,7 +82,7 @@ export const expandSearch = createDataLoadingThunk(
if (data.collections.length > 0) {
dispatch(importFetchedCollections(data.collections));
await importAccountsForPreviewCard(data.collections, dispatch);
await fetchAccountsForCollectionPreview(data.collections, dispatch);
}
return data;

View File

@ -337,7 +337,7 @@ const collectionSlice = createSlice({
/**
* Prefetch accounts whose avatars will be displayed in the collection list
*/
export async function importAccountsForPreviewCard(
export async function fetchAccountsForCollectionPreview(
collections: ApiCollectionJSON[],
dispatch: AppDispatch,
) {
@ -347,15 +347,17 @@ export async function importAccountsForPreviewCard(
)
.filter((id): id is string => !!id);
// fetchAccounts can only process up to 40 item ids, so we'll
// batch the list of ids
const batchedAccountIdLists = batchArray(previewAccountIds, 40);
if (previewAccountIds.length > 0) {
// fetchAccounts can only process up to 40 item ids, so we'll
// batch the list of ids
const batchedAccountIdLists = batchArray(previewAccountIds, 40);
await Promise.allSettled(
batchedAccountIdLists.map((accountIds) =>
dispatch(fetchAccounts({ accountIds })),
),
);
await Promise.allSettled(
batchedAccountIdLists.map((accountIds) =>
dispatch(fetchAccounts({ accountIds })),
),
);
}
}
export const fetchCollectionsCreatedByAccount = createDataLoadingThunk(
@ -363,7 +365,7 @@ export const fetchCollectionsCreatedByAccount = createDataLoadingThunk(
({ accountId }: { accountId: string }) =>
apiGetCollectionsCreatedByAccount(accountId),
async ({ collections }, { dispatch }) => {
await importAccountsForPreviewCard(collections, dispatch);
await fetchAccountsForCollectionPreview(collections, dispatch);
},
);
@ -372,7 +374,7 @@ export const fetchCollectionsFeaturingAccount = createDataLoadingThunk(
({ accountId }: { accountId: string }) =>
apiGetCollectionsFeaturingAccount(accountId),
async ({ collections }, { dispatch }) => {
await importAccountsForPreviewCard(collections, dispatch);
await fetchAccountsForCollectionPreview(collections, dispatch);
},
);