Refactor post threads to use react query (#1851)
* Add post and post-thread queries * Update PostThread components to use new queries * Move from normalized cache to shadow cache model * Merge post shadow into the post automatically * Remove dead code * Remove old temporary session * Fix: set agent on session creation * Temporarily double-login * Handle post-thread uri resolution errors
This commit is contained in:
parent
625cbc435f
commit
fb4f5709c4
12 changed files with 1386 additions and 476 deletions
156
src/state/queries/post.ts
Normal file
156
src/state/queries/post.ts
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
import {AppBskyFeedDefs} from '@atproto/api'
|
||||
import {useQuery, useMutation} from '@tanstack/react-query'
|
||||
import {useSession} from '../session'
|
||||
import {updatePostShadow} from '../cache/post-shadow'
|
||||
|
||||
export const RQKEY = (postUri: string) => ['post', postUri]
|
||||
|
||||
export function usePostQuery(uri: string | undefined) {
|
||||
const {agent} = useSession()
|
||||
return useQuery<AppBskyFeedDefs.PostView>(
|
||||
RQKEY(uri || ''),
|
||||
async () => {
|
||||
const res = await agent.getPosts({uris: [uri!]})
|
||||
if (res.success && res.data.posts[0]) {
|
||||
return res.data.posts[0]
|
||||
}
|
||||
|
||||
throw new Error('No data')
|
||||
},
|
||||
{
|
||||
enabled: !!uri,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export function usePostLikeMutation() {
|
||||
const {agent} = useSession()
|
||||
return useMutation<
|
||||
{uri: string}, // responds with the uri of the like
|
||||
Error,
|
||||
{uri: string; cid: string; likeCount: number} // the post's uri, cid, and likes
|
||||
>(post => agent.like(post.uri, post.cid), {
|
||||
onMutate(variables) {
|
||||
// optimistically update the post-shadow
|
||||
updatePostShadow(variables.uri, {
|
||||
likeCount: variables.likeCount + 1,
|
||||
likeUri: 'pending',
|
||||
})
|
||||
},
|
||||
onSuccess(data, variables) {
|
||||
// finalize the post-shadow with the like URI
|
||||
updatePostShadow(variables.uri, {
|
||||
likeUri: data.uri,
|
||||
})
|
||||
},
|
||||
onError(error, variables) {
|
||||
// revert the optimistic update
|
||||
updatePostShadow(variables.uri, {
|
||||
likeCount: variables.likeCount,
|
||||
likeUri: undefined,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function usePostUnlikeMutation() {
|
||||
const {agent} = useSession()
|
||||
return useMutation<
|
||||
void,
|
||||
Error,
|
||||
{postUri: string; likeUri: string; likeCount: number}
|
||||
>(
|
||||
async ({likeUri}) => {
|
||||
await agent.deleteLike(likeUri)
|
||||
},
|
||||
{
|
||||
onMutate(variables) {
|
||||
// optimistically update the post-shadow
|
||||
updatePostShadow(variables.postUri, {
|
||||
likeCount: variables.likeCount - 1,
|
||||
likeUri: undefined,
|
||||
})
|
||||
},
|
||||
onError(error, variables) {
|
||||
// revert the optimistic update
|
||||
updatePostShadow(variables.postUri, {
|
||||
likeCount: variables.likeCount,
|
||||
likeUri: variables.likeUri,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export function usePostRepostMutation() {
|
||||
const {agent} = useSession()
|
||||
return useMutation<
|
||||
{uri: string}, // responds with the uri of the repost
|
||||
Error,
|
||||
{uri: string; cid: string; repostCount: number} // the post's uri, cid, and reposts
|
||||
>(post => agent.repost(post.uri, post.cid), {
|
||||
onMutate(variables) {
|
||||
// optimistically update the post-shadow
|
||||
updatePostShadow(variables.uri, {
|
||||
repostCount: variables.repostCount + 1,
|
||||
repostUri: 'pending',
|
||||
})
|
||||
},
|
||||
onSuccess(data, variables) {
|
||||
// finalize the post-shadow with the repost URI
|
||||
updatePostShadow(variables.uri, {
|
||||
repostUri: data.uri,
|
||||
})
|
||||
},
|
||||
onError(error, variables) {
|
||||
// revert the optimistic update
|
||||
updatePostShadow(variables.uri, {
|
||||
repostCount: variables.repostCount,
|
||||
repostUri: undefined,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function usePostUnrepostMutation() {
|
||||
const {agent} = useSession()
|
||||
return useMutation<
|
||||
void,
|
||||
Error,
|
||||
{postUri: string; repostUri: string; repostCount: number}
|
||||
>(
|
||||
async ({repostUri}) => {
|
||||
await agent.deleteRepost(repostUri)
|
||||
},
|
||||
{
|
||||
onMutate(variables) {
|
||||
// optimistically update the post-shadow
|
||||
updatePostShadow(variables.postUri, {
|
||||
repostCount: variables.repostCount - 1,
|
||||
repostUri: undefined,
|
||||
})
|
||||
},
|
||||
onError(error, variables) {
|
||||
// revert the optimistic update
|
||||
updatePostShadow(variables.postUri, {
|
||||
repostCount: variables.repostCount,
|
||||
repostUri: variables.repostUri,
|
||||
})
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export function usePostDeleteMutation() {
|
||||
const {agent} = useSession()
|
||||
return useMutation<void, Error, {uri: string}>(
|
||||
async ({uri}) => {
|
||||
await agent.deletePost(uri)
|
||||
},
|
||||
{
|
||||
onSuccess(data, variables) {
|
||||
updatePostShadow(variables.uri, {isDeleted: true})
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue