import { useMutation, useQueryClient } from '@tanstack/react-query' import { Alert } from 'react-native' import { useConversationsContext } from '../contexts/conversations_context' import { ApiResource, ConversationResource } from '../types' import { useApiClient } from './use_api_client' import { getConversationRequestArgs } from './use_conversation' import { useConversationsCache } from './use_conversations_cache' import { useCurrentPersonCache } from './use_current_person' import { getRequestQueryKey } from './use_suspense_api' export const useConversationsMarkRead = ({ conversation, }: { conversation: ConversationResource }) => { const apiClient = useApiClient() const queryClient = useQueryClient() const { args } = useConversationsContext() const currentPersonCache = useCurrentPersonCache() const { update, invalidate, fetchUpdate } = useConversationsCache(args) const conversationQueryKey = getRequestQueryKey( getConversationRequestArgs({ conversation_id: conversation.id }) ) function handlePersonUnreadCount(read: boolean) { currentPersonCache.update({}, person => { const currentUnread = person.unreadCount const updatedUnread = read ? Math.max(currentUnread - 1, 0) : currentUnread + 1 return { ...person, unreadCount: updatedUnread } }) } const { mutate: handleMarkRead, ...mutation } = useMutation({ onMutate: async (read: boolean) => { update({ ...conversation, unreadCount: read ? 0 : 1, ...(read ? { unreadReaction: false } : {}), }) if (read) { queryClient.setQueryData>(conversationQueryKey, prev => { if (!prev?.data) return prev return { ...prev, data: { ...prev.data, unreadReaction: false } } }) } handlePersonUnreadCount(read) }, mutationKey: ['markRead', conversation.id], mutationFn: async (read: boolean) => { const action = read ? 'mark_read' : 'mark_unread' return apiClient.chat.post({ url: `/me/conversations/${conversation.id}/${action}`, data: { data: { type: '', attributes: {} }, fields: { Conversation: 'unread_count,id' } }, }) }, onSuccess: () => { fetchUpdate(conversation) }, onError: () => { Alert.alert('Oops', 'Something went wrong updating this conversation, please try again') invalidate() }, }) return { read: conversation.unreadCount < 1, // prefer cache markRead: handleMarkRead, ...mutation, } } export const useConversationsMute = ({ conversation }: { conversation: ConversationResource }) => { const apiClient = useApiClient() const { args } = useConversationsContext() const { update, invalidate } = useConversationsCache(args) const { mutate: setMuted, ...mutation } = useMutation({ onMutate: async (muted: boolean) => { update({ ...conversation, muted, conversationMembership: { ...conversation?.conversationMembership, muted, }, }) }, mutationKey: ['muteConversation'], mutationFn: async (muted: boolean) => { const action = muted ? 'mute' : 'unmute' return apiClient.chat.post>({ url: `/me/conversations/${conversation.id}/${action}`, data: { data: { type: '', attributes: {} }, fields: { Conversation: 'muted' } }, }) }, onSuccess: (response: ApiResource) => { update(response.data) }, onError: () => { Alert.alert('Oops', 'Something went wrong muting this conversation, please try again') invalidate() }, }) return { muted: conversation.muted, // prefer cache setMuted, ...mutation, } } export const useMarkAllRead = () => { const apiClient = useApiClient() const { args } = useConversationsContext() const { invalidate, updateAll } = useConversationsCache(args) const { mutate: markAllRead, ...query } = useMutation({ onMutate: () => { updateAll({ unreadCount: 0, unreadReaction: false, }) }, mutationKey: ['markAllRead', args], mutationFn: () => apiClient.chat.post({ url: '/me/mark_all_read', }), onSettled: invalidate, }) return { markAllRead, ...query, } }