[SDK] Migrate group chat and join links to the chat client (#11358)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import {useCallback} from 'react'
|
||||
import {ChatBskyGroupCreateGroup} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
||||
@@ -88,29 +87,27 @@ export function NewChat({
|
||||
let errorMessage = l`An issue occurred starting the group chat, please try again.`
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`A network error occurred. Please check your internet connection.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.AccountSuspendedError
|
||||
) {
|
||||
errorMessage = l`Suspended accounts cannot participate in a group chat.`
|
||||
} else if (error instanceof ChatBskyGroupCreateGroup.BlockedActorError) {
|
||||
errorMessage = l`One of the selected recipients has blocked you and cannot be messaged.`
|
||||
} else if (
|
||||
error instanceof
|
||||
ChatBskyGroupCreateGroup.NewAccountCannotCreateGroupError
|
||||
) {
|
||||
errorMessage = l`You cannot create a group chat yet.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.NotFollowedBySenderError
|
||||
) {
|
||||
errorMessage = l`A selected recipient is not followed by the sender.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.RecipientNotFoundError
|
||||
) {
|
||||
errorMessage = l`Unable to find a selected recipient.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.UserForbidsGroupsError
|
||||
) {
|
||||
errorMessage = l`One of the selected recipients does not allow group chats.`
|
||||
} else {
|
||||
switch (matchXrpcError(error, chat.bsky.group.createGroup)) {
|
||||
case 'AccountSuspended':
|
||||
errorMessage = l`Suspended accounts cannot participate in a group chat.`
|
||||
break
|
||||
case 'BlockedActor':
|
||||
errorMessage = l`One of the selected recipients has blocked you and cannot be messaged.`
|
||||
break
|
||||
case 'NewAccountCannotCreateGroup':
|
||||
errorMessage = l`You cannot create a group chat yet.`
|
||||
break
|
||||
case 'NotFollowedBySender':
|
||||
errorMessage = l`A selected recipient is not followed by the sender.`
|
||||
break
|
||||
case 'RecipientNotFound':
|
||||
errorMessage = l`Unable to find a selected recipient.`
|
||||
break
|
||||
case 'UserForbidsGroups':
|
||||
errorMessage = l`One of the selected recipients does not allow group chats.`
|
||||
break
|
||||
}
|
||||
}
|
||||
Toast.show(errorMessage, {
|
||||
type: 'error',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useCallback, useState} from 'react'
|
||||
import {ChatBskyGroupCreateGroup} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
@@ -104,29 +103,27 @@ function SendViaChatDialogInner({
|
||||
let errorMessage = l`An issue occurred starting the group chat, please try again.`
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`A network error occurred. Please check your internet connection.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.AccountSuspendedError
|
||||
) {
|
||||
errorMessage = l`Suspended accounts cannot participate in a group chat.`
|
||||
} else if (error instanceof ChatBskyGroupCreateGroup.BlockedActorError) {
|
||||
errorMessage = l`One of the selected recipients has blocked you and cannot be messaged.`
|
||||
} else if (
|
||||
error instanceof
|
||||
ChatBskyGroupCreateGroup.NewAccountCannotCreateGroupError
|
||||
) {
|
||||
errorMessage = l`You cannot create a group chat yet.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.NotFollowedBySenderError
|
||||
) {
|
||||
errorMessage = l`A selected recipient is not followed by the sender.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.RecipientNotFoundError
|
||||
) {
|
||||
errorMessage = l`Unable to find a selected recipient.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupCreateGroup.UserForbidsGroupsError
|
||||
) {
|
||||
errorMessage = l`One of the selected recipients does not allow group chats.`
|
||||
} else {
|
||||
switch (matchXrpcError(error, chat.bsky.group.createGroup)) {
|
||||
case 'AccountSuspended':
|
||||
errorMessage = l`Suspended accounts cannot participate in a group chat.`
|
||||
break
|
||||
case 'BlockedActor':
|
||||
errorMessage = l`One of the selected recipients has blocked you and cannot be messaged.`
|
||||
break
|
||||
case 'NewAccountCannotCreateGroup':
|
||||
errorMessage = l`You cannot create a group chat yet.`
|
||||
break
|
||||
case 'NotFollowedBySender':
|
||||
errorMessage = l`A selected recipient is not followed by the sender.`
|
||||
break
|
||||
case 'RecipientNotFound':
|
||||
errorMessage = l`Unable to find a selected recipient.`
|
||||
break
|
||||
case 'UserForbidsGroups':
|
||||
errorMessage = l`One of the selected recipients does not allow group chats.`
|
||||
break
|
||||
}
|
||||
}
|
||||
Toast.show(errorMessage, {
|
||||
type: 'error',
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import {useEffect} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
ChatBskyGroupDefs,
|
||||
ChatBskyGroupRequestJoin,
|
||||
ChatBskyGroupWithdrawJoinRequest,
|
||||
moderateProfile,
|
||||
} from '@atproto/api'
|
||||
import {ChatBskyGroupDefs, moderateProfile} from '@atproto/api'
|
||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
@@ -16,6 +11,7 @@ import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {matchXrpcError} from '#/lib/xrpc-error'
|
||||
import {logger} from '#/logger'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {
|
||||
@@ -49,6 +45,7 @@ import {Loader} from '#/components/Loader'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {chat} from '#/lexicons'
|
||||
import {ProfileBadges} from '../ProfileBadges'
|
||||
|
||||
export function GroupChatJoinDialog() {
|
||||
@@ -147,33 +144,37 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
||||
let errorMessage = l`Failed to join the group chat. Please try again.`
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`There was a problem with your internet connection, please try again`
|
||||
} else if (error instanceof ChatBskyGroupRequestJoin.ConvoLockedError) {
|
||||
errorMessage = l`This conversation is locked.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupRequestJoin.FollowRequiredError
|
||||
) {
|
||||
errorMessage = l`Only followers can join this group chat.`
|
||||
} else if (error instanceof ChatBskyGroupRequestJoin.InvalidCodeError) {
|
||||
errorMessage = l`Invalid group chat code.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupRequestJoin.LinkDisabledError
|
||||
) {
|
||||
errorMessage = l`This invite link has been disabled.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupRequestJoin.MemberLimitReachedError
|
||||
) {
|
||||
errorMessage = l`The member limit has been reached.`
|
||||
const preview = data?.joinLinkPreviews[0]
|
||||
if (
|
||||
ChatBskyGroupDefs.isJoinLinkPreviewView(preview) &&
|
||||
preview.convo?.id
|
||||
) {
|
||||
ax.metric('groupchat:join:memberLimitReached', {
|
||||
convoId: preview.convo.id,
|
||||
})
|
||||
} else {
|
||||
switch (matchXrpcError(error, chat.bsky.group.requestJoin)) {
|
||||
case 'ConvoLocked':
|
||||
errorMessage = l`This conversation is locked.`
|
||||
break
|
||||
case 'FollowRequired':
|
||||
errorMessage = l`Only followers can join this group chat.`
|
||||
break
|
||||
case 'InvalidCode':
|
||||
errorMessage = l`Invalid group chat code.`
|
||||
break
|
||||
case 'LinkDisabled':
|
||||
errorMessage = l`This invite link has been disabled.`
|
||||
break
|
||||
case 'MemberLimitReached': {
|
||||
errorMessage = l`The member limit has been reached.`
|
||||
const preview = data?.joinLinkPreviews[0]
|
||||
if (
|
||||
ChatBskyGroupDefs.isJoinLinkPreviewView(preview) &&
|
||||
preview.convo?.id
|
||||
) {
|
||||
ax.metric('groupchat:join:memberLimitReached', {
|
||||
convoId: preview.convo.id,
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'UserKicked':
|
||||
errorMessage = l`You have been previously removed from this group and can’t join it using this link.`
|
||||
break
|
||||
}
|
||||
} else if (error instanceof ChatBskyGroupRequestJoin.UserKickedError) {
|
||||
errorMessage = l`You have been previously removed from this group and can’t join it using this link.`
|
||||
}
|
||||
Toast.show(errorMessage)
|
||||
},
|
||||
@@ -194,8 +195,8 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`There was a problem with your internet connection, please try again`
|
||||
} else if (
|
||||
error instanceof
|
||||
ChatBskyGroupWithdrawJoinRequest.InvalidJoinRequestError
|
||||
matchXrpcError(error, chat.bsky.group.withdrawJoinRequest) ===
|
||||
'InvalidJoinRequest'
|
||||
) {
|
||||
errorMessage = l`Invalid rescind request.`
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs, ChatBskyGroupRemoveMembers} from '@atproto/api'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
@@ -309,14 +309,15 @@ function MutualGroupChat({
|
||||
let errorMessage = l`Could not remove member.`
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`A network error occurred. Please check your internet connection.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupRemoveMembers.InvalidConvoError
|
||||
) {
|
||||
errorMessage = l`Chat not found.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupRemoveMembers.InsufficientRoleError
|
||||
) {
|
||||
errorMessage = l`You must be a chat owner to remove a member.`
|
||||
} else {
|
||||
switch (matchXrpcError(error, chat.bsky.group.removeMembers)) {
|
||||
case 'InvalidConvo':
|
||||
errorMessage = l`Chat not found.`
|
||||
break
|
||||
case 'InsufficientRole':
|
||||
errorMessage = l`You must be a chat owner to remove a member.`
|
||||
break
|
||||
}
|
||||
}
|
||||
Toast.show(errorMessage, {type: 'error'})
|
||||
},
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
ChatBskyGroupApproveJoinRequest,
|
||||
type ChatBskyGroupListJoinRequests,
|
||||
ChatBskyGroupRejectJoinRequest,
|
||||
} from '@atproto/api'
|
||||
import {type ChatBskyGroupListJoinRequests} from '@atproto/api'
|
||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
import {type InfiniteData, useQueryClient} from '@tanstack/react-query'
|
||||
@@ -16,6 +12,7 @@ import {
|
||||
type NativeStackScreenProps,
|
||||
type NavigationProp,
|
||||
} from '#/lib/routes/types'
|
||||
import {matchXrpcError} from '#/lib/xrpc-error'
|
||||
import {logger} from '#/logger'
|
||||
import {ConvoProvider, useConvo} from '#/state/messages/convo'
|
||||
import {ConvoStatus} from '#/state/messages/convo/types'
|
||||
@@ -43,6 +40,7 @@ import * as ProfileCard from '#/components/ProfileCard'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {chat} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {InviteLinkDialog} from './components/InviteLinkDialog'
|
||||
|
||||
@@ -190,19 +188,18 @@ function JoinRequestsList({
|
||||
let errorMessage = l`Failed to accept join request`
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`A network error occurred. Please check your internet connection.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupApproveJoinRequest.InvalidConvoError
|
||||
) {
|
||||
errorMessage = l`Conversation not found.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupApproveJoinRequest.InsufficientRoleError
|
||||
) {
|
||||
errorMessage = l`Only admins can accept join requests.`
|
||||
} else if (
|
||||
error instanceof
|
||||
ChatBskyGroupApproveJoinRequest.MemberLimitReachedError
|
||||
) {
|
||||
errorMessage = l`The member limit has been reached.`
|
||||
} else {
|
||||
switch (matchXrpcError(error, chat.bsky.group.approveJoinRequest)) {
|
||||
case 'InvalidConvo':
|
||||
errorMessage = l`Conversation not found.`
|
||||
break
|
||||
case 'InsufficientRole':
|
||||
errorMessage = l`Only admins can accept join requests.`
|
||||
break
|
||||
case 'MemberLimitReached':
|
||||
errorMessage = l`The member limit has been reached.`
|
||||
break
|
||||
}
|
||||
}
|
||||
Toast.show(errorMessage, {type: 'error'})
|
||||
},
|
||||
@@ -223,14 +220,15 @@ function JoinRequestsList({
|
||||
let errorMessage = l`Failed to reject join request`
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`A network error occurred. Please check your internet connection.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupRejectJoinRequest.InvalidConvoError
|
||||
) {
|
||||
errorMessage = l`Conversation not found.`
|
||||
} else if (
|
||||
error instanceof ChatBskyGroupRejectJoinRequest.InsufficientRoleError
|
||||
) {
|
||||
errorMessage = l`Only admins can reject join requests.`
|
||||
} else {
|
||||
switch (matchXrpcError(error, chat.bsky.group.rejectJoinRequest)) {
|
||||
case 'InvalidConvo':
|
||||
errorMessage = l`Conversation not found.`
|
||||
break
|
||||
case 'InsufficientRole':
|
||||
errorMessage = l`Only admins can reject join requests.`
|
||||
break
|
||||
}
|
||||
}
|
||||
Toast.show(errorMessage, {type: 'error'})
|
||||
},
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import {View} from 'react-native'
|
||||
import {
|
||||
type ChatBskyGroupDefs,
|
||||
ChatBskyGroupWithdrawJoinRequest,
|
||||
} from '@atproto/api'
|
||||
import {type ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {matchXrpcError} from '#/lib/xrpc-error'
|
||||
import {useWithdrawJoinGroupChatRequest} from '#/state/queries/messages/withdraw-join-group-chat'
|
||||
import {TimeElapsed} from '#/view/com/util/TimeElapsed'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
@@ -14,6 +12,7 @@ import {createStaticClick, Link} from '#/components/Link'
|
||||
import * as Prompt from '#/components/Prompt'
|
||||
import * as Toast from '#/components/Toast'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {chat} from '#/lexicons'
|
||||
|
||||
export function OutgoingRequestListItem({
|
||||
convo: convoView,
|
||||
@@ -35,8 +34,8 @@ export function OutgoingRequestListItem({
|
||||
if (isNetworkError(error)) {
|
||||
errorMessage = l`There was a problem with your internet connection, please try again`
|
||||
} else if (
|
||||
error instanceof
|
||||
ChatBskyGroupWithdrawJoinRequest.InvalidJoinRequestError
|
||||
matchXrpcError(error, chat.bsky.group.withdrawJoinRequest) ===
|
||||
'InvalidJoinRequest'
|
||||
) {
|
||||
errorMessage = l`Invalid rescind request.`
|
||||
}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import {useCallback} from 'react'
|
||||
import {
|
||||
type $Typed,
|
||||
AtpAgent,
|
||||
ChatBskyGroupDefs,
|
||||
type ChatBskyGroupGetJoinLinkPreviews,
|
||||
} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type QueryClient, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {CHAT_SERVICE, DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {CHAT_SERVICE} from '#/lib/constants'
|
||||
import {createLexClient} from '#/lib/lexClient'
|
||||
import {logger} from '#/logger'
|
||||
import {STALE} from '#/state/queries/index'
|
||||
import {createQueryKey, type StructuredQueryKey} from '#/state/queries/util'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
|
||||
/**
|
||||
* The three preview shapes we currently support. Excludes the `{$type: string}`
|
||||
@@ -154,23 +156,39 @@ export function invalidateJoinLinkPreviewsForConvo(
|
||||
})
|
||||
}
|
||||
|
||||
let publicChatClient: Client | undefined
|
||||
|
||||
/**
|
||||
* The unauthenticated {@link Client} for the chat service, used to resolve join
|
||||
* links before the viewer has a session.
|
||||
*
|
||||
* It talks to {@link CHAT_SERVICE} directly rather than proxying through a PDS,
|
||||
* so no `atproto-proxy` header is involved. A single module-level instance,
|
||||
* because there is no session to scope it to and reconstructing it per call
|
||||
* would be waste.
|
||||
*
|
||||
* Unlike the public appview client this does NOT wrap `networkAwareFetch`,
|
||||
* matching the plain-fetch behavior of the ad-hoc agent it replaces: a
|
||||
* logged-out link resolution failing says nothing useful about the session's
|
||||
* reachability, so it should not move the app-wide network signal.
|
||||
*/
|
||||
function getPublicChatClient(): Client {
|
||||
return (publicChatClient ??= createLexClient({service: CHAT_SERVICE}))
|
||||
}
|
||||
|
||||
async function fetchJoinLinkPreviews({
|
||||
agent,
|
||||
client,
|
||||
codes,
|
||||
hasSession,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
client: Client
|
||||
codes: string[]
|
||||
hasSession: boolean
|
||||
}) {
|
||||
const previewAgent = new AtpAgent({service: CHAT_SERVICE})
|
||||
const res = hasSession
|
||||
? await agent.chat.bsky.group.getJoinLinkPreviews(
|
||||
{codes},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
: await previewAgent.chat.bsky.group.getJoinLinkPreviews({codes})
|
||||
return res.data
|
||||
return await (hasSession ? client : getPublicChatClient()).call(
|
||||
chat.bsky.group.getJoinLinkPreviews,
|
||||
{codes},
|
||||
)
|
||||
}
|
||||
|
||||
export function useJoinLinkPreviewsQuery({
|
||||
@@ -188,14 +206,14 @@ export function useJoinLinkPreviewsQuery({
|
||||
*/
|
||||
initialData?: ChatBskyGroupGetJoinLinkPreviews.OutputSchema
|
||||
}) {
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useQuery({
|
||||
queryKey: createJoinLinkPreviewQueryKey({codes: codes ?? [], hasSession}),
|
||||
queryFn: async () => {
|
||||
if (!codes) throw new Error('No invite code')
|
||||
try {
|
||||
return await fetchJoinLinkPreviews({agent, codes, hasSession})
|
||||
return await fetchJoinLinkPreviews({client, codes, hasSession})
|
||||
} catch (error) {
|
||||
logger.error('Failed to fetch join link preview', {safeMessage: error})
|
||||
throw error
|
||||
@@ -208,13 +226,13 @@ export function useJoinLinkPreviewsQuery({
|
||||
}
|
||||
|
||||
export function usePrefetchJoinLinkPreviews() {
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return ({codes, hasSession}: {codes: string[]; hasSession: boolean}) => {
|
||||
return queryClient.prefetchQuery({
|
||||
queryKey: createJoinLinkPreviewQueryKey({codes, hasSession}),
|
||||
queryFn: () => fetchJoinLinkPreviews({agent, codes, hasSession}),
|
||||
queryFn: () => fetchJoinLinkPreviews({client, codes, hasSession}),
|
||||
staleTime: STALE.SECONDS.FIFTEEN,
|
||||
})
|
||||
}
|
||||
@@ -226,7 +244,7 @@ export function usePrefetchJoinLinkPreviews() {
|
||||
* Returns undefined if the preview can't be resolved.
|
||||
*/
|
||||
export function useGetJoinLinkPreview() {
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useCallback(
|
||||
@@ -241,7 +259,7 @@ export function useGetJoinLinkPreview() {
|
||||
const data = await queryClient.fetchQuery({
|
||||
queryKey: createJoinLinkPreviewQueryKey({codes: [code], hasSession}),
|
||||
queryFn: () =>
|
||||
fetchJoinLinkPreviews({agent, codes: [code], hasSession}),
|
||||
fetchJoinLinkPreviews({client, codes: [code], hasSession}),
|
||||
staleTime: STALE.SECONDS.FIFTEEN,
|
||||
})
|
||||
const found = data.joinLinkPreviews[0]
|
||||
@@ -251,6 +269,6 @@ export function useGetJoinLinkPreview() {
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
[agent, queryClient],
|
||||
[client, queryClient],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,16 +4,17 @@ import {
|
||||
type ChatBskyConvoListConvos,
|
||||
type ChatBskyGroupAddMembers,
|
||||
} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useChatClient, useSession} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import {RQKEY as CONVO_KEY} from './conversation'
|
||||
import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations'
|
||||
@@ -30,7 +31,7 @@ export function useAddGroupMembers(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
const {currentAccount} = useSession()
|
||||
const {data: myProfile} = useProfileQuery({did: currentAccount?.did})
|
||||
|
||||
@@ -42,11 +43,11 @@ export function useAddGroupMembers(
|
||||
profiles: bsky.profile.AnyProfileView[]
|
||||
}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} = await agent.chat.bsky.group.addMembers(
|
||||
{convoId, members},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.addMembers, {
|
||||
convoId,
|
||||
// callers pass already-resolved actor dids
|
||||
members: members as DidString[],
|
||||
})
|
||||
},
|
||||
onMutate: ({profiles}) => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import {type ChatBskyGroupCreateGroup} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {precacheConvoQuery} from './conversation'
|
||||
|
||||
export function useCreateGroupChat({
|
||||
@@ -14,16 +15,15 @@ export function useCreateGroupChat({
|
||||
onError?: (error: Error) => void
|
||||
}) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({name, members}: {name: string; members: string[]}) => {
|
||||
const {data} = await agent.chat.bsky.group.createGroup(
|
||||
{name, members},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
|
||||
return data
|
||||
return await client.call(chat.bsky.group.createGroup, {
|
||||
name,
|
||||
// callers pass already-resolved actor dids
|
||||
members: members as DidString[],
|
||||
})
|
||||
},
|
||||
onSuccess: data => {
|
||||
precacheConvoQuery(queryClient, data.convo)
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
rollbackConvoOptimistic,
|
||||
updateConvoOptimistic,
|
||||
@@ -24,7 +24,7 @@ export function useCreateJoinLink(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({
|
||||
@@ -35,11 +35,11 @@ export function useCreateJoinLink(
|
||||
requireApproval: boolean
|
||||
}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} = await agent.chat.bsky.group.createJoinLink(
|
||||
{convoId, joinRule, requireApproval},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.createJoinLink, {
|
||||
convoId,
|
||||
joinRule,
|
||||
requireApproval,
|
||||
})
|
||||
},
|
||||
onMutate: ({joinRule, requireApproval}) => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -4,10 +4,10 @@ import {
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {invalidateJoinLinkPreviewsForCode} from '#/state/queries/join-links'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
rollbackConvoOptimistic,
|
||||
updateConvoOptimistic,
|
||||
@@ -24,16 +24,12 @@ export function useDisableJoinLink(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async () => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} = await agent.chat.bsky.group.disableJoinLink(
|
||||
{convoId},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.disableJoinLink, {convoId})
|
||||
},
|
||||
onMutate: () => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {ChatBskyConvoDefs, type ChatBskyGroupEditGroup} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
rollbackConvoOptimistic,
|
||||
updateConvoOptimistic,
|
||||
@@ -20,16 +20,15 @@ export function useEditGroupChatName(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({name: groupName}: {name: string}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} = await agent.chat.bsky.group.editGroup(
|
||||
{convoId, name: groupName},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.editGroup, {
|
||||
convoId,
|
||||
name: groupName,
|
||||
})
|
||||
},
|
||||
onMutate: ({name: groupName}) => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
rollbackConvoOptimistic,
|
||||
updateConvoOptimistic,
|
||||
@@ -24,7 +24,7 @@ export function useEditJoinLink(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({
|
||||
@@ -35,11 +35,11 @@ export function useEditJoinLink(
|
||||
requireApproval: boolean
|
||||
}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} = await agent.chat.bsky.group.editJoinLink(
|
||||
{convoId, joinRule, requireApproval},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.editJoinLink, {
|
||||
convoId,
|
||||
joinRule,
|
||||
requireApproval,
|
||||
})
|
||||
},
|
||||
onMutate: ({joinRule, requireApproval}) => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {ChatBskyConvoDefs, type ChatBskyGroupEnableJoinLink} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {invalidateJoinLinkPreviewsForCode} from '#/state/queries/join-links'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
rollbackConvoOptimistic,
|
||||
updateConvoOptimistic,
|
||||
@@ -21,16 +21,12 @@ export function useEnableJoinLink(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async () => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} = await agent.chat.bsky.group.enableJoinLink(
|
||||
{convoId},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.enableJoinLink, {convoId})
|
||||
},
|
||||
onMutate: () => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -4,15 +4,16 @@ import {
|
||||
type ChatBskyGroupListJoinRequests,
|
||||
type ChatBskyGroupRejectJoinRequest,
|
||||
} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {listConvoMembersQueryKey} from './list-convo-members'
|
||||
import {createListJoinRequestsQueryKey} from './list-join-requests'
|
||||
|
||||
@@ -34,21 +35,28 @@ export function useJoinRequestMutation<A extends JoinRequestAction>(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({member}: {member: string}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} =
|
||||
// callers pass an already-resolved actor did
|
||||
const memberDid = member as DidString
|
||||
const data =
|
||||
action === 'approve'
|
||||
? await agent.chat.bsky.group.approveJoinRequest(
|
||||
{convoId, member},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
: await agent.chat.bsky.group.rejectJoinRequest(
|
||||
{convoId, member},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
? await client.call(chat.bsky.group.approveJoinRequest, {
|
||||
convoId,
|
||||
member: memberDid,
|
||||
})
|
||||
: await client.call(chat.bsky.group.rejectJoinRequest, {
|
||||
convoId,
|
||||
member: memberDid,
|
||||
})
|
||||
/*
|
||||
* The two branches have different output schemas, so the union cannot be
|
||||
* narrowed from the `action` value alone - the cast carries the generic's
|
||||
* mapping through, exactly as the pre-migration code did.
|
||||
*/
|
||||
return data as JoinRequestOutput<A>
|
||||
},
|
||||
onMutate: ({member}) => {
|
||||
|
||||
@@ -2,10 +2,10 @@ import {useEffect} from 'react'
|
||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useInfiniteQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {useMessagesEventBus} from '#/state/messages/events'
|
||||
import {createQueryKey} from '#/state/queries/util'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {STALE} from '..'
|
||||
|
||||
export const JOIN_REQUESTS_THRESHOLD = 20
|
||||
@@ -22,7 +22,7 @@ export function useListJoinRequestsQuery({
|
||||
convoId: string | undefined
|
||||
enabled?: boolean
|
||||
}) {
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
const queryClient = useQueryClient()
|
||||
const messagesBus = useMessagesEventBus()
|
||||
const isEnabled = enabled !== false && !!convoId
|
||||
@@ -54,11 +54,12 @@ export function useListJoinRequestsQuery({
|
||||
enabled: isEnabled,
|
||||
queryKey: createListJoinRequestsQueryKey({convoId: convoId ?? ''}),
|
||||
queryFn: async ({pageParam}) => {
|
||||
const {data} = await agent.chat.bsky.group.listJoinRequests(
|
||||
{convoId: convoId!, cursor: pageParam, limit: JOIN_REQUESTS_THRESHOLD},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.listJoinRequests, {
|
||||
// guarded by `isEnabled`
|
||||
convoId: convoId!,
|
||||
cursor: pageParam,
|
||||
limit: JOIN_REQUESTS_THRESHOLD,
|
||||
})
|
||||
},
|
||||
initialPageParam: undefined as string | undefined,
|
||||
getNextPageParam: page => page.cursor,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {useInfiniteQuery} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {createQueryKey} from '#/state/queries/util'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
|
||||
const listMutualGroupsQueryKeyRoot = 'list-mutual-groups'
|
||||
|
||||
@@ -18,7 +19,7 @@ export function useListMutualGroupsQuery({
|
||||
enabled?: boolean
|
||||
limit?: number
|
||||
}) {
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
const isEnabled = enabled !== false && !!subject
|
||||
|
||||
return useInfiniteQuery({
|
||||
@@ -27,11 +28,12 @@ export function useListMutualGroupsQuery({
|
||||
enabled: isEnabled,
|
||||
queryKey: createListMutualGroupsQueryKey({subject: subject ?? ''}),
|
||||
queryFn: async ({pageParam}) => {
|
||||
const {data} = await agent.chat.bsky.group.listMutualGroups(
|
||||
{subject: subject!, cursor: pageParam, limit},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.listMutualGroups, {
|
||||
// guarded by `enabled`, and callers pass a resolved actor did
|
||||
subject: subject as DidString,
|
||||
cursor: pageParam,
|
||||
limit,
|
||||
})
|
||||
},
|
||||
initialPageParam: undefined as string | undefined,
|
||||
getNextPageParam: page => page.cursor,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {RQKEY as CONVO_KEY} from './conversation'
|
||||
import {
|
||||
type ConvoListQueryData,
|
||||
@@ -12,15 +12,12 @@ import {
|
||||
|
||||
export function useMarkJoinRequestsRead(convoId: string | undefined) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async () => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
await agent.chat.bsky.group.updateJoinRequestsRead(
|
||||
{convoId},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
await client.call(chat.bsky.group.updateJoinRequestsRead, {convoId})
|
||||
},
|
||||
onMutate: () => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -4,15 +4,16 @@ import {
|
||||
type ChatBskyConvoListConvos,
|
||||
type ChatBskyGroupRemoveMembers,
|
||||
} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
useMutation,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {RQKEY as CONVO_KEY} from './conversation'
|
||||
import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations'
|
||||
import {listConvoMembersQueryKey} from './list-convo-members'
|
||||
@@ -28,16 +29,16 @@ export function useRemoveFromGroupChat(
|
||||
},
|
||||
) {
|
||||
const queryClient = useQueryClient()
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({members}: {members: string[]}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
const {data} = await agent.chat.bsky.group.removeMembers(
|
||||
{convoId, members},
|
||||
{headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
|
||||
)
|
||||
return data
|
||||
return await client.call(chat.bsky.group.removeMembers, {
|
||||
convoId,
|
||||
// callers pass already-resolved actor dids
|
||||
members: members as DidString[],
|
||||
})
|
||||
},
|
||||
onMutate: ({members}) => {
|
||||
if (!convoId) return
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {type ChatBskyGroupRequestJoin} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useChatClient, useSession} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {RQKEY_ROOT as REQUESTS_RQKEY_ROOT} from './list-conversation-requests'
|
||||
|
||||
export function useRequestJoinGroupChat({
|
||||
@@ -13,7 +13,7 @@ export function useRequestJoinGroupChat({
|
||||
onSuccess?: (data: ChatBskyGroupRequestJoin.OutputSchema) => void
|
||||
onError?: (error: Error) => void
|
||||
} = {}) {
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
const queryClient = useQueryClient()
|
||||
const {hasSession} = useSession()
|
||||
|
||||
@@ -22,11 +22,7 @@ export function useRequestJoinGroupChat({
|
||||
if (!hasSession) throw new Error('Must be logged in to join')
|
||||
if (!code) throw new Error('No invite code')
|
||||
|
||||
const res = await agent.chat.bsky.group.requestJoin(
|
||||
{code},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
return res.data
|
||||
return await client.call(chat.bsky.group.requestJoin, {code})
|
||||
},
|
||||
onSuccess: data => {
|
||||
void queryClient.invalidateQueries({queryKey: [REQUESTS_RQKEY_ROOT]})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {type ChatBskyGroupWithdrawJoinRequest} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {DM_SERVICE_HEADERS} from '#/lib/constants'
|
||||
import {logger} from '#/logger'
|
||||
import {useAgent, useSession} from '#/state/session'
|
||||
import {useChatClient, useSession} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
type ConvoRequestListQueryData,
|
||||
optimisticDeleteJoinRequest,
|
||||
@@ -17,7 +17,7 @@ export function useWithdrawJoinGroupChatRequest({
|
||||
onSuccess?: (data: ChatBskyGroupWithdrawJoinRequest.OutputSchema) => void
|
||||
onError?: (error: Error) => void
|
||||
} = {}) {
|
||||
const agent = useAgent()
|
||||
const client = useChatClient()
|
||||
const queryClient = useQueryClient()
|
||||
const {hasSession} = useSession()
|
||||
|
||||
@@ -27,11 +27,7 @@ export function useWithdrawJoinGroupChatRequest({
|
||||
throw new Error('Must be logged in to withdraw a join request')
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
|
||||
const res = await agent.chat.bsky.group.withdrawJoinRequest(
|
||||
{convoId},
|
||||
{headers: DM_SERVICE_HEADERS},
|
||||
)
|
||||
return res.data
|
||||
return await client.call(chat.bsky.group.withdrawJoinRequest, {convoId})
|
||||
},
|
||||
onSuccess: (data, {convoId}) => {
|
||||
queryClient.setQueriesData<ConvoRequestListQueryData>(
|
||||
|
||||
Reference in New Issue
Block a user