[Glitch] Prefetch collection accounts for statuses and notifications

Port 906ae955fb694588d3c948e8c774937e83933098 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
diondiondion 2026-06-05 10:34:39 +02:00 committed by Claire
parent 550299a71c
commit a147932ce6
4 changed files with 34 additions and 14 deletions

View File

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

View File

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

View File

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

View File

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