about summary refs log tree commit diff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/api/feed/author.ts21
-rw-r--r--src/lib/api/feed/custom.ts28
-rw-r--r--src/lib/api/feed/following.ts14
-rw-r--r--src/lib/api/feed/home.ts27
-rw-r--r--src/lib/api/feed/likes.ts21
-rw-r--r--src/lib/api/feed/list.ts21
-rw-r--r--src/lib/api/feed/merge.ts89
7 files changed, 172 insertions, 49 deletions
diff --git a/src/lib/api/feed/author.ts b/src/lib/api/feed/author.ts
index 57db061b3..85601d068 100644
--- a/src/lib/api/feed/author.ts
+++ b/src/lib/api/feed/author.ts
@@ -1,15 +1,28 @@
 import {
   AppBskyFeedDefs,
   AppBskyFeedGetAuthorFeed as GetAuthorFeed,
+  BskyAgent,
 } from '@atproto/api'
+
 import {FeedAPI, FeedAPIResponse} from './types'
-import {getAgent} from '#/state/session'
 
 export class AuthorFeedAPI implements FeedAPI {
-  constructor(public params: GetAuthorFeed.QueryParams) {}
+  getAgent: () => BskyAgent
+  params: GetAuthorFeed.QueryParams
+
+  constructor({
+    getAgent,
+    feedParams,
+  }: {
+    getAgent: () => BskyAgent
+    feedParams: GetAuthorFeed.QueryParams
+  }) {
+    this.getAgent = getAgent
+    this.params = feedParams
+  }
 
   async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
-    const res = await getAgent().getAuthorFeed({
+    const res = await this.getAgent().getAuthorFeed({
       ...this.params,
       limit: 1,
     })
@@ -23,7 +36,7 @@ export class AuthorFeedAPI implements FeedAPI {
     cursor: string | undefined
     limit: number
   }): Promise<FeedAPIResponse> {
-    const res = await getAgent().getAuthorFeed({
+    const res = await this.getAgent().getAuthorFeed({
       ...this.params,
       cursor,
       limit,
diff --git a/src/lib/api/feed/custom.ts b/src/lib/api/feed/custom.ts
index bd30d58ac..75182c41f 100644
--- a/src/lib/api/feed/custom.ts
+++ b/src/lib/api/feed/custom.ts
@@ -2,18 +2,30 @@ import {
   AppBskyFeedDefs,
   AppBskyFeedGetFeed as GetCustomFeed,
   AtpAgent,
+  BskyAgent,
 } from '@atproto/api'
 
 import {getContentLanguages} from '#/state/preferences/languages'
-import {getAgent} from '#/state/session'
 import {FeedAPI, FeedAPIResponse} from './types'
 
 export class CustomFeedAPI implements FeedAPI {
-  constructor(public params: GetCustomFeed.QueryParams) {}
+  getAgent: () => BskyAgent
+  params: GetCustomFeed.QueryParams
+
+  constructor({
+    getAgent,
+    feedParams,
+  }: {
+    getAgent: () => BskyAgent
+    feedParams: GetCustomFeed.QueryParams
+  }) {
+    this.getAgent = getAgent
+    this.params = feedParams
+  }
 
   async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
     const contentLangs = getContentLanguages().join(',')
-    const res = await getAgent().app.bsky.feed.getFeed(
+    const res = await this.getAgent().app.bsky.feed.getFeed(
       {
         ...this.params,
         limit: 1,
@@ -31,15 +43,19 @@ export class CustomFeedAPI implements FeedAPI {
     limit: number
   }): Promise<FeedAPIResponse> {
     const contentLangs = getContentLanguages().join(',')
-    const agent = getAgent()
+    const agent = this.getAgent()
     const res = agent.session
-      ? await getAgent().app.bsky.feed.getFeed(
+      ? await this.getAgent().app.bsky.feed.getFeed(
           {
             ...this.params,
             cursor,
             limit,
           },
-          {headers: {'Accept-Language': contentLangs}},
+          {
+            headers: {
+              'Accept-Language': contentLangs,
+            },
+          },
         )
       : await loggedOutFetch({...this.params, cursor, limit})
     if (res.success) {
diff --git a/src/lib/api/feed/following.ts b/src/lib/api/feed/following.ts
index 24389b5ed..36c376554 100644
--- a/src/lib/api/feed/following.ts
+++ b/src/lib/api/feed/following.ts
@@ -1,12 +1,16 @@
-import {AppBskyFeedDefs} from '@atproto/api'
+import {AppBskyFeedDefs, BskyAgent} from '@atproto/api'
+
 import {FeedAPI, FeedAPIResponse} from './types'
-import {getAgent} from '#/state/session'
 
 export class FollowingFeedAPI implements FeedAPI {
-  constructor() {}
+  getAgent: () => BskyAgent
+
+  constructor({getAgent}: {getAgent: () => BskyAgent}) {
+    this.getAgent = getAgent
+  }
 
   async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
-    const res = await getAgent().getTimeline({
+    const res = await this.getAgent().getTimeline({
       limit: 1,
     })
     return res.data.feed[0]
@@ -19,7 +23,7 @@ export class FollowingFeedAPI implements FeedAPI {
     cursor: string | undefined
     limit: number
   }): Promise<FeedAPIResponse> {
-    const res = await getAgent().getTimeline({
+    const res = await this.getAgent().getTimeline({
       cursor,
       limit,
     })
diff --git a/src/lib/api/feed/home.ts b/src/lib/api/feed/home.ts
index 436a66d07..4a5308346 100644
--- a/src/lib/api/feed/home.ts
+++ b/src/lib/api/feed/home.ts
@@ -1,8 +1,9 @@
-import {AppBskyFeedDefs} from '@atproto/api'
-import {FeedAPI, FeedAPIResponse} from './types'
-import {FollowingFeedAPI} from './following'
-import {CustomFeedAPI} from './custom'
+import {AppBskyFeedDefs, BskyAgent} from '@atproto/api'
+
 import {PROD_DEFAULT_FEED} from '#/lib/constants'
+import {CustomFeedAPI} from './custom'
+import {FollowingFeedAPI} from './following'
+import {FeedAPI, FeedAPIResponse} from './types'
 
 // HACK
 // the feed API does not include any facilities for passing down
@@ -26,19 +27,27 @@ export const FALLBACK_MARKER_POST: AppBskyFeedDefs.FeedViewPost = {
 }
 
 export class HomeFeedAPI implements FeedAPI {
+  getAgent: () => BskyAgent
   following: FollowingFeedAPI
   discover: CustomFeedAPI
   usingDiscover = false
   itemCursor = 0
 
-  constructor() {
-    this.following = new FollowingFeedAPI()
-    this.discover = new CustomFeedAPI({feed: PROD_DEFAULT_FEED('whats-hot')})
+  constructor({getAgent}: {getAgent: () => BskyAgent}) {
+    this.getAgent = getAgent
+    this.following = new FollowingFeedAPI({getAgent})
+    this.discover = new CustomFeedAPI({
+      getAgent,
+      feedParams: {feed: PROD_DEFAULT_FEED('whats-hot')},
+    })
   }
 
   reset() {
-    this.following = new FollowingFeedAPI()
-    this.discover = new CustomFeedAPI({feed: PROD_DEFAULT_FEED('whats-hot')})
+    this.following = new FollowingFeedAPI({getAgent: this.getAgent})
+    this.discover = new CustomFeedAPI({
+      getAgent: this.getAgent,
+      feedParams: {feed: PROD_DEFAULT_FEED('whats-hot')},
+    })
     this.usingDiscover = false
     this.itemCursor = 0
   }
diff --git a/src/lib/api/feed/likes.ts b/src/lib/api/feed/likes.ts
index 2b0afdf11..1729ee05c 100644
--- a/src/lib/api/feed/likes.ts
+++ b/src/lib/api/feed/likes.ts
@@ -1,15 +1,28 @@
 import {
   AppBskyFeedDefs,
   AppBskyFeedGetActorLikes as GetActorLikes,
+  BskyAgent,
 } from '@atproto/api'
+
 import {FeedAPI, FeedAPIResponse} from './types'
-import {getAgent} from '#/state/session'
 
 export class LikesFeedAPI implements FeedAPI {
-  constructor(public params: GetActorLikes.QueryParams) {}
+  getAgent: () => BskyAgent
+  params: GetActorLikes.QueryParams
+
+  constructor({
+    getAgent,
+    feedParams,
+  }: {
+    getAgent: () => BskyAgent
+    feedParams: GetActorLikes.QueryParams
+  }) {
+    this.getAgent = getAgent
+    this.params = feedParams
+  }
 
   async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
-    const res = await getAgent().getActorLikes({
+    const res = await this.getAgent().getActorLikes({
       ...this.params,
       limit: 1,
     })
@@ -23,7 +36,7 @@ export class LikesFeedAPI implements FeedAPI {
     cursor: string | undefined
     limit: number
   }): Promise<FeedAPIResponse> {
-    const res = await getAgent().getActorLikes({
+    const res = await this.getAgent().getActorLikes({
       ...this.params,
       cursor,
       limit,
diff --git a/src/lib/api/feed/list.ts b/src/lib/api/feed/list.ts
index 19f2ff177..004685b99 100644
--- a/src/lib/api/feed/list.ts
+++ b/src/lib/api/feed/list.ts
@@ -1,15 +1,28 @@
 import {
   AppBskyFeedDefs,
   AppBskyFeedGetListFeed as GetListFeed,
+  BskyAgent,
 } from '@atproto/api'
+
 import {FeedAPI, FeedAPIResponse} from './types'
-import {getAgent} from '#/state/session'
 
 export class ListFeedAPI implements FeedAPI {
-  constructor(public params: GetListFeed.QueryParams) {}
+  getAgent: () => BskyAgent
+  params: GetListFeed.QueryParams
+
+  constructor({
+    getAgent,
+    feedParams,
+  }: {
+    getAgent: () => BskyAgent
+    feedParams: GetListFeed.QueryParams
+  }) {
+    this.getAgent = getAgent
+    this.params = feedParams
+  }
 
   async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
-    const res = await getAgent().app.bsky.feed.getListFeed({
+    const res = await this.getAgent().app.bsky.feed.getListFeed({
       ...this.params,
       limit: 1,
     })
@@ -23,7 +36,7 @@ export class ListFeedAPI implements FeedAPI {
     cursor: string | undefined
     limit: number
   }): Promise<FeedAPIResponse> {
-    const res = await getAgent().app.bsky.feed.getListFeed({
+    const res = await this.getAgent().app.bsky.feed.getListFeed({
       ...this.params,
       cursor,
       limit,
diff --git a/src/lib/api/feed/merge.ts b/src/lib/api/feed/merge.ts
index 28bf143cb..c85de0306 100644
--- a/src/lib/api/feed/merge.ts
+++ b/src/lib/api/feed/merge.ts
@@ -1,31 +1,51 @@
-import {AppBskyFeedDefs, AppBskyFeedGetTimeline} from '@atproto/api'
+import {AppBskyFeedDefs, AppBskyFeedGetTimeline, BskyAgent} from '@atproto/api'
 import shuffle from 'lodash.shuffle'
-import {timeout} from 'lib/async/timeout'
+
+import {getContentLanguages} from '#/state/preferences/languages'
+import {FeedParams} from '#/state/queries/post-feed'
 import {bundleAsync} from 'lib/async/bundle'
+import {timeout} from 'lib/async/timeout'
 import {feedUriToHref} from 'lib/strings/url-helpers'
 import {FeedTuner} from '../feed-manip'
-import {FeedAPI, FeedAPIResponse, ReasonFeedSource} from './types'
-import {FeedParams} from '#/state/queries/post-feed'
 import {FeedTunerFn} from '../feed-manip'
-import {getAgent} from '#/state/session'
-import {getContentLanguages} from '#/state/preferences/languages'
+import {FeedAPI, FeedAPIResponse, ReasonFeedSource} from './types'
 
 const REQUEST_WAIT_MS = 500 // 500ms
 const POST_AGE_CUTOFF = 60e3 * 60 * 24 // 24hours
 
 export class MergeFeedAPI implements FeedAPI {
+  getAgent: () => BskyAgent
+  params: FeedParams
+  feedTuners: FeedTunerFn[]
   following: MergeFeedSource_Following
   customFeeds: MergeFeedSource_Custom[] = []
   feedCursor = 0
   itemCursor = 0
   sampleCursor = 0
 
-  constructor(public params: FeedParams, public feedTuners: FeedTunerFn[]) {
-    this.following = new MergeFeedSource_Following(this.feedTuners)
+  constructor({
+    getAgent,
+    feedParams,
+    feedTuners,
+  }: {
+    getAgent: () => BskyAgent
+    feedParams: FeedParams
+    feedTuners: FeedTunerFn[]
+  }) {
+    this.getAgent = getAgent
+    this.params = feedParams
+    this.feedTuners = feedTuners
+    this.following = new MergeFeedSource_Following({
+      getAgent: this.getAgent,
+      feedTuners: this.feedTuners,
+    })
   }
 
   reset() {
-    this.following = new MergeFeedSource_Following(this.feedTuners)
+    this.following = new MergeFeedSource_Following({
+      getAgent: this.getAgent,
+      feedTuners: this.feedTuners,
+    })
     this.customFeeds = []
     this.feedCursor = 0
     this.itemCursor = 0
@@ -33,7 +53,12 @@ export class MergeFeedAPI implements FeedAPI {
     if (this.params.mergeFeedSources) {
       this.customFeeds = shuffle(
         this.params.mergeFeedSources.map(
-          feedUri => new MergeFeedSource_Custom(feedUri, this.feedTuners),
+          feedUri =>
+            new MergeFeedSource_Custom({
+              getAgent: this.getAgent,
+              feedUri,
+              feedTuners: this.feedTuners,
+            }),
         ),
       )
     } else {
@@ -42,7 +67,7 @@ export class MergeFeedAPI implements FeedAPI {
   }
 
   async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
-    const res = await getAgent().getTimeline({
+    const res = await this.getAgent().getTimeline({
       limit: 1,
     })
     return res.data.feed[0]
@@ -136,12 +161,23 @@ export class MergeFeedAPI implements FeedAPI {
 }
 
 class MergeFeedSource {
+  getAgent: () => BskyAgent
+  feedTuners: FeedTunerFn[]
   sourceInfo: ReasonFeedSource | undefined
   cursor: string | undefined = undefined
   queue: AppBskyFeedDefs.FeedViewPost[] = []
   hasMore = true
 
-  constructor(public feedTuners: FeedTunerFn[]) {}
+  constructor({
+    getAgent,
+    feedTuners,
+  }: {
+    getAgent: () => BskyAgent
+    feedTuners: FeedTunerFn[]
+  }) {
+    this.getAgent = getAgent
+    this.feedTuners = feedTuners
+  }
 
   get numReady() {
     return this.queue.length
@@ -203,7 +239,7 @@ class MergeFeedSource_Following extends MergeFeedSource {
     cursor: string | undefined,
     limit: number,
   ): Promise<AppBskyFeedGetTimeline.Response> {
-    const res = await getAgent().getTimeline({cursor, limit})
+    const res = await this.getAgent().getTimeline({cursor, limit})
     // run the tuner pre-emptively to ensure better mixing
     const slices = this.tuner.tune(res.data.feed, {
       dryRun: false,
@@ -215,10 +251,25 @@ class MergeFeedSource_Following extends MergeFeedSource {
 }
 
 class MergeFeedSource_Custom extends MergeFeedSource {
+  getAgent: () => BskyAgent
   minDate: Date
+  feedUri: string
 
-  constructor(public feedUri: string, public feedTuners: FeedTunerFn[]) {
-    super(feedTuners)
+  constructor({
+    getAgent,
+    feedUri,
+    feedTuners,
+  }: {
+    getAgent: () => BskyAgent
+    feedUri: string
+    feedTuners: FeedTunerFn[]
+  }) {
+    super({
+      getAgent,
+      feedTuners,
+    })
+    this.getAgent = getAgent
+    this.feedUri = feedUri
     this.sourceInfo = {
       $type: 'reasonFeedSource',
       uri: feedUri,
@@ -233,13 +284,17 @@ class MergeFeedSource_Custom extends MergeFeedSource {
   ): Promise<AppBskyFeedGetTimeline.Response> {
     try {
       const contentLangs = getContentLanguages().join(',')
-      const res = await getAgent().app.bsky.feed.getFeed(
+      const res = await this.getAgent().app.bsky.feed.getFeed(
         {
           cursor,
           limit,
           feed: this.feedUri,
         },
-        {headers: {'Accept-Language': contentLangs}},
+        {
+          headers: {
+            'Accept-Language': contentLangs,
+          },
+        },
       )
       // NOTE
       // some custom feeds fail to enforce the pagination limit