migrate the list and feed generator queries to the appview client
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
type AppBskyActorDefs,
|
type AppBskyActorDefs,
|
||||||
type AppBskyGraphDefs,
|
type AppBskyGraphDefs,
|
||||||
type AppBskyGraphGetList,
|
|
||||||
type AtpAgent,
|
type AtpAgent,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {
|
import {
|
||||||
@@ -13,7 +12,8 @@ import {
|
|||||||
} from '@tanstack/react-query'
|
} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {STALE} from '#/state/queries'
|
import {STALE} from '#/state/queries'
|
||||||
import {useAgent} from '#/state/session'
|
import {useAgent, useAppviewClient} from '#/state/session'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
const PAGE_SIZE = 30
|
const PAGE_SIZE = 30
|
||||||
type RQPageParam = string | undefined
|
type RQPageParam = string | undefined
|
||||||
@@ -24,23 +24,23 @@ export const RQKEY = (uri: string) => [RQKEY_ROOT, uri]
|
|||||||
export const RQKEY_ALL = (uri: string) => [RQKEY_ROOT_ALL, uri]
|
export const RQKEY_ALL = (uri: string) => [RQKEY_ROOT_ALL, uri]
|
||||||
|
|
||||||
export function useListMembersQuery(uri?: string, limit: number = PAGE_SIZE) {
|
export function useListMembersQuery(uri?: string, limit: number = PAGE_SIZE) {
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
return useInfiniteQuery<
|
return useInfiniteQuery<
|
||||||
AppBskyGraphGetList.OutputSchema,
|
app.bsky.graph.getList.$OutputBody,
|
||||||
Error,
|
Error,
|
||||||
InfiniteData<AppBskyGraphGetList.OutputSchema>,
|
InfiniteData<app.bsky.graph.getList.$OutputBody>,
|
||||||
QueryKey,
|
QueryKey,
|
||||||
RQPageParam
|
RQPageParam
|
||||||
>({
|
>({
|
||||||
staleTime: STALE.MINUTES.ONE,
|
staleTime: STALE.MINUTES.ONE,
|
||||||
queryKey: RQKEY(uri ?? ''),
|
queryKey: RQKEY(uri ?? ''),
|
||||||
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
||||||
const res = await agent.app.bsky.graph.getList({
|
return await client.call(app.bsky.graph.getList, {
|
||||||
list: uri!, // the enabled flag will prevent this from running until uri is set
|
// the enabled flag will prevent this from running until uri is set
|
||||||
|
list: uri! as app.bsky.graph.getList.$Params['list'],
|
||||||
limit,
|
limit,
|
||||||
cursor: pageParam,
|
cursor: pageParam,
|
||||||
})
|
})
|
||||||
return res.data
|
|
||||||
},
|
},
|
||||||
initialPageParam: undefined,
|
initialPageParam: undefined,
|
||||||
getNextPageParam: lastPage => lastPage.cursor,
|
getNextPageParam: lastPage => lastPage.cursor,
|
||||||
@@ -60,6 +60,10 @@ export function useAllListMembersQuery(uri?: string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Still on the legacy agent: four call sites outside this cluster pass their
|
||||||
|
* own `AtpAgent`, so the parameter type is migrated with those consumers.
|
||||||
|
*/
|
||||||
export async function getAllListMembers(agent: AtpAgent, uri: string) {
|
export async function getAllListMembers(agent: AtpAgent, uri: string) {
|
||||||
let hasMore = true
|
let hasMore = true
|
||||||
let cursor: string | undefined
|
let cursor: string | undefined
|
||||||
@@ -95,7 +99,7 @@ export function* findAllProfilesInQueryData(
|
|||||||
did: string,
|
did: string,
|
||||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||||
const queryDatas = queryClient.getQueriesData<
|
const queryDatas = queryClient.getQueriesData<
|
||||||
InfiniteData<AppBskyGraphGetList.OutputSchema>
|
InfiniteData<app.bsky.graph.getList.$OutputBody>
|
||||||
>({
|
>({
|
||||||
queryKey: [RQKEY_ROOT],
|
queryKey: [RQKEY_ROOT],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import {
|
import {type AppBskyActorDefs} from '@atproto/api'
|
||||||
type AppBskyActorDefs,
|
|
||||||
type AppBskyGraphGetListsWithMembership,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {
|
import {
|
||||||
type InfiniteData,
|
type InfiniteData,
|
||||||
type QueryClient,
|
type QueryClient,
|
||||||
@@ -10,10 +7,11 @@ import {
|
|||||||
} from '@tanstack/react-query'
|
} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {createQueryKey} from '#/state/queries/util'
|
import {createQueryKey} from '#/state/queries/util'
|
||||||
import {useAgent} from '#/state/session'
|
import {useAppviewClient} from '#/state/session'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
export type ListWithMembership =
|
export type ListWithMembership =
|
||||||
AppBskyGraphGetListsWithMembership.ListWithMembership
|
app.bsky.graph.getListsWithMembership.ListWithMembership
|
||||||
|
|
||||||
const listsWithMembershipQueryKeyRoot = 'lists-with-membership'
|
const listsWithMembershipQueryKeyRoot = 'lists-with-membership'
|
||||||
export const createListsWithMembershipQueryKey = (args: {actor: string}) =>
|
export const createListsWithMembershipQueryKey = (args: {actor: string}) =>
|
||||||
@@ -26,23 +24,23 @@ export function useListsWithMembershipQuery({
|
|||||||
actor: string | undefined
|
actor: string | undefined
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
}) {
|
}) {
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
|
|
||||||
return useInfiniteQuery<
|
return useInfiniteQuery<
|
||||||
AppBskyGraphGetListsWithMembership.OutputSchema,
|
app.bsky.graph.getListsWithMembership.$OutputBody,
|
||||||
Error,
|
Error,
|
||||||
InfiniteData<AppBskyGraphGetListsWithMembership.OutputSchema>,
|
InfiniteData<app.bsky.graph.getListsWithMembership.$OutputBody>,
|
||||||
QueryKey,
|
QueryKey,
|
||||||
string | undefined
|
string | undefined
|
||||||
>({
|
>({
|
||||||
queryKey: createListsWithMembershipQueryKey({actor: actor ?? ''}),
|
queryKey: createListsWithMembershipQueryKey({actor: actor ?? ''}),
|
||||||
queryFn: async ({pageParam}: {pageParam?: string}) => {
|
queryFn: async ({pageParam}: {pageParam?: string}) => {
|
||||||
const res = await agent.app.bsky.graph.getListsWithMembership({
|
return await client.call(app.bsky.graph.getListsWithMembership, {
|
||||||
actor: actor!, // the enabled flag prevents this from running until actor is set
|
// the enabled flag prevents this from running until actor is set
|
||||||
|
actor: actor! as app.bsky.graph.getListsWithMembership.$Params['actor'],
|
||||||
limit: 50,
|
limit: 50,
|
||||||
cursor: pageParam,
|
cursor: pageParam,
|
||||||
})
|
})
|
||||||
return res.data
|
|
||||||
},
|
},
|
||||||
enabled: Boolean(actor) && enabled,
|
enabled: Boolean(actor) && enabled,
|
||||||
initialPageParam: undefined,
|
initialPageParam: undefined,
|
||||||
@@ -64,7 +62,7 @@ export function updateListMembershipOptimistically({
|
|||||||
subject: AppBskyActorDefs.ProfileView
|
subject: AppBskyActorDefs.ProfileView
|
||||||
}) {
|
}) {
|
||||||
queryClient.setQueryData<
|
queryClient.setQueryData<
|
||||||
InfiniteData<AppBskyGraphGetListsWithMembership.OutputSchema>
|
InfiniteData<app.bsky.graph.getListsWithMembership.$OutputBody>
|
||||||
>(createListsWithMembershipQueryKey({actor}), old => {
|
>(createListsWithMembershipQueryKey({actor}), old => {
|
||||||
if (!old) return old
|
if (!old) return old
|
||||||
|
|
||||||
@@ -74,12 +72,18 @@ export function updateListMembershipOptimistically({
|
|||||||
...page,
|
...page,
|
||||||
listsWithMembership: page.listsWithMembership.map(lwm => {
|
listsWithMembership: page.listsWithMembership.map(lwm => {
|
||||||
if (lwm.list.uri === listUri) {
|
if (lwm.list.uri === listUri) {
|
||||||
|
/*
|
||||||
|
* Callers hand over a plain at-uri and an old-world ProfileView,
|
||||||
|
* whose `uri`/`did` are unbranded strings. They are runtime
|
||||||
|
* identical to the generated branded forms, so the synthesised
|
||||||
|
* listItem is asserted rather than re-validated.
|
||||||
|
*/
|
||||||
return {
|
return {
|
||||||
...lwm,
|
...lwm,
|
||||||
listItem: {
|
listItem: {
|
||||||
uri: membershipUri,
|
uri: membershipUri,
|
||||||
subject,
|
subject,
|
||||||
},
|
} as app.bsky.graph.defs.ListItemView,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lwm
|
return lwm
|
||||||
@@ -99,7 +103,7 @@ export function removeListMembershipOptimistically({
|
|||||||
listUri: string
|
listUri: string
|
||||||
}) {
|
}) {
|
||||||
queryClient.setQueryData<
|
queryClient.setQueryData<
|
||||||
InfiniteData<AppBskyGraphGetListsWithMembership.OutputSchema>
|
InfiniteData<app.bsky.graph.getListsWithMembership.$OutputBody>
|
||||||
>(createListsWithMembershipQueryKey({actor}), old => {
|
>(createListsWithMembershipQueryKey({actor}), old => {
|
||||||
if (!old) return old
|
if (!old) return old
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import {type QueryClient, useQuery} from '@tanstack/react-query'
|
|||||||
|
|
||||||
import {accumulate} from '#/lib/async/accumulate'
|
import {accumulate} from '#/lib/async/accumulate'
|
||||||
import {STALE} from '#/state/queries'
|
import {STALE} from '#/state/queries'
|
||||||
import {useAgent, useSession} from '#/state/session'
|
import {useAppviewClient, useSession} from '#/state/session'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
export type MyListsFilter =
|
export type MyListsFilter =
|
||||||
| 'all'
|
| 'all'
|
||||||
@@ -16,7 +17,7 @@ export const RQKEY = (filter: MyListsFilter) => [RQKEY_ROOT, filter]
|
|||||||
|
|
||||||
export function useMyListsQuery(filter: MyListsFilter) {
|
export function useMyListsQuery(filter: MyListsFilter) {
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
return useQuery<AppBskyGraphDefs.ListView[]>({
|
return useQuery<AppBskyGraphDefs.ListView[]>({
|
||||||
staleTime: STALE.MINUTES.ONE,
|
staleTime: STALE.MINUTES.ONE,
|
||||||
queryKey: RQKEY(filter),
|
queryKey: RQKEY(filter),
|
||||||
@@ -24,42 +25,43 @@ export function useMyListsQuery(filter: MyListsFilter) {
|
|||||||
let lists: AppBskyGraphDefs.ListView[] = []
|
let lists: AppBskyGraphDefs.ListView[] = []
|
||||||
const promises = [
|
const promises = [
|
||||||
accumulate(cursor =>
|
accumulate(cursor =>
|
||||||
agent.app.bsky.graph
|
client
|
||||||
.getLists({
|
.call(app.bsky.graph.getLists, {
|
||||||
actor: currentAccount!.did,
|
actor: currentAccount!
|
||||||
|
.did as app.bsky.graph.getLists.$Params['actor'],
|
||||||
cursor,
|
cursor,
|
||||||
limit: 50,
|
limit: 50,
|
||||||
})
|
})
|
||||||
.then(res => ({
|
.then(data => ({
|
||||||
cursor: res.data.cursor,
|
cursor: data.cursor,
|
||||||
items: res.data.lists,
|
items: data.lists,
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
if (filter === 'all-including-subscribed' || filter === 'mod') {
|
if (filter === 'all-including-subscribed' || filter === 'mod') {
|
||||||
promises.push(
|
promises.push(
|
||||||
accumulate(cursor =>
|
accumulate(cursor =>
|
||||||
agent.app.bsky.graph
|
client
|
||||||
.getListMutes({
|
.call(app.bsky.graph.getListMutes, {
|
||||||
cursor,
|
cursor,
|
||||||
limit: 50,
|
limit: 50,
|
||||||
})
|
})
|
||||||
.then(res => ({
|
.then(data => ({
|
||||||
cursor: res.data.cursor,
|
cursor: data.cursor,
|
||||||
items: res.data.lists,
|
items: data.lists,
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
promises.push(
|
promises.push(
|
||||||
accumulate(cursor =>
|
accumulate(cursor =>
|
||||||
agent.app.bsky.graph
|
client
|
||||||
.getListBlocks({
|
.call(app.bsky.graph.getListBlocks, {
|
||||||
cursor,
|
cursor,
|
||||||
limit: 50,
|
limit: 50,
|
||||||
})
|
})
|
||||||
.then(res => ({
|
.then(data => ({
|
||||||
cursor: res.data.cursor,
|
cursor: data.cursor,
|
||||||
items: res.data.lists,
|
items: data.lists,
|
||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import {
|
import {moderateFeedGenerator} from '@atproto/api'
|
||||||
type AppBskyFeedGetActorFeeds,
|
|
||||||
moderateFeedGenerator,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {
|
import {
|
||||||
type InfiniteData,
|
type InfiniteData,
|
||||||
type QueryKey,
|
type QueryKey,
|
||||||
useInfiniteQuery,
|
useInfiniteQuery,
|
||||||
} from '@tanstack/react-query'
|
} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {useAgent} from '#/state/session'
|
import {useAppviewClient} from '#/state/session'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useModerationOpts} from '../preferences/moderation-opts'
|
import {useModerationOpts} from '../preferences/moderation-opts'
|
||||||
|
|
||||||
const PAGE_SIZE = 50
|
const PAGE_SIZE = 50
|
||||||
@@ -24,25 +22,25 @@ export function useProfileFeedgensQuery(
|
|||||||
) {
|
) {
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const enabled = opts?.enabled !== false && Boolean(moderationOpts)
|
const enabled = opts?.enabled !== false && Boolean(moderationOpts)
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
return useInfiniteQuery<
|
return useInfiniteQuery<
|
||||||
AppBskyFeedGetActorFeeds.OutputSchema,
|
app.bsky.feed.getActorFeeds.$OutputBody,
|
||||||
Error,
|
Error,
|
||||||
InfiniteData<AppBskyFeedGetActorFeeds.OutputSchema>,
|
InfiniteData<app.bsky.feed.getActorFeeds.$OutputBody>,
|
||||||
QueryKey,
|
QueryKey,
|
||||||
RQPageParam
|
RQPageParam
|
||||||
>({
|
>({
|
||||||
queryKey: RQKEY(did),
|
queryKey: RQKEY(did),
|
||||||
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
||||||
const res = await agent.app.bsky.feed.getActorFeeds({
|
const data = await client.call(app.bsky.feed.getActorFeeds, {
|
||||||
actor: did,
|
actor: did as app.bsky.feed.getActorFeeds.$Params['actor'],
|
||||||
limit: PAGE_SIZE,
|
limit: PAGE_SIZE,
|
||||||
cursor: pageParam,
|
cursor: pageParam,
|
||||||
})
|
})
|
||||||
res.data.feeds.sort((a, b) => {
|
data.feeds.sort((a, b) => {
|
||||||
return (b.likeCount || 0) - (a.likeCount || 0)
|
return (b.likeCount || 0) - (a.likeCount || 0)
|
||||||
})
|
})
|
||||||
return res.data
|
return data
|
||||||
},
|
},
|
||||||
initialPageParam: undefined,
|
initialPageParam: undefined,
|
||||||
getNextPageParam: lastPage => lastPage.cursor,
|
getNextPageParam: lastPage => lastPage.cursor,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import {type AppBskyGraphGetLists, moderateUserList} from '@atproto/api'
|
import {moderateUserList} from '@atproto/api'
|
||||||
import {
|
import {
|
||||||
type InfiniteData,
|
type InfiniteData,
|
||||||
type QueryKey,
|
type QueryKey,
|
||||||
useInfiniteQuery,
|
useInfiniteQuery,
|
||||||
} from '@tanstack/react-query'
|
} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {useAgent} from '#/state/session'
|
import {useAppviewClient} from '#/state/session'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useModerationOpts} from '../preferences/moderation-opts'
|
import {useModerationOpts} from '../preferences/moderation-opts'
|
||||||
|
|
||||||
const PAGE_SIZE = 30
|
const PAGE_SIZE = 30
|
||||||
@@ -17,23 +18,21 @@ export const RQKEY = (did: string) => [RQKEY_ROOT, did]
|
|||||||
export function useProfileListsQuery(did: string, opts?: {enabled?: boolean}) {
|
export function useProfileListsQuery(did: string, opts?: {enabled?: boolean}) {
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const enabled = opts?.enabled !== false && Boolean(moderationOpts)
|
const enabled = opts?.enabled !== false && Boolean(moderationOpts)
|
||||||
const agent = useAgent()
|
const client = useAppviewClient()
|
||||||
return useInfiniteQuery<
|
return useInfiniteQuery<
|
||||||
AppBskyGraphGetLists.OutputSchema,
|
app.bsky.graph.getLists.$OutputBody,
|
||||||
Error,
|
Error,
|
||||||
InfiniteData<AppBskyGraphGetLists.OutputSchema>,
|
InfiniteData<app.bsky.graph.getLists.$OutputBody>,
|
||||||
QueryKey,
|
QueryKey,
|
||||||
RQPageParam
|
RQPageParam
|
||||||
>({
|
>({
|
||||||
queryKey: RQKEY(did),
|
queryKey: RQKEY(did),
|
||||||
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
async queryFn({pageParam}: {pageParam: RQPageParam}) {
|
||||||
const res = await agent.app.bsky.graph.getLists({
|
return await client.call(app.bsky.graph.getLists, {
|
||||||
actor: did,
|
actor: did as app.bsky.graph.getLists.$Params['actor'],
|
||||||
limit: PAGE_SIZE,
|
limit: PAGE_SIZE,
|
||||||
cursor: pageParam,
|
cursor: pageParam,
|
||||||
})
|
})
|
||||||
|
|
||||||
return res.data
|
|
||||||
},
|
},
|
||||||
initialPageParam: undefined,
|
initialPageParam: undefined,
|
||||||
getNextPageParam: lastPage => lastPage.cursor,
|
getNextPageParam: lastPage => lastPage.cursor,
|
||||||
|
|||||||
Reference in New Issue
Block a user