import { Updater, useMutation, useQueryClient } from '@tanstack/react-query' import { ApiResource, ConversationMembershipResource, ConversationResource } from '../types' import { deepSnakeCaseKeys } from '../utils/deep_snake_case_keys' import { throwResponseError } from '../utils/response_error' import { useApiClient } from './use_api_client' import { getConversationRequestArgs } from './use_conversation' import { getRequestQueryKey } from './use_suspense_api' export const useConversationMembershipUpdate = ({ conversation_id, }: { conversation_id: number }) => { const apiClient = useApiClient() const queryClient = useQueryClient() const requestArgs = getConversationRequestArgs({ conversation_id }) const conversationMembershipFields = requestArgs.data.fields.ConversationMembership.join(',') const queryKey = getRequestQueryKey(requestArgs) return useMutation({ throwOnError: true, onMutate: async (attributes: Partial) => { queryClient.setQueryData>( queryKey, updateConversationMembershipAttributes(attributes) ) }, mutationKey: ['updateConversationMembership', conversation_id], mutationFn: async (attributes: Partial) => { return apiClient.chat .patch>({ url: `/me/conversations/${conversation_id}/conversation_membership`, data: { data: { type: 'ConversationMembership', attributes: deepSnakeCaseKeys(attributes), }, fields: { ConversationMembership: conversationMembershipFields, }, }, }) .catch(throwResponseError) }, onSuccess: response => { const membership = response.data queryClient.setQueryData>( queryKey, updateConversationMembershipAttributes(membership) ) }, }) } const updateConversationMembershipAttributes = ( membership: Partial ): Updater< ApiResource | undefined, ApiResource | undefined > => conversationData => mergeConversationMembership(conversationData, membership) const mergeConversationMembership = ( conversationData: ApiResource | undefined, membership: Partial ) => { if (!conversationData) return undefined if (!conversationData.data) return conversationData if (!conversationData.data.conversationMembership) return conversationData const previousMembership: Partial = conversationData.data.conversationMembership || {} const mergedMembership: Partial = { ...previousMembership, ...membership, } const data: ConversationResource = { ...conversationData.data, conversationMembership: mergedMembership, } return { ...conversationData, data, } }