Handle blocks in list and chat

This commit is contained in:
Eric Bailey
2024-05-14 15:35:35 -05:00
parent 4c68e8157c
commit f7d97297aa
4 changed files with 110 additions and 9 deletions
+42 -9
View File
@@ -12,6 +12,10 @@ import {
} from '#/state/queries/messages/conversation'
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
import {useMuteConvo} from '#/state/queries/messages/mute-conversation'
import {
useAwaitedProfileBlockMutation,
useAwaitedProfileUnblockMutation,
} from '#/state/queries/profile'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useTheme} from '#/alf'
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as ArrowBoxLeft} from '#/components/icons/ArrowBoxLeft'
@@ -34,10 +38,11 @@ let ConvoMenu = ({
showMarkAsRead,
hideTrigger,
triggerOpacity,
onUpdateConvo,
}: {
convo: ChatBskyConvoDefs.ConvoView
profile: AppBskyActorDefs.ProfileViewBasic
onUpdateConvo?: (convo: ChatBskyConvoDefs.ConvoView) => void
onUpdateConvo?: () => void
control?: Menu.MenuControlProps
currentScreen: 'list' | 'conversation'
showMarkAsRead?: boolean
@@ -64,12 +69,41 @@ let ConvoMenu = ({
} else {
Toast.show(_(msg`Chat unmuted`))
}
onUpdateConvo?.()
},
onError: () => {
Toast.show(_(msg`Could not mute chat`))
},
})
const {mutateAsync: blockProfile, isPending: isBlockPending} =
useAwaitedProfileBlockMutation()
const {mutateAsync: unblockProfile, isPending: isUnblockPending} =
useAwaitedProfileUnblockMutation()
const isBlockMutationPending = isBlockPending || isUnblockPending
const isBlocking = Boolean(profile.viewer?.blocking)
const toggleBlock = useCallback(async () => {
if (isBlockMutationPending) return
if (profile.viewer?.blocking) {
await unblockProfile({
subject: profile.did,
blockUri: profile.viewer?.blocking,
})
} else {
await blockProfile({subject: profile.did})
}
onUpdateConvo?.()
}, [
profile,
isBlockMutationPending,
blockProfile,
unblockProfile,
onUpdateConvo,
])
const {mutate: leaveConvo} = useLeaveConvo(convo?.id, {
onSuccess: () => {
if (currentScreen === 'conversation') {
@@ -146,18 +180,17 @@ let ConvoMenu = ({
</Menu.Item>
</Menu.Group>
<Menu.Divider />
{/* TODO(samuel): implement this */}
<Menu.Group>
<Menu.Item
label={_(msg`Block account`)}
onPress={() => {}}
disabled>
disabled={isBlockMutationPending}
label={
isBlocking ? _(msg`Unblock account`) : _(msg`Block account`)
}
onPress={toggleBlock}>
<Menu.ItemText>
<Trans>Block account</Trans>
{isBlocking ? _(msg`Unblock account`) : _(msg`Block account`)}
</Menu.ItemText>
<Menu.ItemIcon
icon={profile.viewer?.blocking ? PersonCheck : PersonX}
/>
<Menu.ItemIcon icon={isBlocking ? PersonX : PersonCheck} />
</Menu.Item>
<Menu.Item
label={_(msg`Report conversation`)}
@@ -98,6 +98,7 @@ function Inner() {
* Any other convo states (atm) are "ready" states
*/
console.log(convoState.blocks)
return (
<KeyboardProvider>
<KeyboardAvoidingView
@@ -242,6 +243,7 @@ let Header = ({
convo={convoState.convo}
profile={profile}
currentScreen="conversation"
onUpdateConvo={convoState.revalidateConvo}
/>
) : (
<View style={{width: 30}} />
@@ -4,9 +4,11 @@ import {ChatBskyConvoDefs} from '@atproto/api'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {NavigationProp} from '#/lib/routes/types'
import {isNative} from '#/platform/detection'
import {RQKEY as ListConvosQueryKey} from '#/state/queries/messages/list-converations'
import {useSession} from '#/state/session'
import {TimeElapsed} from '#/view/com/util/TimeElapsed'
import {UserAvatar} from '#/view/com/util/UserAvatar'
@@ -36,6 +38,7 @@ export function ChatListItem({
const displayName = isDeletedAccount
? 'Deleted Account'
: otherUser?.displayName || otherUser?.handle
const queryClient = useQueryClient()
let lastMessage = _(msg`No messages yet`)
let lastMessageSentAt: string | null = null
@@ -73,6 +76,10 @@ export function ChatListItem({
})
}, [convo.id, navigation])
const onUpdateConvo = React.useCallback(() => {
queryClient.invalidateQueries({queryKey: ListConvosQueryKey})
}, [queryClient])
if (!otherUser) {
return null
}
@@ -204,6 +211,7 @@ export function ChatListItem({
triggerOpacity={
!gtMobile || showActions || menuControl.isOpen ? 1 : 0
}
onUpdateConvo={onUpdateConvo}
/>
</View>
</View>
+58
View File
@@ -384,6 +384,9 @@ function useProfileUnmuteMutation() {
export function useProfileBlockMutationQueue(
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
options?: {
onSuccess?: () => void
},
) {
const queryClient = useQueryClient()
const did = profile.did
@@ -414,6 +417,7 @@ export function useProfileBlockMutationQueue(
updateProfileShadow(queryClient, did, {
blockingUri: finalBlockingUri,
})
options?.onSuccess?.()
},
})
@@ -478,6 +482,60 @@ function useProfileUnblockMutation() {
})
}
export function useAwaitedProfileBlockMutation() {
const {currentAccount} = useSession()
const {getAgent} = useAgent()
const queryClient = useQueryClient()
return useMutation({
mutationFn: async ({subject}: {subject: string}) => {
if (!currentAccount) {
throw new Error('Not signed in')
}
await getAgent().app.bsky.graph.block.create(
{repo: currentAccount.did},
{subject: subject, createdAt: new Date().toISOString()},
)
await whenAppViewReady(
getAgent,
subject,
res => !!res.data.viewer?.blocking,
)
},
onSuccess(_, {subject}) {
queryClient.invalidateQueries({queryKey: RQKEY_MY_BLOCKED()})
resetProfilePostsQueries(queryClient, subject, 1000)
},
})
}
export function useAwaitedProfileUnblockMutation() {
const {currentAccount} = useSession()
const {getAgent} = useAgent()
const queryClient = useQueryClient()
return useMutation<void, Error, {subject: string; blockUri: string}>({
mutationFn: async ({blockUri, subject}) => {
if (!currentAccount) {
throw new Error('Not signed in')
}
const {rkey} = new AtUri(blockUri)
await getAgent().app.bsky.graph.block.delete({
repo: currentAccount.did,
rkey,
})
await whenAppViewReady(
getAgent,
subject,
res => !res.data.viewer?.blocking,
)
},
onSuccess(_, {subject}) {
resetProfilePostsQueries(queryClient, subject, 1000)
},
})
}
export function precacheProfile(
queryClient: QueryClient,
profile: AppBskyActorDefs.ProfileViewBasic,