a7db0bac6f
* add context for toast * add
88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
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})
|
|
}
|
|
}
|
|
},
|
|
})
|
|
}
|