diff --git a/packages/common/src/api/tan-query/batchers/getEventsByEntityIdBatcher.ts b/packages/common/src/api/tan-query/batchers/getEventsByEntityIdBatcher.ts index 6cc4d2c2f1c..de7bdb09940 100644 --- a/packages/common/src/api/tan-query/batchers/getEventsByEntityIdBatcher.ts +++ b/packages/common/src/api/tan-query/batchers/getEventsByEntityIdBatcher.ts @@ -1,10 +1,12 @@ -import { Id, OptionalId } from '@audius/sdk' +import { Id, OptionalHashId, OptionalId } from '@audius/sdk' import { create, windowScheduler } from '@yornaath/batshit' import { memoize } from 'lodash' import { eventMetadataListFromSDK } from '~/adapters/event' import { ID, Event } from '~/models' +import { getRemixesCountQueryKey } from '../remixes/useRemixes' + import { contextCacheResolver } from './contextCacheResolver' import { BatchContext } from './types' @@ -12,13 +14,31 @@ export const getEventsByEntityIdBatcher = memoize( (context: BatchContext) => create({ fetcher: async (entityIds: ID[]): Promise => { - const { sdk, currentUserId } = context + const { sdk, currentUserId, queryClient } = context if (!entityIds.length) return [] - const { data } = await sdk.events.getEntityEvents({ + const { data, related } = await sdk.events.getEntityEvents({ entityId: entityIds.map((entityId) => Id.parse(entityId)), userId: OptionalId.parse(currentUserId) }) + // Prime the dedicated `useRemixesCount` cache from the entry counts + // delivered alongside the event list (keyed by the contest's parent + // track hashid). This turns ContestCard's entry-count badge into a + // cache hit so surfaces that resolve contests via this endpoint (the + // track-page contest section, cold contest pages, web Explore's + // featured contests) don't fire a count-only + // `/tracks/{id}/remixes?limit=0` per card. Same pattern as + // useAllRemixContests / useUserRemixContests. + const entryCounts = related?.entryCounts ?? {} + for (const [hashedTrackId, count] of Object.entries(entryCounts)) { + const trackId = OptionalHashId.parse(hashedTrackId) + if (!trackId) continue + queryClient.setQueryData( + getRemixesCountQueryKey({ trackId, isContestEntry: true }), + count + ) + } + return eventMetadataListFromSDK(data) }, resolver: (events: Event[], entityId: ID) => diff --git a/packages/sdk/src/sdk/api/generated/default/models/EventsResponse.ts b/packages/sdk/src/sdk/api/generated/default/models/EventsResponse.ts index 3460c025e74..894c7f349bf 100644 --- a/packages/sdk/src/sdk/api/generated/default/models/EventsResponse.ts +++ b/packages/sdk/src/sdk/api/generated/default/models/EventsResponse.ts @@ -19,19 +19,31 @@ import { EventFromJSONTyped, EventToJSON, } from './Event'; +import type { RemixContestsRelated } from './RemixContestsRelated'; +import { + RemixContestsRelatedFromJSON, + RemixContestsRelatedFromJSONTyped, + RemixContestsRelatedToJSON, +} from './RemixContestsRelated'; /** - * + * * @export * @interface EventsResponse */ export interface EventsResponse { /** - * + * * @type {Array} * @memberof EventsResponse */ data?: Array; + /** + * + * @type {RemixContestsRelated} + * @memberof EventsResponse + */ + related?: RemixContestsRelated; } /** @@ -52,8 +64,9 @@ export function EventsResponseFromJSONTyped(json: any, ignoreDiscriminator: bool return json; } return { - + 'data': !exists(json, 'data') ? undefined : ((json['data'] as Array).map(EventFromJSON)), + 'related': !exists(json, 'related') ? undefined : RemixContestsRelatedFromJSON(json['related']), }; } @@ -65,8 +78,9 @@ export function EventsResponseToJSON(value?: EventsResponse | null): any { return null; } return { - + 'data': value.data === undefined ? undefined : ((value.data as Array).map(EventToJSON)), + 'related': RemixContestsRelatedToJSON(value.related), }; }