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 {
|
import {AppBskyFeedDefs} from '@atproto/api'
|
||||||
AppBskyFeedDefs,
|
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||||
type AppBskyFeedGetAuthorFeed as GetAuthorFeed,
|
|
||||||
type AtpAgent,
|
|
||||||
} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||||
|
|
||||||
|
type GetAuthorFeedParams = XrpcRequestParams<
|
||||||
|
typeof app.bsky.feed.getAuthorFeed.main
|
||||||
|
>
|
||||||
|
|
||||||
export class AuthorFeedAPI implements FeedAPI {
|
export class AuthorFeedAPI implements FeedAPI {
|
||||||
agent: AtpAgent
|
client: Client
|
||||||
_params: GetAuthorFeed.QueryParams
|
_params: GetAuthorFeedParams
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
agent,
|
client,
|
||||||
feedParams,
|
feedParams,
|
||||||
}: {
|
}: {
|
||||||
agent: AtpAgent
|
client: Client
|
||||||
feedParams: GetAuthorFeed.QueryParams
|
feedParams: GetAuthorFeedParams
|
||||||
}) {
|
}) {
|
||||||
this.agent = agent
|
this.client = client
|
||||||
this._params = feedParams
|
this._params = feedParams
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,11 +30,11 @@ export class AuthorFeedAPI implements FeedAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||||
const res = await this.agent.getAuthorFeed({
|
const data = await this.client.call(app.bsky.feed.getAuthorFeed, {
|
||||||
...this.params,
|
...this.params,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
return res.data.feed[0]
|
return data.feed[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch({
|
async fetch({
|
||||||
@@ -42,19 +44,20 @@ export class AuthorFeedAPI implements FeedAPI {
|
|||||||
cursor: string | undefined
|
cursor: string | undefined
|
||||||
limit: number
|
limit: number
|
||||||
}): Promise<FeedAPIResponse> {
|
}): 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,
|
...this.params,
|
||||||
cursor,
|
cursor,
|
||||||
limit,
|
limit,
|
||||||
})
|
})
|
||||||
if (res.success) {
|
|
||||||
return {
|
return {
|
||||||
cursor: res.data.cursor,
|
cursor: data.cursor,
|
||||||
feed: this._filter(res.data.feed),
|
feed: this._filter(data.feed),
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
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 {DEMO_FEED} from '#/lib/demo'
|
||||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||||
|
|
||||||
export class DemoFeedAPI implements FeedAPI {
|
export class DemoFeedAPI implements FeedAPI {
|
||||||
agent: AtpAgent
|
client: Client
|
||||||
|
|
||||||
constructor({agent}: {agent: AtpAgent}) {
|
constructor({client}: {client: Client}) {
|
||||||
this.agent = agent
|
this.client = client
|
||||||
}
|
}
|
||||||
|
|
||||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
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'
|
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||||
|
|
||||||
export class FollowingFeedAPI implements FeedAPI {
|
export class FollowingFeedAPI implements FeedAPI {
|
||||||
agent: AtpAgent
|
client: Client
|
||||||
|
|
||||||
constructor({agent}: {agent: AtpAgent}) {
|
constructor({client}: {client: Client}) {
|
||||||
this.agent = agent
|
this.client = client
|
||||||
}
|
}
|
||||||
|
|
||||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||||
const res = await this.agent.getTimeline({
|
const data = await this.client.call(app.bsky.feed.getTimeline, {
|
||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
return res.data.feed[0]
|
return data.feed[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch({
|
async fetch({
|
||||||
@@ -23,18 +25,19 @@ export class FollowingFeedAPI implements FeedAPI {
|
|||||||
cursor: string | undefined
|
cursor: string | undefined
|
||||||
limit: number
|
limit: number
|
||||||
}): Promise<FeedAPIResponse> {
|
}): 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,
|
cursor,
|
||||||
limit,
|
limit,
|
||||||
})
|
})
|
||||||
if (res.success) {
|
|
||||||
return {
|
return {
|
||||||
cursor: res.data.cursor,
|
cursor: data.cursor,
|
||||||
feed: res.data.feed,
|
feed: data.feed,
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
feed: [],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-22
@@ -1,32 +1,34 @@
|
|||||||
import {
|
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||||
type AppBskyFeedDefs,
|
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||||
type AppBskyFeedGetActorLikes as GetActorLikes,
|
|
||||||
type AtpAgent,
|
|
||||||
} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||||
|
|
||||||
|
type GetActorLikesParams = XrpcRequestParams<
|
||||||
|
typeof app.bsky.feed.getActorLikes.main
|
||||||
|
>
|
||||||
|
|
||||||
export class LikesFeedAPI implements FeedAPI {
|
export class LikesFeedAPI implements FeedAPI {
|
||||||
agent: AtpAgent
|
client: Client
|
||||||
params: GetActorLikes.QueryParams
|
params: GetActorLikesParams
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
agent,
|
client,
|
||||||
feedParams,
|
feedParams,
|
||||||
}: {
|
}: {
|
||||||
agent: AtpAgent
|
client: Client
|
||||||
feedParams: GetActorLikes.QueryParams
|
feedParams: GetActorLikesParams
|
||||||
}) {
|
}) {
|
||||||
this.agent = agent
|
this.client = client
|
||||||
this.params = feedParams
|
this.params = feedParams
|
||||||
}
|
}
|
||||||
|
|
||||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
||||||
const res = await this.agent.getActorLikes({
|
const data = await this.client.call(app.bsky.feed.getActorLikes, {
|
||||||
...this.params,
|
...this.params,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
return res.data.feed[0]
|
return data.feed[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch({
|
async fetch({
|
||||||
@@ -36,21 +38,22 @@ export class LikesFeedAPI implements FeedAPI {
|
|||||||
cursor: string | undefined
|
cursor: string | undefined
|
||||||
limit: number
|
limit: number
|
||||||
}): Promise<FeedAPIResponse> {
|
}): 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,
|
...this.params,
|
||||||
cursor,
|
cursor,
|
||||||
limit,
|
limit,
|
||||||
})
|
})
|
||||||
if (res.success) {
|
|
||||||
// HACKFIX: the API incorrectly returns a cursor when there are no items -sfn
|
// HACKFIX: the API incorrectly returns a cursor when there are no items -sfn
|
||||||
const isEmptyPage = res.data.feed.length === 0
|
const isEmptyPage = data.feed.length === 0
|
||||||
return {
|
return {
|
||||||
cursor: isEmptyPage ? undefined : res.data.cursor,
|
cursor: isEmptyPage ? undefined : data.cursor,
|
||||||
feed: res.data.feed,
|
feed: data.feed,
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
feed: [],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-21
@@ -1,32 +1,34 @@
|
|||||||
import {
|
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||||
type Agent,
|
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||||
type AppBskyFeedDefs,
|
|
||||||
type AppBskyFeedGetListFeed as GetListFeed,
|
|
||||||
} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||||
|
|
||||||
|
type GetListFeedParams = XrpcRequestParams<
|
||||||
|
typeof app.bsky.feed.getListFeed.main
|
||||||
|
>
|
||||||
|
|
||||||
export class ListFeedAPI implements FeedAPI {
|
export class ListFeedAPI implements FeedAPI {
|
||||||
agent: Agent
|
client: Client
|
||||||
params: GetListFeed.QueryParams
|
params: GetListFeedParams
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
agent,
|
client,
|
||||||
feedParams,
|
feedParams,
|
||||||
}: {
|
}: {
|
||||||
agent: Agent
|
client: Client
|
||||||
feedParams: GetListFeed.QueryParams
|
feedParams: GetListFeedParams
|
||||||
}) {
|
}) {
|
||||||
this.agent = agent
|
this.client = client
|
||||||
this.params = feedParams
|
this.params = feedParams
|
||||||
}
|
}
|
||||||
|
|
||||||
async peekLatest(): Promise<AppBskyFeedDefs.FeedViewPost> {
|
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,
|
...this.params,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
})
|
})
|
||||||
return res.data.feed[0]
|
return data.feed[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch({
|
async fetch({
|
||||||
@@ -36,19 +38,20 @@ export class ListFeedAPI implements FeedAPI {
|
|||||||
cursor: string | undefined
|
cursor: string | undefined
|
||||||
limit: number
|
limit: number
|
||||||
}): Promise<FeedAPIResponse> {
|
}): 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,
|
...this.params,
|
||||||
cursor,
|
cursor,
|
||||||
limit,
|
limit,
|
||||||
})
|
})
|
||||||
if (res.success) {
|
|
||||||
return {
|
return {
|
||||||
cursor: res.data.cursor,
|
cursor: data.cursor,
|
||||||
feed: res.data.feed,
|
feed: data.feed,
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
feed: [],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-19
@@ -1,25 +1,25 @@
|
|||||||
import {
|
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||||
type Agent,
|
import {type Client, type XrpcRequestParams} from '@atproto/lex'
|
||||||
type AppBskyFeedDefs,
|
|
||||||
type AppBskyFeedGetPosts,
|
|
||||||
} from '@atproto/api'
|
|
||||||
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||||
|
|
||||||
|
type GetPostsParams = XrpcRequestParams<typeof app.bsky.feed.getPosts.main>
|
||||||
|
|
||||||
export class PostListFeedAPI implements FeedAPI {
|
export class PostListFeedAPI implements FeedAPI {
|
||||||
agent: Agent
|
client: Client
|
||||||
params: AppBskyFeedGetPosts.QueryParams
|
params: GetPostsParams
|
||||||
peek: AppBskyFeedDefs.FeedViewPost | null = null
|
peek: AppBskyFeedDefs.FeedViewPost | null = null
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
agent,
|
client,
|
||||||
feedParams,
|
feedParams,
|
||||||
}: {
|
}: {
|
||||||
agent: Agent
|
client: Client
|
||||||
feedParams: AppBskyFeedGetPosts.QueryParams
|
feedParams: GetPostsParams
|
||||||
}) {
|
}) {
|
||||||
this.agent = agent
|
this.client = client
|
||||||
if (feedParams.uris.length > 25) {
|
if (feedParams.uris.length > 25) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`Too many URIs provided - expected 25, got ${feedParams.uris.length}`,
|
`Too many URIs provided - expected 25, got ${feedParams.uris.length}`,
|
||||||
@@ -36,17 +36,18 @@ export class PostListFeedAPI implements FeedAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fetch({}: {}): Promise<FeedAPIResponse> {
|
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,
|
...this.params,
|
||||||
})
|
})
|
||||||
if (res.success) {
|
this.peek = {post: data.posts[0]}
|
||||||
this.peek = {post: res.data.posts[0]}
|
|
||||||
return {
|
return {
|
||||||
feed: res.data.posts.map(post => ({post})),
|
feed: data.posts.map(post => ({post})),
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
feed: [],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user