diff options
Diffstat (limited to 'src/lib/api/feed/merge.ts')
-rw-r--r-- | src/lib/api/feed/merge.ts | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/src/lib/api/feed/merge.ts b/src/lib/api/feed/merge.ts index e0fbcecd8..7a0f02887 100644 --- a/src/lib/api/feed/merge.ts +++ b/src/lib/api/feed/merge.ts @@ -1,11 +1,12 @@ -import {AppBskyFeedDefs, AppBskyFeedGetTimeline} from '@atproto/api' +import {AppBskyFeedDefs, AppBskyFeedGetTimeline, BskyAgent} from '@atproto/api' import shuffle from 'lodash.shuffle' -import {RootStoreModel} from 'state/index' import {timeout} from 'lib/async/timeout' import {bundleAsync} from 'lib/async/bundle' import {feedUriToHref} from 'lib/strings/url-helpers' import {FeedTuner} from '../feed-manip' -import {FeedAPI, FeedAPIResponse, FeedSourceInfo} from './types' +import {FeedAPI, FeedAPIResponse, ReasonFeedSource} from './types' +import {FeedParams} from '#/state/queries/post-feed' +import {FeedTunerFn} from '../feed-manip' const REQUEST_WAIT_MS = 500 // 500ms const POST_AGE_CUTOFF = 60e3 * 60 * 24 // 24hours @@ -17,28 +18,49 @@ export class MergeFeedAPI implements FeedAPI { itemCursor = 0 sampleCursor = 0 - constructor(public rootStore: RootStoreModel) { - this.following = new MergeFeedSource_Following(this.rootStore) + constructor( + public agent: BskyAgent, + public params: FeedParams, + public feedTuners: FeedTunerFn[], + ) { + this.following = new MergeFeedSource_Following(this.agent, this.feedTuners) } reset() { - this.following = new MergeFeedSource_Following(this.rootStore) + this.following = new MergeFeedSource_Following(this.agent, this.feedTuners) this.customFeeds = [] // just empty the array, they will be captured in _fetchNext() this.feedCursor = 0 this.itemCursor = 0 this.sampleCursor = 0 + if (this.params.mergeFeedEnabled && this.params.mergeFeedSources) { + this.customFeeds = shuffle( + this.params.mergeFeedSources.map( + feedUri => + new MergeFeedSource_Custom(this.agent, feedUri, this.feedTuners), + ), + ) + } else { + this.customFeeds = [] + } } async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> { - const res = await this.rootStore.agent.getTimeline({ + const res = await this.agent.getTimeline({ limit: 1, }) return res.data.feed[0] } - async fetchNext({limit}: {limit: number}): Promise<FeedAPIResponse> { - // we capture here to ensure the data has loaded - this._captureFeedsIfNeeded() + async fetch({ + cursor, + limit, + }: { + cursor: string | undefined + limit: number + }): Promise<FeedAPIResponse> { + if (!cursor) { + this.reset() + } const promises = [] @@ -76,7 +98,7 @@ export class MergeFeedAPI implements FeedAPI { } return { - cursor: posts.length ? 'fake' : undefined, + cursor: posts.length ? String(this.itemCursor) : undefined, feed: posts, } } @@ -107,28 +129,15 @@ export class MergeFeedAPI implements FeedAPI { // provide follow return this.following.take(1) } - - _captureFeedsIfNeeded() { - if (!this.rootStore.preferences.homeFeed.lab_mergeFeedEnabled) { - return - } - if (this.customFeeds.length === 0) { - this.customFeeds = shuffle( - this.rootStore.preferences.savedFeeds.map( - feedUri => new MergeFeedSource_Custom(this.rootStore, feedUri), - ), - ) - } - } } class MergeFeedSource { - sourceInfo: FeedSourceInfo | undefined + sourceInfo: ReasonFeedSource | undefined cursor: string | undefined = undefined queue: AppBskyFeedDefs.FeedViewPost[] = [] hasMore = true - constructor(public rootStore: RootStoreModel) {} + constructor(public agent: BskyAgent, public feedTuners: FeedTunerFn[]) {} get numReady() { return this.queue.length @@ -190,16 +199,12 @@ class MergeFeedSource_Following extends MergeFeedSource { cursor: string | undefined, limit: number, ): Promise<AppBskyFeedGetTimeline.Response> { - const res = await this.rootStore.agent.getTimeline({cursor, limit}) + const res = await this.agent.getTimeline({cursor, limit}) // run the tuner pre-emptively to ensure better mixing - const slices = this.tuner.tune( - res.data.feed, - this.rootStore.preferences.getFeedTuners('home'), - { - dryRun: false, - maintainOrder: true, - }, - ) + const slices = this.tuner.tune(res.data.feed, this.feedTuners, { + dryRun: false, + maintainOrder: true, + }) res.data.feed = slices.map(slice => slice.rootItem) return res } @@ -208,14 +213,19 @@ class MergeFeedSource_Following extends MergeFeedSource { class MergeFeedSource_Custom extends MergeFeedSource { minDate: Date - constructor(public rootStore: RootStoreModel, public feedUri: string) { - super(rootStore) + constructor( + public agent: BskyAgent, + public feedUri: string, + public feedTuners: FeedTunerFn[], + ) { + super(agent, feedTuners) this.sourceInfo = { + $type: 'reasonFeedSource', displayName: feedUri.split('/').pop() || '', uri: feedUriToHref(feedUri), } this.minDate = new Date(Date.now() - POST_AGE_CUTOFF) - this.rootStore.agent.app.bsky.feed + this.agent.app.bsky.feed .getFeedGenerator({ feed: feedUri, }) @@ -234,7 +244,7 @@ class MergeFeedSource_Custom extends MergeFeedSource { limit: number, ): Promise<AppBskyFeedGetTimeline.Response> { try { - const res = await this.rootStore.agent.app.bsky.feed.getFeed({ + const res = await this.agent.app.bsky.feed.getFeed({ cursor, limit, feed: this.feedUri, |