diff options
Diffstat (limited to 'src/state/queries')
-rw-r--r-- | src/state/queries/profile.ts | 166 | ||||
-rw-r--r-- | src/state/queries/resolve-uri.ts | 15 |
2 files changed, 171 insertions, 10 deletions
diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts index c2cd19482..1bd28d5b1 100644 --- a/src/state/queries/profile.ts +++ b/src/state/queries/profile.ts @@ -1,13 +1,169 @@ -import {useQuery} from '@tanstack/react-query' +import {AtUri} from '@atproto/api' +import {useQuery, useMutation} from '@tanstack/react-query' +import {useSession} from '../session' +import {updateProfileShadow} from '../cache/profile-shadow' -import {PUBLIC_BSKY_AGENT} from '#/state/queries' +export const RQKEY = (did: string) => ['profile', did] -export function useProfileQuery({did}: {did: string}) { +export function useProfileQuery({did}: {did: string | undefined}) { + const {agent} = useSession() return useQuery({ - queryKey: ['getProfile', did], + queryKey: RQKEY(did), queryFn: async () => { - const res = await PUBLIC_BSKY_AGENT.getProfile({actor: did}) + const res = await agent.getProfile({actor: did || ''}) return res.data }, + enabled: !!did, + }) +} + +export function useProfileFollowMutation() { + const {agent} = useSession() + return useMutation<{uri: string; cid: string}, Error, {did: string}>({ + mutationFn: async ({did}) => { + return await agent.follow(did) + }, + onMutate(variables) { + // optimstically update + updateProfileShadow(variables.did, { + followingUri: 'pending', + }) + }, + onSuccess(data, variables) { + // finalize + updateProfileShadow(variables.did, { + followingUri: data.uri, + }) + }, + onError(error, variables) { + // revert the optimistic update + updateProfileShadow(variables.did, { + followingUri: undefined, + }) + }, + }) +} + +export function useProfileUnfollowMutation() { + const {agent} = useSession() + return useMutation<void, Error, {did: string; followUri: string}>({ + mutationFn: async ({followUri}) => { + return await agent.deleteFollow(followUri) + }, + onMutate(variables) { + // optimstically update + updateProfileShadow(variables.did, { + followingUri: undefined, + }) + }, + onError(error, variables) { + // revert the optimistic update + updateProfileShadow(variables.did, { + followingUri: variables.followUri, + }) + }, + }) +} + +export function useProfileMuteMutation() { + const {agent} = useSession() + return useMutation<void, Error, {did: string}>({ + mutationFn: async ({did}) => { + await agent.mute(did) + }, + onMutate(variables) { + // optimstically update + updateProfileShadow(variables.did, { + muted: true, + }) + }, + onError(error, variables) { + // revert the optimistic update + updateProfileShadow(variables.did, { + muted: false, + }) + }, + }) +} + +export function useProfileUnmuteMutation() { + const {agent} = useSession() + return useMutation<void, Error, {did: string}>({ + mutationFn: async ({did}) => { + await agent.unmute(did) + }, + onMutate(variables) { + // optimstically update + updateProfileShadow(variables.did, { + muted: false, + }) + }, + onError(error, variables) { + // revert the optimistic update + updateProfileShadow(variables.did, { + muted: true, + }) + }, + }) +} + +export function useProfileBlockMutation() { + const {agent, currentAccount} = useSession() + return useMutation<{uri: string; cid: string}, Error, {did: string}>({ + mutationFn: async ({did}) => { + if (!currentAccount) { + throw new Error('Not signed in') + } + return await agent.app.bsky.graph.block.create( + {repo: currentAccount.did}, + {subject: did, createdAt: new Date().toISOString()}, + ) + }, + onMutate(variables) { + // optimstically update + updateProfileShadow(variables.did, { + blockingUri: 'pending', + }) + }, + onSuccess(data, variables) { + // finalize + updateProfileShadow(variables.did, { + blockingUri: data.uri, + }) + }, + onError(error, variables) { + // revert the optimistic update + updateProfileShadow(variables.did, { + blockingUri: undefined, + }) + }, + }) +} + +export function useProfileUnblockMutation() { + const {agent, currentAccount} = useSession() + return useMutation<void, Error, {did: string; blockUri: string}>({ + mutationFn: async ({blockUri}) => { + if (!currentAccount) { + throw new Error('Not signed in') + } + const {rkey} = new AtUri(blockUri) + await agent.app.bsky.graph.block.delete({ + repo: currentAccount.did, + rkey, + }) + }, + onMutate(variables) { + // optimstically update + updateProfileShadow(variables.did, { + blockingUri: undefined, + }) + }, + onError(error, variables) { + // revert the optimistic update + updateProfileShadow(variables.did, { + blockingUri: variables.blockUri, + }) + }, }) } diff --git a/src/state/queries/resolve-uri.ts b/src/state/queries/resolve-uri.ts index 26e0a475b..83bccdce7 100644 --- a/src/state/queries/resolve-uri.ts +++ b/src/state/queries/resolve-uri.ts @@ -4,17 +4,22 @@ import {useSession} from '../session' export const RQKEY = (uri: string) => ['resolved-uri', uri] -export function useResolveUriQuery(uri: string) { +export function useResolveUriQuery(uri: string | undefined) { const {agent} = useSession() - return useQuery<string | undefined, Error>({ - queryKey: RQKEY(uri), + return useQuery<{uri: string; did: string}, Error>({ + queryKey: RQKEY(uri || ''), async queryFn() { - const urip = new AtUri(uri) + const urip = new AtUri(uri || '') if (!urip.host.startsWith('did:')) { const res = await agent.resolveHandle({handle: urip.host}) urip.host = res.data.did } - return urip.toString() + return {did: urip.host, uri: urip.toString()} }, + enabled: !!uri, }) } + +export function useResolveDidQuery(didOrHandle: string | undefined) { + return useResolveUriQuery(didOrHandle ? `at://${didOrHandle}/` : undefined) +} |