1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useMutation, useQueryClient} from '@tanstack/react-query'
import {logger} from '#/logger'
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import * as Toast from '#/view/com/util/Toast'
import {updatePostShadow} from '../cache/post-shadow'
import {useAgent, useSession} from '../session'
import {useProfileUpdateMutation} from './profile'
export function usePinnedPostMutation() {
const {_} = useLingui()
const {currentAccount} = useSession()
const agent = useAgent()
const queryClient = useQueryClient()
const {mutateAsync: profileUpdateMutate} = useProfileUpdateMutation()
return useMutation({
mutationFn: async ({
postUri,
postCid,
action,
}: {
postUri: string
postCid: string
action: 'pin' | 'unpin'
}) => {
const pinCurrentPost = action === 'pin'
let prevPinnedPost: string | undefined
try {
updatePostShadow(queryClient, postUri, {pinned: pinCurrentPost})
// get the currently pinned post so we can optimistically remove the pin from it
if (!currentAccount) throw new Error('Not signed in')
const {data: profile} = await agent.getProfile({
actor: currentAccount.did,
})
prevPinnedPost = profile.pinnedPost?.uri
if (prevPinnedPost && prevPinnedPost !== postUri) {
updatePostShadow(queryClient, prevPinnedPost, {pinned: false})
}
await profileUpdateMutate({
profile,
updates: existing => {
existing.pinnedPost = pinCurrentPost
? {uri: postUri, cid: postCid}
: undefined
return existing
},
checkCommitted: res =>
pinCurrentPost
? res.data.pinnedPost?.uri === postUri
: !res.data.pinnedPost,
})
if (pinCurrentPost) {
Toast.show(_(msg({message: 'Post pinned', context: 'toast'})))
} else {
Toast.show(_(msg({message: 'Post unpinned', context: 'toast'})))
}
queryClient.invalidateQueries({
queryKey: FEED_RQKEY(
`author|${currentAccount.did}|posts_and_author_threads`,
),
})
queryClient.invalidateQueries({
queryKey: FEED_RQKEY(
`author|${currentAccount.did}|posts_with_replies`,
),
})
} catch (e: any) {
Toast.show(_(msg`Failed to pin post`))
logger.error('Failed to pin post', {message: String(e)})
// revert optimistic update
updatePostShadow(queryClient, postUri, {
pinned: !pinCurrentPost,
})
if (prevPinnedPost && prevPinnedPost !== postUri) {
updatePostShadow(queryClient, prevPinnedPost, {pinned: true})
}
}
},
})
}
|