82 lines
3.1 KiB
TypeScript
82 lines
3.1 KiB
TypeScript
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { apiClient } from '@/services/api/client';
|
|
import { useToast } from '@/hooks/useToast';
|
|
import { useChatStore } from '../../store/chatStore';
|
|
|
|
export interface UseConversationActionsCallbacks {
|
|
onLeaveError?: (error: Error) => void;
|
|
onDeleteError?: (error: Error) => void;
|
|
onLeaveSuccess?: () => void;
|
|
onDeleteSuccess?: () => void;
|
|
}
|
|
|
|
export function useConversationActions(
|
|
userId: string | undefined,
|
|
callbacks?: UseConversationActionsCallbacks,
|
|
) {
|
|
const queryClient = useQueryClient();
|
|
const toast = useToast();
|
|
const setCurrentConversation = useChatStore((s) => s.setCurrentConversation);
|
|
|
|
const leaveRoomMutation = useMutation({
|
|
mutationFn: async (roomId: string) => {
|
|
await apiClient.delete(`/conversations/${roomId}/participants/${userId}`);
|
|
},
|
|
onMutate: async (roomId: string) => {
|
|
await queryClient.cancelQueries({ queryKey: ['chatConversations', userId] });
|
|
const previous = queryClient.getQueryData<unknown[]>(['chatConversations', userId]);
|
|
if (previous && Array.isArray(previous)) {
|
|
queryClient.setQueryData(
|
|
['chatConversations', userId],
|
|
previous.filter((c: { id: string }) => c.id !== roomId),
|
|
);
|
|
}
|
|
return { previous };
|
|
},
|
|
onError: (err, _roomId, context) => {
|
|
if (context?.previous) {
|
|
queryClient.setQueryData(['chatConversations', userId], context.previous);
|
|
}
|
|
const msg = (err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed to leave room';
|
|
callbacks?.onLeaveError?.(new Error(msg));
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['chatConversations', userId] });
|
|
toast.success('Left room successfully');
|
|
setCurrentConversation(null);
|
|
callbacks?.onLeaveSuccess?.();
|
|
},
|
|
});
|
|
|
|
const deleteRoomMutation = useMutation({
|
|
mutationFn: async (roomId: string) => {
|
|
await apiClient.delete(`/conversations/${roomId}`);
|
|
},
|
|
onMutate: async (roomId: string) => {
|
|
await queryClient.cancelQueries({ queryKey: ['chatConversations', userId] });
|
|
const previous = queryClient.getQueryData<unknown[]>(['chatConversations', userId]);
|
|
if (previous && Array.isArray(previous)) {
|
|
queryClient.setQueryData(
|
|
['chatConversations', userId],
|
|
previous.filter((c: { id: string }) => c.id !== roomId),
|
|
);
|
|
}
|
|
return { previous };
|
|
},
|
|
onError: (err, _roomId, context) => {
|
|
if (context?.previous) {
|
|
queryClient.setQueryData(['chatConversations', userId], context.previous);
|
|
}
|
|
const msg = (err as { response?: { data?: { error?: string } } })?.response?.data?.error ?? 'Failed to delete room';
|
|
callbacks?.onDeleteError?.(new Error(msg));
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['chatConversations', userId] });
|
|
toast.success('Room deleted successfully');
|
|
setCurrentConversation(null);
|
|
callbacks?.onDeleteSuccess?.();
|
|
},
|
|
});
|
|
|
|
return { leaveRoomMutation, deleteRoomMutation };
|
|
}
|