migrate the single-source feed api classes to the appview client
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+24
-21
@@ -1,23 +1,25 @@
|
||||
import {
|
||||
AppBskyFeedDefs,
|
||||
type AppBskyFeedGetAuthorFeed as GetAuthorFeed,
|
||||
type AtpAgent,
|
||||
} from '@atproto/api'
|
||||
import {AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
type GetAuthorFeedParams = XrpcRequestParams<
|
||||
typeof app.bsky.feed.getAuthorFeed.main
|
||||
>
|
||||
|
||||
export class AuthorFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
_params: GetAuthorFeed.QueryParams
|
||||
client: Client
|
||||
_params: GetAuthorFeedParams
|
||||
|
||||
constructor({
|
||||
agent,
|
||||
client,
|
||||
feedParams,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
feedParams: GetAuthorFeed.QueryParams
|
||||
client: Client
|
||||
feedParams: GetAuthorFeedParams
|
||||
}) {
|
||||
this.agent = agent
|
||||
this.client = client
|
||||
this._params = feedParams
|
||||
}
|
||||
|
||||
@@ -28,11 +30,11 @@ export class AuthorFeedAPI implements FeedAPI {
|
||||
}
|
||||
|
||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||
const res = await this.agent.getAuthorFeed({
|
||||
const data = await this.client.call(app.bsky.feed.getAuthorFeed, {
|
||||
...this.params,
|
||||
limit: 1,
|
||||
})
|
||||
return res.data.feed[0]
|
||||
return data.feed[0]
|
||||
}
|
||||
|
||||
async fetch({
|
||||
@@ -42,19 +44,20 @@ export class AuthorFeedAPI implements FeedAPI {
|
||||
cursor: string | undefined
|
||||
limit: number
|
||||
}): Promise<FeedAPIResponse> {
|
||||
const res = await this.agent.getAuthorFeed({
|
||||
/*
|
||||
* A failed request rejects rather than resolving, so the error propagates
|
||||
* to the query and drives the feed error UI (blocked actor, rate limit).
|
||||
* The agent behaved the same way - its `success` flag was only ever true -
|
||||
* so the empty-page branch this replaces was unreachable.
|
||||
*/
|
||||
const data = await this.client.call(app.bsky.feed.getAuthorFeed, {
|
||||
...this.params,
|
||||
cursor,
|
||||
limit,
|
||||
})
|
||||
if (res.success) {
|
||||
return {
|
||||
cursor: res.data.cursor,
|
||||
feed: this._filter(res.data.feed),
|
||||
}
|
||||
}
|
||||
return {
|
||||
feed: [],
|
||||
cursor: data.cursor,
|
||||
feed: this._filter(data.feed),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import {type AppBskyFeedDefs, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
|
||||
import {DEMO_FEED} from '#/lib/demo'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
export class DemoFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
client: Client
|
||||
|
||||
constructor({agent}: {agent: AtpAgent}) {
|
||||
this.agent = agent
|
||||
constructor({client}: {client: Client}) {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import {type AppBskyFeedDefs, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
export class FollowingFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
client: Client
|
||||
|
||||
constructor({agent}: {agent: AtpAgent}) {
|
||||
this.agent = agent
|
||||
constructor({client}: {client: Client}) {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||
const res = await this.agent.getTimeline({
|
||||
const data = await this.client.call(app.bsky.feed.getTimeline, {
|
||||
limit: 1,
|
||||
})
|
||||
return res.data.feed[0]
|
||||
return data.feed[0]
|
||||
}
|
||||
|
||||
async fetch({
|
||||
@@ -23,18 +25,19 @@ export class FollowingFeedAPI implements FeedAPI {
|
||||
cursor: string | undefined
|
||||
limit: number
|
||||
}): Promise<FeedAPIResponse> {
|
||||
const res = await this.agent.getTimeline({
|
||||
/*
|
||||
* A failed request rejects rather than resolving, so the error propagates
|
||||
* to the query and drives the feed error UI. The agent behaved the same
|
||||
* way - its `success` flag was only ever true - so the empty-page branch
|
||||
* this replaces was unreachable.
|
||||
*/
|
||||
const data = await this.client.call(app.bsky.feed.getTimeline, {
|
||||
cursor,
|
||||
limit,
|
||||
})
|
||||
if (res.success) {
|
||||
return {
|
||||
cursor: res.data.cursor,
|
||||
feed: res.data.feed,
|
||||
}
|
||||
}
|
||||
return {
|
||||
feed: [],
|
||||
cursor: data.cursor,
|
||||
feed: data.feed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-23
@@ -1,32 +1,34 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedGetActorLikes as GetActorLikes,
|
||||
type AtpAgent,
|
||||
} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
type GetActorLikesParams = XrpcRequestParams<
|
||||
typeof app.bsky.feed.getActorLikes.main
|
||||
>
|
||||
|
||||
export class LikesFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
params: GetActorLikes.QueryParams
|
||||
client: Client
|
||||
params: GetActorLikesParams
|
||||
|
||||
constructor({
|
||||
agent,
|
||||
client,
|
||||
feedParams,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
feedParams: GetActorLikes.QueryParams
|
||||
client: Client
|
||||
feedParams: GetActorLikesParams
|
||||
}) {
|
||||
this.agent = agent
|
||||
this.client = client
|
||||
this.params = feedParams
|
||||
}
|
||||
|
||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||
const res = await this.agent.getActorLikes({
|
||||
const data = await this.client.call(app.bsky.feed.getActorLikes, {
|
||||
...this.params,
|
||||
limit: 1,
|
||||
})
|
||||
return res.data.feed[0]
|
||||
return data.feed[0]
|
||||
}
|
||||
|
||||
async fetch({
|
||||
@@ -36,21 +38,22 @@ export class LikesFeedAPI implements FeedAPI {
|
||||
cursor: string | undefined
|
||||
limit: number
|
||||
}): Promise<FeedAPIResponse> {
|
||||
const res = await this.agent.getActorLikes({
|
||||
/*
|
||||
* A failed request rejects rather than resolving, so the error propagates
|
||||
* to the query and drives the feed error UI. The agent behaved the same
|
||||
* way - its `success` flag was only ever true - so the empty-page branch
|
||||
* this replaces was unreachable.
|
||||
*/
|
||||
const data = await this.client.call(app.bsky.feed.getActorLikes, {
|
||||
...this.params,
|
||||
cursor,
|
||||
limit,
|
||||
})
|
||||
if (res.success) {
|
||||
// HACKFIX: the API incorrectly returns a cursor when there are no items -sfn
|
||||
const isEmptyPage = res.data.feed.length === 0
|
||||
return {
|
||||
cursor: isEmptyPage ? undefined : res.data.cursor,
|
||||
feed: res.data.feed,
|
||||
}
|
||||
}
|
||||
// HACKFIX: the API incorrectly returns a cursor when there are no items -sfn
|
||||
const isEmptyPage = data.feed.length === 0
|
||||
return {
|
||||
feed: [],
|
||||
cursor: isEmptyPage ? undefined : data.cursor,
|
||||
feed: data.feed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-21
@@ -1,32 +1,34 @@
|
||||
import {
|
||||
type Agent,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedGetListFeed as GetListFeed,
|
||||
} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
type GetListFeedParams = XrpcRequestParams<
|
||||
typeof app.bsky.feed.getListFeed.main
|
||||
>
|
||||
|
||||
export class ListFeedAPI implements FeedAPI {
|
||||
agent: Agent
|
||||
params: GetListFeed.QueryParams
|
||||
client: Client
|
||||
params: GetListFeedParams
|
||||
|
||||
constructor({
|
||||
agent,
|
||||
client,
|
||||
feedParams,
|
||||
}: {
|
||||
agent: Agent
|
||||
feedParams: GetListFeed.QueryParams
|
||||
client: Client
|
||||
feedParams: GetListFeedParams
|
||||
}) {
|
||||
this.agent = agent
|
||||
this.client = client
|
||||
this.params = feedParams
|
||||
}
|
||||
|
||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||
const res = await this.agent.app.bsky.feed.getListFeed({
|
||||
const data = await this.client.call(app.bsky.feed.getListFeed, {
|
||||
...this.params,
|
||||
limit: 1,
|
||||
})
|
||||
return res.data.feed[0]
|
||||
return data.feed[0]
|
||||
}
|
||||
|
||||
async fetch({
|
||||
@@ -36,19 +38,20 @@ export class ListFeedAPI implements FeedAPI {
|
||||
cursor: string | undefined
|
||||
limit: number
|
||||
}): Promise<FeedAPIResponse> {
|
||||
const res = await this.agent.app.bsky.feed.getListFeed({
|
||||
/*
|
||||
* A failed request rejects rather than resolving, so the error propagates
|
||||
* to the query and drives the feed error UI. The agent behaved the same
|
||||
* way - its `success` flag was only ever true - so the empty-page branch
|
||||
* this replaces was unreachable.
|
||||
*/
|
||||
const data = await this.client.call(app.bsky.feed.getListFeed, {
|
||||
...this.params,
|
||||
cursor,
|
||||
limit,
|
||||
})
|
||||
if (res.success) {
|
||||
return {
|
||||
cursor: res.data.cursor,
|
||||
feed: res.data.feed,
|
||||
}
|
||||
}
|
||||
return {
|
||||
feed: [],
|
||||
cursor: data.cursor,
|
||||
feed: data.feed,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-19
@@ -1,25 +1,25 @@
|
||||
import {
|
||||
type Agent,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedGetPosts,
|
||||
} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
import {app} from '#/lexicons'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
type GetPostsParams = XrpcRequestParams<typeof app.bsky.feed.getPosts.main>
|
||||
|
||||
export class PostListFeedAPI implements FeedAPI {
|
||||
agent: Agent
|
||||
params: AppBskyFeedGetPosts.QueryParams
|
||||
client: Client
|
||||
params: GetPostsParams
|
||||
peek: AppBskyFeedDefs.FeedViewPost | null = null
|
||||
|
||||
constructor({
|
||||
agent,
|
||||
client,
|
||||
feedParams,
|
||||
}: {
|
||||
agent: Agent
|
||||
feedParams: AppBskyFeedGetPosts.QueryParams
|
||||
client: Client
|
||||
feedParams: GetPostsParams
|
||||
}) {
|
||||
this.agent = agent
|
||||
this.client = client
|
||||
if (feedParams.uris.length > 25) {
|
||||
logger.warn(
|
||||
`Too many URIs provided - expected 25, got ${feedParams.uris.length}`,
|
||||
@@ -36,17 +36,18 @@ export class PostListFeedAPI implements FeedAPI {
|
||||
}
|
||||
|
||||
async fetch({}: {}): Promise<FeedAPIResponse> {
|
||||
const res = await this.agent.app.bsky.feed.getPosts({
|
||||
/*
|
||||
* A failed request rejects rather than resolving, so the error propagates
|
||||
* to the query and drives the feed error UI. The agent behaved the same
|
||||
* way - its `success` flag was only ever true - so the empty-page branch
|
||||
* this replaces was unreachable.
|
||||
*/
|
||||
const data = await this.client.call(app.bsky.feed.getPosts, {
|
||||
...this.params,
|
||||
})
|
||||
if (res.success) {
|
||||
this.peek = {post: res.data.posts[0]}
|
||||
return {
|
||||
feed: res.data.posts.map(post => ({post})),
|
||||
}
|
||||
}
|
||||
this.peek = {post: data.posts[0]}
|
||||
return {
|
||||
feed: [],
|
||||
feed: data.posts.map(post => ({post})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user