This commit is contained in:
Eric Bailey
2024-04-11 21:15:41 -05:00
parent 73fec7fb3c
commit d5e0653f62
16 changed files with 122 additions and 76 deletions
+14 -7
View File
@@ -2,22 +2,29 @@ import {AppBskyActorDefs} from '@atproto/api'
import {QueryClient, useQuery} from '@tanstack/react-query' import {QueryClient, useQuery} from '@tanstack/react-query'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const RQKEY_ROOT = 'actor-search' const RQKEY_ROOT = 'actor-search'
export const RQKEY = (prefix: string) => [RQKEY_ROOT, prefix] export const RQKEY = (query: string) => [RQKEY_ROOT, query]
export function useActorSearch(prefix: string) { export function useActorSearch({
query,
enabled,
}: {
query: string
enabled?: boolean
}) {
const agent = useAgent()
return useQuery<AppBskyActorDefs.ProfileView[]>({ return useQuery<AppBskyActorDefs.ProfileView[]>({
staleTime: STALE.MINUTES.ONE, staleTime: STALE.MINUTES.ONE,
queryKey: RQKEY(prefix || ''), queryKey: RQKEY(query || ''),
async queryFn() { async queryFn() {
const res = await getAgent().searchActors({ const res = await agent.searchActors({
q: prefix, q: query,
}) })
return res.data.actors return res.data.actors
}, },
enabled: !!prefix, enabled: enabled && !!query,
}) })
} }
+10 -6
View File
@@ -5,7 +5,7 @@ import {z} from 'zod'
import {labelersDetailedInfoQueryKeyRoot} from '#/lib/react-query' import {labelersDetailedInfoQueryKeyRoot} from '#/lib/react-query'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {preferencesQueryKey} from '#/state/queries/preferences' import {preferencesQueryKey} from '#/state/queries/preferences'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const labelerInfoQueryKeyRoot = 'labeler-info' const labelerInfoQueryKeyRoot = 'labeler-info'
export const labelerInfoQueryKey = (did: string) => [ export const labelerInfoQueryKey = (did: string) => [
@@ -31,11 +31,12 @@ export function useLabelerInfoQuery({
did?: string did?: string
enabled?: boolean enabled?: boolean
}) { }) {
const agent = useAgent()
return useQuery({ return useQuery({
enabled: !!did && enabled !== false, enabled: !!did && enabled !== false,
queryKey: labelerInfoQueryKey(did as string), queryKey: labelerInfoQueryKey(did as string),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().app.bsky.labeler.getServices({ const res = await agent.app.bsky.labeler.getServices({
dids: [did as string], dids: [did as string],
detailed: true, detailed: true,
}) })
@@ -45,24 +46,26 @@ export function useLabelerInfoQuery({
} }
export function useLabelersInfoQuery({dids}: {dids: string[]}) { export function useLabelersInfoQuery({dids}: {dids: string[]}) {
const agent = useAgent()
return useQuery({ return useQuery({
enabled: !!dids.length, enabled: !!dids.length,
queryKey: labelersInfoQueryKey(dids), queryKey: labelersInfoQueryKey(dids),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().app.bsky.labeler.getServices({dids}) const res = await agent.app.bsky.labeler.getServices({dids})
return res.data.views as AppBskyLabelerDefs.LabelerView[] return res.data.views as AppBskyLabelerDefs.LabelerView[]
}, },
}) })
} }
export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) { export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) {
const agent = useAgent()
return useQuery({ return useQuery({
enabled: !!dids.length, enabled: !!dids.length,
queryKey: labelersDetailedInfoQueryKey(dids), queryKey: labelersDetailedInfoQueryKey(dids),
gcTime: 1000 * 60 * 60 * 6, // 6 hours gcTime: 1000 * 60 * 60 * 6, // 6 hours
staleTime: STALE.MINUTES.ONE, staleTime: STALE.MINUTES.ONE,
queryFn: async () => { queryFn: async () => {
const res = await getAgent().app.bsky.labeler.getServices({ const res = await agent.app.bsky.labeler.getServices({
dids, dids,
detailed: true, detailed: true,
}) })
@@ -73,6 +76,7 @@ export function useLabelersDetailedInfoQuery({dids}: {dids: string[]}) {
export function useLabelerSubscriptionMutation() { export function useLabelerSubscriptionMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({ return useMutation({
async mutationFn({did, subscribe}: {did: string; subscribe: boolean}) { async mutationFn({did, subscribe}: {did: string; subscribe: boolean}) {
@@ -83,9 +87,9 @@ export function useLabelerSubscriptionMutation() {
}).parse({did, subscribe}) }).parse({did, subscribe})
if (subscribe) { if (subscribe) {
await getAgent().addLabeler(did) await agent.addLabeler(did)
} else { } else {
await getAgent().removeLabeler(did) await agent.removeLabeler(did)
} }
}, },
onSuccess() { onSuccess() {
+3 -2
View File
@@ -7,7 +7,7 @@ import {
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
type RQPageParam = string | undefined type RQPageParam = string | undefined
@@ -16,6 +16,7 @@ const RQKEY_ROOT = 'list-members'
export const RQKEY = (uri: string) => [RQKEY_ROOT, uri] export const RQKEY = (uri: string) => [RQKEY_ROOT, uri]
export function useListMembersQuery(uri: string) { export function useListMembersQuery(uri: string) {
const agent = useAgent()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetList.OutputSchema, AppBskyGraphGetList.OutputSchema,
Error, Error,
@@ -26,7 +27,7 @@ export function useListMembersQuery(uri: string) {
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 getAgent().app.bsky.graph.getList({ const res = await agent.app.bsky.graph.getList({
list: uri, list: uri,
limit: PAGE_SIZE, limit: PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
+3 -2
View File
@@ -6,13 +6,14 @@ import {
useInfiniteQuery, useInfiniteQuery,
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const RQKEY_ROOT = 'my-blocked-accounts' const RQKEY_ROOT = 'my-blocked-accounts'
export const RQKEY = () => [RQKEY_ROOT] export const RQKEY = () => [RQKEY_ROOT]
type RQPageParam = string | undefined type RQPageParam = string | undefined
export function useMyBlockedAccountsQuery() { export function useMyBlockedAccountsQuery() {
const agent = useAgent()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetBlocks.OutputSchema, AppBskyGraphGetBlocks.OutputSchema,
Error, Error,
@@ -22,7 +23,7 @@ export function useMyBlockedAccountsQuery() {
>({ >({
queryKey: RQKEY(), queryKey: RQKEY(),
async queryFn({pageParam}: {pageParam: RQPageParam}) { async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await getAgent().app.bsky.graph.getBlocks({ const res = await agent.app.bsky.graph.getBlocks({
limit: 30, limit: 30,
cursor: pageParam, cursor: pageParam,
}) })
+3 -2
View File
@@ -6,13 +6,14 @@ import {
useInfiniteQuery, useInfiniteQuery,
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const RQKEY_ROOT = 'my-muted-accounts' const RQKEY_ROOT = 'my-muted-accounts'
export const RQKEY = () => [RQKEY_ROOT] export const RQKEY = () => [RQKEY_ROOT]
type RQPageParam = string | undefined type RQPageParam = string | undefined
export function useMyMutedAccountsQuery() { export function useMyMutedAccountsQuery() {
const agent = useAgent()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetMutes.OutputSchema, AppBskyGraphGetMutes.OutputSchema,
Error, Error,
@@ -22,7 +23,7 @@ export function useMyMutedAccountsQuery() {
>({ >({
queryKey: RQKEY(), queryKey: RQKEY(),
async queryFn({pageParam}: {pageParam: RQPageParam}) { async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await getAgent().app.bsky.graph.getMutes({ const res = await agent.app.bsky.graph.getMutes({
limit: 30, limit: 30,
cursor: pageParam, cursor: pageParam,
}) })
+3 -2
View File
@@ -19,7 +19,7 @@ import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
import {logger} from '#/logger' import {logger} from '#/logger'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const' import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
import {AuthorFeedAPI} from 'lib/api/feed/author' import {AuthorFeedAPI} from 'lib/api/feed/author'
import {CustomFeedAPI} from 'lib/api/feed/custom' import {CustomFeedAPI} from 'lib/api/feed/custom'
import {FollowingFeedAPI} from 'lib/api/feed/following' import {FollowingFeedAPI} from 'lib/api/feed/following'
@@ -111,6 +111,7 @@ export function usePostFeedQuery(
result: InfiniteData<FeedPage> result: InfiniteData<FeedPage>
} | null>(null) } | null>(null)
const lastPageCountRef = useRef(0) const lastPageCountRef = useRef(0)
const agent = useAgent()
// Make sure this doesn't invalidate unless really needed. // Make sure this doesn't invalidate unless really needed.
const selectArgs = React.useMemo( const selectArgs = React.useMemo(
@@ -153,7 +154,7 @@ export function usePostFeedQuery(
* moderations happen later, which results in some posts being shown and * moderations happen later, which results in some posts being shown and
* some not. * some not.
*/ */
if (!getAgent().session) { if (!agent.session) {
assertSomePostsPassModeration(res.feed) assertSomePostsPassModeration(res.feed)
} }
+3 -2
View File
@@ -6,7 +6,7 @@ import {
useInfiniteQuery, useInfiniteQuery,
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
type RQPageParam = string | undefined type RQPageParam = string | undefined
@@ -16,6 +16,7 @@ const RQKEY_ROOT = 'liked-by'
export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri]
export function useLikedByQuery(resolvedUri: string | undefined) { export function useLikedByQuery(resolvedUri: string | undefined) {
const agent = useAgent()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyFeedGetLikes.OutputSchema, AppBskyFeedGetLikes.OutputSchema,
Error, Error,
@@ -25,7 +26,7 @@ export function useLikedByQuery(resolvedUri: string | undefined) {
>({ >({
queryKey: RQKEY(resolvedUri || ''), queryKey: RQKEY(resolvedUri || ''),
async queryFn({pageParam}: {pageParam: RQPageParam}) { async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await getAgent().getLikes({ const res = await agent.getLikes({
uri: resolvedUri || '', uri: resolvedUri || '',
limit: PAGE_SIZE, limit: PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
+3 -2
View File
@@ -6,7 +6,7 @@ import {
useInfiniteQuery, useInfiniteQuery,
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
type RQPageParam = string | undefined type RQPageParam = string | undefined
@@ -16,6 +16,7 @@ const RQKEY_ROOT = 'post-reposted-by'
export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri] export const RQKEY = (resolvedUri: string) => [RQKEY_ROOT, resolvedUri]
export function usePostRepostedByQuery(resolvedUri: string | undefined) { export function usePostRepostedByQuery(resolvedUri: string | undefined) {
const agent = useAgent()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyFeedGetRepostedBy.OutputSchema, AppBskyFeedGetRepostedBy.OutputSchema,
Error, Error,
@@ -25,7 +26,7 @@ export function usePostRepostedByQuery(resolvedUri: string | undefined) {
>({ >({
queryKey: RQKEY(resolvedUri || ''), queryKey: RQKEY(resolvedUri || ''),
async queryFn({pageParam}: {pageParam: RQPageParam}) { async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await getAgent().getRepostedBy({ const res = await agent.getRepostedBy({
uri: resolvedUri || '', uri: resolvedUri || '',
limit: PAGE_SIZE, limit: PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
+3 -2
View File
@@ -7,7 +7,7 @@ import {
import {QueryClient, useQuery, useQueryClient} from '@tanstack/react-query' import {QueryClient, useQuery, useQueryClient} from '@tanstack/react-query'
import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {UsePreferencesQueryResponse} from '#/state/queries/preferences/types'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
import {findAllPostsInQueryData as findAllPostsInNotifsQueryData} from './notifications/feed' import {findAllPostsInQueryData as findAllPostsInNotifsQueryData} from './notifications/feed'
import {findAllPostsInQueryData as findAllPostsInFeedQueryData} from './post-feed' import {findAllPostsInQueryData as findAllPostsInFeedQueryData} from './post-feed'
import {precacheThreadPostProfiles} from './profile' import {precacheThreadPostProfiles} from './profile'
@@ -65,11 +65,12 @@ export type ThreadNode =
export function usePostThreadQuery(uri: string | undefined) { export function usePostThreadQuery(uri: string | undefined) {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useQuery<ThreadNode, Error>({ return useQuery<ThreadNode, Error>({
gcTime: 0, gcTime: 0,
queryKey: RQKEY(uri || ''), queryKey: RQKEY(uri || ''),
async queryFn() { async queryFn() {
const res = await getAgent().getPostThread({uri: uri!}) const res = await agent.getPostThread({uri: uri!})
if (res.success) { if (res.success) {
const nodes = responseToThreadNodes(res.data.thread) const nodes = responseToThreadNodes(res.data.thread)
precacheThreadPostProfiles(queryClient, nodes) precacheThreadPostProfiles(queryClient, nodes)
+32 -18
View File
@@ -22,7 +22,7 @@ import {
ThreadViewPreferences, ThreadViewPreferences,
UsePreferencesQueryResponse, UsePreferencesQueryResponse,
} from '#/state/queries/preferences/types' } from '#/state/queries/preferences/types'
import {getAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
import {saveLabelers} from '#/state/session/agent-config' import {saveLabelers} from '#/state/session/agent-config'
export * from '#/state/queries/preferences/const' export * from '#/state/queries/preferences/const'
@@ -33,14 +33,13 @@ const preferencesQueryKeyRoot = 'getPreferences'
export const preferencesQueryKey = [preferencesQueryKeyRoot] export const preferencesQueryKey = [preferencesQueryKeyRoot]
export function usePreferencesQuery() { export function usePreferencesQuery() {
const agent = useAgent()
return useQuery({ return useQuery({
staleTime: STALE.SECONDS.FIFTEEN, staleTime: STALE.SECONDS.FIFTEEN,
structuralSharing: true, structuralSharing: true,
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
queryFn: async () => { queryFn: async () => {
const agent = getAgent()
if (agent.session?.did === undefined) { if (agent.session?.did === undefined) {
return DEFAULT_LOGGED_OUT_PREFERENCES return DEFAULT_LOGGED_OUT_PREFERENCES
} else { } else {
@@ -118,10 +117,11 @@ export function useModerationOpts() {
export function useClearPreferencesMutation() { export function useClearPreferencesMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({ return useMutation({
mutationFn: async () => { mutationFn: async () => {
await getAgent().app.bsky.actor.putPreferences({preferences: []}) await agent.app.bsky.actor.putPreferences({preferences: []})
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -132,6 +132,7 @@ export function useClearPreferencesMutation() {
export function usePreferencesSetContentLabelMutation() { export function usePreferencesSetContentLabelMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation< return useMutation<
void, void,
@@ -139,7 +140,7 @@ export function usePreferencesSetContentLabelMutation() {
{label: string; visibility: LabelPreference; labelerDid: string | undefined} {label: string; visibility: LabelPreference; labelerDid: string | undefined}
>({ >({
mutationFn: async ({label, visibility, labelerDid}) => { mutationFn: async ({label, visibility, labelerDid}) => {
await getAgent().setContentLabelPref(label, visibility, labelerDid) await agent.setContentLabelPref(label, visibility, labelerDid)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -150,6 +151,7 @@ export function usePreferencesSetContentLabelMutation() {
export function useSetContentLabelMutation() { export function useSetContentLabelMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({ return useMutation({
mutationFn: async ({ mutationFn: async ({
@@ -161,7 +163,7 @@ export function useSetContentLabelMutation() {
visibility: LabelPreference visibility: LabelPreference
labelerDid?: string labelerDid?: string
}) => { }) => {
await getAgent().setContentLabelPref(label, visibility, labelerDid) await agent.setContentLabelPref(label, visibility, labelerDid)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -172,10 +174,11 @@ export function useSetContentLabelMutation() {
export function usePreferencesSetAdultContentMutation() { export function usePreferencesSetAdultContentMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, {enabled: boolean}>({ return useMutation<void, unknown, {enabled: boolean}>({
mutationFn: async ({enabled}) => { mutationFn: async ({enabled}) => {
await getAgent().setAdultContentEnabled(enabled) await agent.setAdultContentEnabled(enabled)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -186,10 +189,11 @@ export function usePreferencesSetAdultContentMutation() {
export function usePreferencesSetBirthDateMutation() { export function usePreferencesSetBirthDateMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, {birthDate: Date}>({ return useMutation<void, unknown, {birthDate: Date}>({
mutationFn: async ({birthDate}: {birthDate: Date}) => { mutationFn: async ({birthDate}: {birthDate: Date}) => {
await getAgent().setPersonalDetails({birthDate: birthDate.toISOString()}) await agent.setPersonalDetails({birthDate: birthDate.toISOString()})
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -200,10 +204,11 @@ export function usePreferencesSetBirthDateMutation() {
export function useSetFeedViewPreferencesMutation() { export function useSetFeedViewPreferencesMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, Partial<BskyFeedViewPreference>>({ return useMutation<void, unknown, Partial<BskyFeedViewPreference>>({
mutationFn: async prefs => { mutationFn: async prefs => {
await getAgent().setFeedViewPrefs('home', prefs) await agent.setFeedViewPrefs('home', prefs)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -214,10 +219,11 @@ export function useSetFeedViewPreferencesMutation() {
export function useSetThreadViewPreferencesMutation() { export function useSetThreadViewPreferencesMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, Partial<ThreadViewPreferences>>({ return useMutation<void, unknown, Partial<ThreadViewPreferences>>({
mutationFn: async prefs => { mutationFn: async prefs => {
await getAgent().setThreadViewPrefs(prefs) await agent.setThreadViewPrefs(prefs)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -228,6 +234,7 @@ export function useSetThreadViewPreferencesMutation() {
export function useSetSaveFeedsMutation() { export function useSetSaveFeedsMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation< return useMutation<
void, void,
@@ -235,7 +242,7 @@ export function useSetSaveFeedsMutation() {
Pick<UsePreferencesQueryResponse['feeds'], 'saved' | 'pinned'> Pick<UsePreferencesQueryResponse['feeds'], 'saved' | 'pinned'>
>({ >({
mutationFn: async ({saved, pinned}) => { mutationFn: async ({saved, pinned}) => {
await getAgent().setSavedFeeds(saved, pinned) await agent.setSavedFeeds(saved, pinned)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -246,10 +253,11 @@ export function useSetSaveFeedsMutation() {
export function useSaveFeedMutation() { export function useSaveFeedMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, {uri: string}>({
mutationFn: async ({uri}) => { mutationFn: async ({uri}) => {
await getAgent().addSavedFeed(uri) await agent.addSavedFeed(uri)
track('CustomFeed:Save') track('CustomFeed:Save')
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
@@ -261,10 +269,11 @@ export function useSaveFeedMutation() {
export function useRemoveFeedMutation() { export function useRemoveFeedMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, {uri: string}>({
mutationFn: async ({uri}) => { mutationFn: async ({uri}) => {
await getAgent().removeSavedFeed(uri) await agent.removeSavedFeed(uri)
track('CustomFeed:Unsave') track('CustomFeed:Unsave')
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
@@ -276,10 +285,11 @@ export function useRemoveFeedMutation() {
export function usePinFeedMutation() { export function usePinFeedMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, {uri: string}>({
mutationFn: async ({uri}) => { mutationFn: async ({uri}) => {
await getAgent().addPinnedFeed(uri) await agent.addPinnedFeed(uri)
track('CustomFeed:Pin', {uri}) track('CustomFeed:Pin', {uri})
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
@@ -291,10 +301,11 @@ export function usePinFeedMutation() {
export function useUnpinFeedMutation() { export function useUnpinFeedMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, unknown, {uri: string}>({ return useMutation<void, unknown, {uri: string}>({
mutationFn: async ({uri}) => { mutationFn: async ({uri}) => {
await getAgent().removePinnedFeed(uri) await agent.removePinnedFeed(uri)
track('CustomFeed:Unpin', {uri}) track('CustomFeed:Unpin', {uri})
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
@@ -306,10 +317,11 @@ export function useUnpinFeedMutation() {
export function useUpsertMutedWordsMutation() { export function useUpsertMutedWordsMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({ return useMutation({
mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => { mutationFn: async (mutedWords: AppBskyActorDefs.MutedWord[]) => {
await getAgent().upsertMutedWords(mutedWords) await agent.upsertMutedWords(mutedWords)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -320,10 +332,11 @@ export function useUpsertMutedWordsMutation() {
export function useUpdateMutedWordMutation() { export function useUpdateMutedWordMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({ return useMutation({
mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => {
await getAgent().updateMutedWord(mutedWord) await agent.updateMutedWord(mutedWord)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
@@ -334,10 +347,11 @@ export function useUpdateMutedWordMutation() {
export function useRemoveMutedWordMutation() { export function useRemoveMutedWordMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation({ return useMutation({
mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => { mutationFn: async (mutedWord: AppBskyActorDefs.MutedWord) => {
await getAgent().removeMutedWord(mutedWord) await agent.removeMutedWord(mutedWord)
// triggers a refetch // triggers a refetch
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: preferencesQueryKey, queryKey: preferencesQueryKey,
+3 -2
View File
@@ -6,7 +6,7 @@ import {
useInfiniteQuery, useInfiniteQuery,
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
type RQPageParam = string | undefined type RQPageParam = string | undefined
@@ -15,6 +15,7 @@ const RQKEY_ROOT = 'profile-followers'
export const RQKEY = (did: string) => [RQKEY_ROOT, did] export const RQKEY = (did: string) => [RQKEY_ROOT, did]
export function useProfileFollowersQuery(did: string | undefined) { export function useProfileFollowersQuery(did: string | undefined) {
const agent = useAgent()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetFollowers.OutputSchema, AppBskyGraphGetFollowers.OutputSchema,
Error, Error,
@@ -24,7 +25,7 @@ export function useProfileFollowersQuery(did: string | undefined) {
>({ >({
queryKey: RQKEY(did || ''), queryKey: RQKEY(did || ''),
async queryFn({pageParam}: {pageParam: RQPageParam}) { async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await getAgent().app.bsky.graph.getFollowers({ const res = await agent.app.bsky.graph.getFollowers({
actor: did || '', actor: did || '',
limit: PAGE_SIZE, limit: PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
+3 -2
View File
@@ -7,7 +7,7 @@ import {
} from '@tanstack/react-query' } from '@tanstack/react-query'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {getAgent} from '#/state/session' import {useAgent} from '#/state/session'
const PAGE_SIZE = 30 const PAGE_SIZE = 30
type RQPageParam = string | undefined type RQPageParam = string | undefined
@@ -17,6 +17,7 @@ const RQKEY_ROOT = 'profile-follows'
export const RQKEY = (did: string) => [RQKEY_ROOT, did] export const RQKEY = (did: string) => [RQKEY_ROOT, did]
export function useProfileFollowsQuery(did: string | undefined) { export function useProfileFollowsQuery(did: string | undefined) {
const agent = useAgent()
return useInfiniteQuery< return useInfiniteQuery<
AppBskyGraphGetFollows.OutputSchema, AppBskyGraphGetFollows.OutputSchema,
Error, Error,
@@ -27,7 +28,7 @@ export function useProfileFollowsQuery(did: string | undefined) {
staleTime: STALE.MINUTES.ONE, staleTime: STALE.MINUTES.ONE,
queryKey: RQKEY(did || ''), queryKey: RQKEY(did || ''),
async queryFn({pageParam}: {pageParam: RQPageParam}) { async queryFn({pageParam}: {pageParam: RQPageParam}) {
const res = await getAgent().app.bsky.graph.getFollows({ const res = await agent.app.bsky.graph.getFollows({
actor: did || '', actor: did || '',
limit: PAGE_SIZE, limit: PAGE_SIZE,
cursor: pageParam, cursor: pageParam,
+22 -15
View File
@@ -25,7 +25,7 @@ import {Shadow} from '#/state/cache/types'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {resetProfilePostsQueries} from '#/state/queries/post-feed' import {resetProfilePostsQueries} from '#/state/queries/post-feed'
import {updateProfileShadow} from '../cache/profile-shadow' import {updateProfileShadow} from '../cache/profile-shadow'
import {getAgent, useSession} from '../session' import {getAgent, useAgent, useSession} from '../session'
import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts' import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts'
import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts' import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts'
import {ThreadNode} from './post-thread' import {ThreadNode} from './post-thread'
@@ -53,6 +53,7 @@ export function useProfileQuery({
staleTime?: number staleTime?: number
}) { }) {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useQuery<AppBskyActorDefs.ProfileViewDetailed>({ return useQuery<AppBskyActorDefs.ProfileViewDetailed>({
// WARNING // WARNING
// this staleTime is load-bearing // this staleTime is load-bearing
@@ -62,7 +63,7 @@ export function useProfileQuery({
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
queryKey: RQKEY(did ?? ''), queryKey: RQKEY(did ?? ''),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().getProfile({actor: did ?? ''}) const res = await agent.getProfile({actor: did ?? ''})
return res.data return res.data
}, },
placeholderData: () => { placeholderData: () => {
@@ -77,11 +78,12 @@ export function useProfileQuery({
} }
export function useProfilesQuery({handles}: {handles: string[]}) { export function useProfilesQuery({handles}: {handles: string[]}) {
const agent = useAgent()
return useQuery({ return useQuery({
staleTime: STALE.MINUTES.FIVE, staleTime: STALE.MINUTES.FIVE,
queryKey: profilesQueryKey(handles), queryKey: profilesQueryKey(handles),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().getProfiles({actors: handles}) const res = await agent.getProfiles({actors: handles})
return res.data return res.data
}, },
}) })
@@ -89,17 +91,18 @@ export function useProfilesQuery({handles}: {handles: string[]}) {
export function usePrefetchProfileQuery() { export function usePrefetchProfileQuery() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
const prefetchProfileQuery = useCallback( const prefetchProfileQuery = useCallback(
(did: string) => { (did: string) => {
queryClient.prefetchQuery({ queryClient.prefetchQuery({
queryKey: RQKEY(did), queryKey: RQKEY(did),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().getProfile({actor: did || ''}) const res = await agent.getProfile({actor: did || ''})
return res.data return res.data
}, },
}) })
}, },
[queryClient], [queryClient, agent],
) )
return prefetchProfileQuery return prefetchProfileQuery
} }
@@ -115,6 +118,7 @@ interface ProfileUpdateParams {
} }
export function useProfileUpdateMutation() { export function useProfileUpdateMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, Error, ProfileUpdateParams>({ return useMutation<void, Error, ProfileUpdateParams>({
mutationFn: async ({ mutationFn: async ({
profile, profile,
@@ -123,7 +127,7 @@ export function useProfileUpdateMutation() {
newUserBanner, newUserBanner,
checkCommitted, checkCommitted,
}) => { }) => {
await getAgent().upsertProfile(async existing => { await agent.upsertProfile(async existing => {
existing = existing || {} existing = existing || {}
if (typeof updates === 'function') { if (typeof updates === 'function') {
existing = updates(existing) existing = updates(existing)
@@ -254,7 +258,7 @@ function useProfileFollowMutation(
logContext: LogEvents['profile:follow']['logContext'], logContext: LogEvents['profile:follow']['logContext'],
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>, profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
) { ) {
const {currentAccount} = useSession() const {currentAccount, agent} = useSession()
const queryClient = useQueryClient() const queryClient = useQueryClient()
return useMutation<{uri: string; cid: string}, Error, {did: string}>({ return useMutation<{uri: string; cid: string}, Error, {did: string}>({
mutationFn: async ({did}) => { mutationFn: async ({did}) => {
@@ -270,7 +274,7 @@ function useProfileFollowMutation(
followeeClout: toClout(profile.followersCount), followeeClout: toClout(profile.followersCount),
followerClout: toClout(ownProfile?.followersCount), followerClout: toClout(ownProfile?.followersCount),
}) })
return await getAgent().follow(did) return await agent.follow(did)
}, },
onSuccess(data, variables) { onSuccess(data, variables) {
track('Profile:Follow', {username: variables.did}) track('Profile:Follow', {username: variables.did})
@@ -281,11 +285,12 @@ function useProfileFollowMutation(
function useProfileUnfollowMutation( function useProfileUnfollowMutation(
logContext: LogEvents['profile:unfollow']['logContext'], logContext: LogEvents['profile:unfollow']['logContext'],
) { ) {
const agent = useAgent()
return useMutation<void, Error, {did: string; followUri: string}>({ return useMutation<void, Error, {did: string; followUri: string}>({
mutationFn: async ({followUri}) => { mutationFn: async ({followUri}) => {
logEvent('profile:unfollow', {logContext}) logEvent('profile:unfollow', {logContext})
track('Profile:Unfollow', {username: followUri}) track('Profile:Unfollow', {username: followUri})
return await getAgent().deleteFollow(followUri) return await agent.deleteFollow(followUri)
}, },
}) })
} }
@@ -341,9 +346,10 @@ export function useProfileMuteMutationQueue(
function useProfileMuteMutation() { function useProfileMuteMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, Error, {did: string}>({ return useMutation<void, Error, {did: string}>({
mutationFn: async ({did}) => { mutationFn: async ({did}) => {
await getAgent().mute(did) await agent.mute(did)
}, },
onSuccess() { onSuccess() {
queryClient.invalidateQueries({queryKey: RQKEY_MY_MUTED()}) queryClient.invalidateQueries({queryKey: RQKEY_MY_MUTED()})
@@ -353,9 +359,10 @@ function useProfileMuteMutation() {
function useProfileUnmuteMutation() { function useProfileUnmuteMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return useMutation<void, Error, {did: string}>({ return useMutation<void, Error, {did: string}>({
mutationFn: async ({did}) => { mutationFn: async ({did}) => {
await getAgent().unmute(did) await agent.unmute(did)
}, },
onSuccess() { onSuccess() {
queryClient.invalidateQueries({queryKey: RQKEY_MY_MUTED()}) queryClient.invalidateQueries({queryKey: RQKEY_MY_MUTED()})
@@ -418,14 +425,14 @@ export function useProfileBlockMutationQueue(
} }
function useProfileBlockMutation() { function useProfileBlockMutation() {
const {currentAccount} = useSession() const {currentAccount, agent} = useSession()
const queryClient = useQueryClient() const queryClient = useQueryClient()
return useMutation<{uri: string; cid: string}, Error, {did: string}>({ return useMutation<{uri: string; cid: string}, Error, {did: string}>({
mutationFn: async ({did}) => { mutationFn: async ({did}) => {
if (!currentAccount) { if (!currentAccount) {
throw new Error('Not signed in') throw new Error('Not signed in')
} }
return await getAgent().app.bsky.graph.block.create( return await agent.app.bsky.graph.block.create(
{repo: currentAccount.did}, {repo: currentAccount.did},
{subject: did, createdAt: new Date().toISOString()}, {subject: did, createdAt: new Date().toISOString()},
) )
@@ -438,7 +445,7 @@ function useProfileBlockMutation() {
} }
function useProfileUnblockMutation() { function useProfileUnblockMutation() {
const {currentAccount} = useSession() const {currentAccount, agent} = useSession()
const queryClient = useQueryClient() const queryClient = useQueryClient()
return useMutation<void, Error, {did: string; blockUri: string}>({ return useMutation<void, Error, {did: string; blockUri: string}>({
mutationFn: async ({blockUri}) => { mutationFn: async ({blockUri}) => {
@@ -446,7 +453,7 @@ function useProfileUnblockMutation() {
throw new Error('Not signed in') throw new Error('Not signed in')
} }
const {rkey} = new AtUri(blockUri) const {rkey} = new AtUri(blockUri)
await getAgent().app.bsky.graph.block.delete({ await agent.app.bsky.graph.block.delete({
repo: currentAccount.did, repo: currentAccount.did,
rkey, rkey,
}) })
+10 -9
View File
@@ -16,7 +16,7 @@ import {
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {useModerationOpts} from '#/state/queries/preferences' import {useModerationOpts} from '#/state/queries/preferences'
import {getAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
const suggestedFollowsQueryKeyRoot = 'suggested-follows' const suggestedFollowsQueryKeyRoot = 'suggested-follows'
const suggestedFollowsQueryKey = [suggestedFollowsQueryKeyRoot] const suggestedFollowsQueryKey = [suggestedFollowsQueryKeyRoot]
@@ -28,7 +28,7 @@ const suggestedFollowsByActorQueryKey = (did: string) => [
] ]
export function useSuggestedFollowsQuery() { export function useSuggestedFollowsQuery() {
const {currentAccount} = useSession() const {agent, currentAccount} = useSession()
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
return useInfiniteQuery< return useInfiniteQuery<
@@ -42,7 +42,7 @@ export function useSuggestedFollowsQuery() {
staleTime: STALE.HOURS.ONE, staleTime: STALE.HOURS.ONE,
queryKey: suggestedFollowsQueryKey, queryKey: suggestedFollowsQueryKey,
queryFn: async ({pageParam}) => { queryFn: async ({pageParam}) => {
const res = await getAgent().app.bsky.actor.getSuggestions({ const res = await agent.app.bsky.actor.getSuggestions({
limit: 25, limit: 25,
cursor: pageParam, cursor: pageParam,
}) })
@@ -79,10 +79,11 @@ export function useSuggestedFollowsQuery() {
} }
export function useSuggestedFollowsByActorQuery({did}: {did: string}) { export function useSuggestedFollowsByActorQuery({did}: {did: string}) {
const agent = useAgent()
return useQuery<AppBskyGraphGetSuggestedFollowsByActor.OutputSchema, Error>({ return useQuery<AppBskyGraphGetSuggestedFollowsByActor.OutputSchema, Error>({
queryKey: suggestedFollowsByActorQueryKey(did), queryKey: suggestedFollowsByActorQueryKey(did),
queryFn: async () => { queryFn: async () => {
const res = await getAgent().app.bsky.graph.getSuggestedFollowsByActor({ const res = await agent.app.bsky.graph.getSuggestedFollowsByActor({
actor: did, actor: did,
}) })
return res.data return res.data
@@ -92,6 +93,7 @@ export function useSuggestedFollowsByActorQuery({did}: {did: string}) {
export function useGetSuggestedFollowersByActor() { export function useGetSuggestedFollowersByActor() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent()
return React.useCallback( return React.useCallback(
async (actor: string) => { async (actor: string) => {
@@ -99,17 +101,16 @@ export function useGetSuggestedFollowersByActor() {
staleTime: STALE.MINUTES.ONE, staleTime: STALE.MINUTES.ONE,
queryKey: suggestedFollowsByActorQueryKey(actor), queryKey: suggestedFollowsByActorQueryKey(actor),
queryFn: async () => { queryFn: async () => {
const res = const res = await agent.app.bsky.graph.getSuggestedFollowsByActor({
await getAgent().app.bsky.graph.getSuggestedFollowsByActor({ actor: actor,
actor: actor, })
})
return res.data return res.data
}, },
}) })
return res return res
}, },
[queryClient], [queryClient, agent],
) )
} }
+6 -2
View File
@@ -53,7 +53,7 @@ export function getAgent() {
} }
const StateContext = React.createContext<SessionStateContext>({ const StateContext = React.createContext<SessionStateContext>({
currentAgent: INITIAL_AGENT, agent: INITIAL_AGENT,
isInitialLoad: true, isInitialLoad: true,
isSwitchingAccounts: false, isSwitchingAccounts: false,
accounts: [], accounts: [],
@@ -477,7 +477,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
const stateContext = React.useMemo( const stateContext = React.useMemo(
() => ({ () => ({
currentAgent, agent: currentAgent,
isInitialLoad, isInitialLoad,
isSwitchingAccounts, isSwitchingAccounts,
currentAccount, currentAccount,
@@ -537,6 +537,10 @@ export function useSession() {
return React.useContext(StateContext) return React.useContext(StateContext)
} }
export function useAgent() {
return useSession().agent
}
export function useSessionApi() { export function useSessionApi() {
return React.useContext(ApiContext) return React.useContext(ApiContext)
} }
+1 -1
View File
@@ -17,7 +17,7 @@ export type CurrentAccount = Omit<SessionAccount, 'accessJwt' | 'refreshJwt'>
* Context shape returned from `useSession()` * Context shape returned from `useSession()`
*/ */
export type SessionStateContext = { export type SessionStateContext = {
currentAgent: BskyAgent agent: BskyAgent
isInitialLoad: boolean isInitialLoad: boolean
isSwitchingAccounts: boolean isSwitchingAccounts: boolean
hasSession: boolean hasSession: boolean