blob: e33a9ccb021cf4d7ea76329e82f8548243a58f7e [file] [log] [blame]
simon26e79f72022-10-05 22:16:08 -04001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
simond47ef9e2022-09-28 22:24:28 -040018import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
idillon18283ac2023-01-07 12:06:42 -050019import { AxiosResponse } from 'axios';
20import {
21 ConversationInfos,
22 IConversationMember,
23 IConversationRequest,
24 IConversationSummary,
25 Message,
26} from 'jami-web-common';
idillon07d31cc2022-12-06 22:40:14 -050027import { useCallback } from 'react';
idillon08f77172022-09-13 19:14:17 -040028
simon5da8ca62022-11-09 15:21:25 -050029import { useAuthContext } from '../contexts/AuthProvider';
idillon07d31cc2022-12-06 22:40:14 -050030import { ConversationMember } from '../models/conversation-member';
idillon18283ac2023-01-07 12:06:42 -050031import { useAddToCache, useRemoveFromCache } from '../utils/reactquery';
simon5da8ca62022-11-09 15:21:25 -050032
idillon07d31cc2022-12-06 22:40:14 -050033export const useConversationInfosQuery = (conversationId?: string) => {
simon94fe53e2022-11-10 12:51:58 -050034 const { axiosInstance } = useAuthContext();
idillon07d31cc2022-12-06 22:40:14 -050035 return useQuery(
36 ['conversations', conversationId],
simon94fe53e2022-11-10 12:51:58 -050037 async () => {
idillon07d31cc2022-12-06 22:40:14 -050038 const { data } = await axiosInstance.get<ConversationInfos>(`/conversations/${conversationId}/infos`);
simon94fe53e2022-11-10 12:51:58 -050039 return data;
40 },
41 {
42 enabled: !!conversationId,
43 }
44 );
idillon07d31cc2022-12-06 22:40:14 -050045};
simone35acc22022-12-02 16:51:12 -050046
idillon07d31cc2022-12-06 22:40:14 -050047export const useConversationsSummariesQuery = () => {
48 const { axiosInstance } = useAuthContext();
49 return useQuery(['conversations', 'summaries'], async () => {
50 const { data } = await axiosInstance.get<IConversationSummary[]>(`/conversations`);
51 return data;
52 });
53};
54
idillon18283ac2023-01-07 12:06:42 -050055const checkConversationSummariesAreEqual = (
56 conversationSummary1: IConversationSummary,
57 conversationSummary2: IConversationSummary
58) => conversationSummary1.id === conversationSummary2.id;
59const checkIsConversationSummaryFn = (conversationSummary: IConversationSummary, conversationId: string) =>
60 conversationSummary.id === conversationId;
61
62export const useAddConversationSummaryToCache = () =>
63 useAddToCache(['conversations', 'summaries'], checkConversationSummariesAreEqual);
64export const useRemoveConversationSummaryFromCache = () =>
65 useRemoveFromCache(['conversations', 'summaries'], checkIsConversationSummaryFn);
66
67export const useRemoveConversationMutation = () => {
68 const { axiosInstance } = useAuthContext();
69 const removeConversationSummaryFromCache = useRemoveConversationSummaryFromCache();
70 return useMutation(
71 ({ conversationId }: { conversationId: string }) => axiosInstance.delete(`/conversations/${conversationId}`),
72 {
73 onSuccess: (_data, { conversationId }) => {
74 removeConversationSummaryFromCache(conversationId);
75 },
76 }
77 );
78};
79
idillon07d31cc2022-12-06 22:40:14 -050080export const useRefreshConversationsSummaries = () => {
81 const queryClient = useQueryClient();
82 return useCallback(() => {
83 queryClient.invalidateQueries(['conversations', 'summaries']);
84 }, [queryClient]);
85};
86
87export const useMembersQuery = (conversationId?: string) => {
88 const { axiosInstance } = useAuthContext();
89 return useQuery(
90 ['conversations', conversationId, 'members'],
91 async () => {
92 const { data } = await axiosInstance.get<IConversationMember[]>(`/conversations/${conversationId}/members`);
93 return data.map((item) => ConversationMember.fromInterface(item));
94 },
95 {
96 enabled: !!conversationId,
simone35acc22022-12-02 16:51:12 -050097 }
idillon07d31cc2022-12-06 22:40:14 -050098 );
simond47ef9e2022-09-28 22:24:28 -040099};
idillon08f77172022-09-13 19:14:17 -0400100
simon5da8ca62022-11-09 15:21:25 -0500101export const useMessagesQuery = (conversationId: string) => {
simon94fe53e2022-11-10 12:51:58 -0500102 const { axiosInstance } = useAuthContext();
103 return useQuery(
idillon07d31cc2022-12-06 22:40:14 -0500104 ['conversations', conversationId, 'messages'],
simon94fe53e2022-11-10 12:51:58 -0500105 async () => {
Misha Krieger-Raynauldcfa44302022-11-30 18:36:36 -0500106 const { data } = await axiosInstance.get<Message[]>(`/conversations/${conversationId}/messages`);
simon94fe53e2022-11-10 12:51:58 -0500107 return data;
108 },
109 {
110 enabled: !!conversationId,
111 }
112 );
simond47ef9e2022-09-28 22:24:28 -0400113};
idillon08f77172022-09-13 19:14:17 -0400114
simon5da8ca62022-11-09 15:21:25 -0500115export const useSendMessageMutation = (conversationId: string) => {
simon94fe53e2022-11-10 12:51:58 -0500116 const { axiosInstance } = useAuthContext();
simond47ef9e2022-09-28 22:24:28 -0400117 const queryClient = useQueryClient();
118 return useMutation(
simon94fe53e2022-11-10 12:51:58 -0500119 (message: string) => axiosInstance.post(`/conversations/${conversationId}/messages`, { message }),
simond47ef9e2022-09-28 22:24:28 -0400120 {
simon5da8ca62022-11-09 15:21:25 -0500121 onSuccess: () => queryClient.invalidateQueries(['messages', conversationId]),
simond47ef9e2022-09-28 22:24:28 -0400122 }
123 );
124};
idillon18283ac2023-01-07 12:06:42 -0500125
126const CheckConversationRequestsAreEqual = (
127 conversationRequest1: IConversationRequest,
128 conversationRequest2: IConversationRequest
129) => conversationRequest1.conversationId === conversationRequest2.conversationId;
130const checkIsConversationRequestFn = (conversationRequest: IConversationRequest, conversationId: string) =>
131 conversationRequest.conversationId === conversationId;
132
133export const useAddConversationRequestToCache = () =>
134 useAddToCache(['conversationsRequests'], CheckConversationRequestsAreEqual);
135export const useRemoveConversationRequestFromCache = () =>
136 useRemoveFromCache(['conversationsRequests'], checkIsConversationRequestFn);
137
138export const useConversationRequestsQuery = () => {
139 const { axiosInstance } = useAuthContext();
140 return useQuery({
141 queryKey: ['conversationRequests'],
142 queryFn: async () => {
143 const { data } = await axiosInstance.get<IConversationRequest[]>('/conversation-requests/');
144 return data;
145 },
146 });
147};
148
149export const useAcceptConversationRequestMutation = () => {
150 const { axiosInstance } = useAuthContext();
151 const addConversationSummaryToCache = useAddConversationSummaryToCache();
152 const removeConversationRequestFromCache = useRemoveConversationRequestFromCache();
153 return useMutation(
154 async (variables: { conversationId: string }) => {
155 const { data } = await axiosInstance.post<undefined, AxiosResponse<IConversationSummary>>(
156 `/conversation-requests/${variables.conversationId}`
157 );
158 return data;
159 },
160 {
161 onSuccess: (data, { conversationId }) => {
162 addConversationSummaryToCache(data);
163 removeConversationRequestFromCache(conversationId);
164 },
165 }
166 );
167};
168
169export const useBlockConversationRequestMutation = () => {
170 const { axiosInstance } = useAuthContext();
171 const removeConversationRequestFromCache = useRemoveConversationRequestFromCache();
172 return useMutation(
173 ({ conversationId }: { conversationId: string }) =>
174 axiosInstance.post(`/conversation-requests/${conversationId}/block`),
175 {
176 onSuccess: (_data, { conversationId }) => {
177 removeConversationRequestFromCache(conversationId);
178 },
179 }
180 );
181};
182
183export const useDeclineConversationRequestMutation = () => {
184 const { axiosInstance } = useAuthContext();
185 const removeConversationRequestFromCache = useRemoveConversationRequestFromCache();
186 return useMutation(
187 ({ conversationId }: { conversationId: string }) =>
188 axiosInstance.delete(`/conversation-requests/${conversationId}`),
189 {
190 onSuccess: (_data, { conversationId }) => {
191 removeConversationRequestFromCache(conversationId);
192 },
193 }
194 );
195};