diff --git a/packages/bsky/src/hydration/feed.ts b/packages/bsky/src/hydration/feed.ts index 1cec1880161..9d71d987753 100644 --- a/packages/bsky/src/hydration/feed.ts +++ b/packages/bsky/src/hydration/feed.ts @@ -1,5 +1,6 @@ import { DataPlaneClient } from '../data-plane/client' import { Record as PostRecord } from '../lexicon/types/app/bsky/feed/post' +import { Record as LikeRecord } from '../lexicon/types/app/bsky/feed/like' import { Record as FeedGenRecord } from '../lexicon/types/app/bsky/feed/generator' import { Record as ThreadgateRecord } from '../lexicon/types/app/bsky/feed/threadgate' import { HydrationMap } from './util' @@ -21,6 +22,9 @@ export type PostAgg = { export type PostAggs = HydrationMap +export type Like = LikeRecord +export type Likes = HydrationMap + export type FeedGenAgg = { likes: number } @@ -75,4 +79,9 @@ export class FeedHydrator { async getThreadgatesForPosts(postUris: string[]): Promise { throw new Error('unimplemented') } + + // @TODO may not be supported yet by data plane + async getLikes(uris: string[]): Promise { + throw new Error('unimplemented') + } } diff --git a/packages/bsky/src/hydration/graph.ts b/packages/bsky/src/hydration/graph.ts index 4b0ecba2ec7..66f2f667246 100644 --- a/packages/bsky/src/hydration/graph.ts +++ b/packages/bsky/src/hydration/graph.ts @@ -1,10 +1,14 @@ import { Record as ListRecord } from '../lexicon/types/app/bsky/graph/list' +import { Record as ListItemRecord } from '../lexicon/types/app/bsky/graph/listitem' import { DataPlaneClient } from '../data-plane/client' import { HydrationMap, RecordInfo, parseRecord } from './util' export type List = RecordInfo export type Lists = HydrationMap +export type ListItem = RecordInfo +export type ListItems = HydrationMap + export type ListViewerState = { viewerMuted?: string viewerListBlockUri?: string @@ -38,6 +42,11 @@ export class GraphHydrator { }, new HydrationMap()) } + // @TODO may not be supported yet by data plane + async getListItems(uris: string[]): Promise { + throw new Error('unimplemented') + } + async getListViewerStates( uris: string[], viewer: string, diff --git a/packages/bsky/src/hydration/hydrator.ts b/packages/bsky/src/hydration/hydrator.ts index dba8109dca8..0f259567b2b 100644 --- a/packages/bsky/src/hydration/hydrator.ts +++ b/packages/bsky/src/hydration/hydrator.ts @@ -8,7 +8,7 @@ import { ProfileViewerStates, ProfileViewerState, } from './actor' -import { GraphHydrator, ListViewerStates, Lists } from './graph' +import { GraphHydrator, ListItems, ListViewerStates, Lists } from './graph' import { LabelHydrator, Labels } from './label' import { HydrationMap } from './util' import { @@ -16,6 +16,7 @@ import { FeedGens, FeedGenViewerStates, FeedHydrator, + Likes, } from './feed' export type HydrationState = { @@ -24,6 +25,8 @@ export type HydrationState = { profileAggs?: ProfileAggs lists?: Lists listViewers?: ListViewerStates + listItems?: ListItems + likes?: Likes labels?: Labels feedgens?: FeedGens feedgenViewers?: FeedGenViewerStates @@ -123,18 +126,46 @@ export class Hydrator { return { lists, listViewers } } + // app.bsky.graph.defs#listItemView + // - list item + // - profile + // - list basic + async hydrateListItems( + uris: string[], + viewer: string | null, + ): Promise { + const listItems = await this.graph.getListItems(uris) + const dids: string[] = [] + listItems.forEach((item) => { + if (item) { + dids.push(item.record.subject) + } + }) + const profileState = await this.hydrateProfiles(dids, viewer) + return mergeStates(profileState, { listItems }) + } + // app.bsky.feed.defs#postView - async hydratePosts(uris: string[]): Promise { + async hydratePosts( + uris: string[], + viewer: string | null, + ): Promise { throw new Error('not implemented') } // app.bsky.feed.defs#feedViewPost - async hydrateFeedPosts(uris: string[]): Promise { + async hydrateFeedPosts( + uris: string[], + viewer: string | null, + ): Promise { throw new Error('not implemented') } // app.bsky.feed.defs#threadViewPost - async hydrateThreadPosts(uris: string[]): Promise { + async hydrateThreadPosts( + uris: string[], + viewer: string | null, + ): Promise { throw new Error('not implemented') } @@ -142,7 +173,10 @@ export class Hydrator { // - feedgen // - profile // - list basic - async hydrateFeedGens(uris: string[], viewer): Promise { + async hydrateFeedGens( + uris: string[], + viewer: string | null, + ): Promise { const [feedgens, feedgenAggs, feedgenViewers, profileState] = await Promise.all([ this.feed.getFeedGens(uris), @@ -156,6 +190,18 @@ export class Hydrator { feedgenViewers, }) } + + // app.bsky.feed.getLikes#like + // - like + // - profile + // - list basic + async hydrateLikes(uris: string[], viewer: string | null) { + const [likes, profileState] = await Promise.all([ + this.feed.getLikes(uris), + this.hydrateProfiles(uris.map(didFromUri), viewer), + ]) + return mergeStates(profileState, { likes }) + } } const listUrisFromProfileViewer = (item: ProfileViewerState | null) => { @@ -190,6 +236,8 @@ const mergeStates = ( profileViewers: mergeMaps(stateA.profileViewers, stateB.profileViewers), lists: mergeMaps(stateA.lists, stateB.lists), listViewers: mergeMaps(stateA.listViewers, stateB.listViewers), + listItems: mergeMaps(stateA.listItems, stateB.listItems), + likes: mergeMaps(stateA.likes, stateB.likes), labels: mergeMaps(stateA.labels, stateB.labels), feedgens: mergeMaps(stateA.feedgens, stateB.feedgens), feedgenAggs: mergeMaps(stateA.feedgenAggs, stateB.feedgenAggs),