forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {
2 type ChatBskyActorDefs,
3 type ChatBskyConvoDefs,
4 type ChatBskyConvoListConvos,
5 type ChatBskyGroupRemoveMembers,
6} from '@atproto/api'
7import {
8 type InfiniteData,
9 useMutation,
10 useQueryClient,
11} from '@tanstack/react-query'
12
13import {DM_SERVICE_HEADERS} from '#/lib/constants'
14import {logger} from '#/logger'
15import {useAgent} from '#/state/session'
16import {RQKEY as CONVO_KEY} from './conversation'
17import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations'
18import {listConvoMembersQueryKey} from './list-convo-members'
19
20export function useRemoveFromGroupChat(
21 convoId: string | undefined,
22 {
23 onSuccess,
24 onError,
25 }: {
26 onSuccess?: (data: ChatBskyGroupRemoveMembers.OutputSchema) => void
27 onError?: (error: Error) => void
28 },
29) {
30 const queryClient = useQueryClient()
31 const agent = useAgent()
32
33 return useMutation({
34 mutationFn: async ({members}: {members: string[]}) => {
35 if (!convoId) throw new Error('No convoId provided')
36 const {data} = await agent.chat.bsky.group.removeMembers(
37 {convoId, members},
38 {headers: DM_SERVICE_HEADERS, encoding: 'application/json'},
39 )
40 return data
41 },
42 onMutate: ({members}) => {
43 if (!convoId) return
44
45 const prevConvo = queryClient.getQueryData<ChatBskyConvoDefs.ConvoView>(
46 CONVO_KEY(convoId),
47 )
48 const prevListEntries = queryClient.getQueriesData<
49 InfiniteData<ChatBskyConvoListConvos.OutputSchema>
50 >({queryKey: [CONVO_LIST_KEY]})
51 const prevMemberList = queryClient.getQueryData<
52 ChatBskyActorDefs.ProfileViewBasic[]
53 >(listConvoMembersQueryKey(convoId))
54
55 queryClient.setQueryData<ChatBskyConvoDefs.ConvoView>(
56 CONVO_KEY(convoId),
57 prev => {
58 if (!prev) return
59 return {
60 ...prev,
61 members: prev.members.filter(m => !members.includes(m.did)),
62 }
63 },
64 )
65
66 queryClient.setQueriesData<
67 InfiniteData<ChatBskyConvoListConvos.OutputSchema>
68 >({queryKey: [CONVO_LIST_KEY]}, prev => {
69 if (!prev?.pages) return
70 return {
71 ...prev,
72 pages: prev.pages.map(page => ({
73 ...page,
74 convos: page.convos.map(convo => {
75 if (convo.id !== convoId) return convo
76 return {
77 ...convo,
78 members: convo.members.filter(m => !members.includes(m.did)),
79 }
80 }),
81 })),
82 }
83 })
84
85 queryClient.setQueryData<ChatBskyActorDefs.ProfileViewBasic[]>(
86 listConvoMembersQueryKey(convoId),
87 prev => {
88 if (!prev) return
89 return prev.filter(m => !members.includes(m.did))
90 },
91 )
92
93 return {prevConvo, prevListEntries, prevMemberList}
94 },
95 onSuccess: data => {
96 onSuccess?.(data)
97 },
98 onError: (e, _variables, context) => {
99 logger.error(e)
100 if (context?.prevConvo && convoId) {
101 queryClient.setQueryData(CONVO_KEY(convoId), context.prevConvo)
102 }
103 if (context?.prevListEntries) {
104 for (const [key, data] of context.prevListEntries) {
105 queryClient.setQueryData(key, data)
106 }
107 }
108 if (context?.prevMemberList && convoId) {
109 queryClient.setQueryData(
110 listConvoMembersQueryKey(convoId),
111 context.prevMemberList,
112 )
113 }
114 onError?.(e)
115 },
116 })
117}