diff --git a/features/conversation-requests-list/use-conversation-requests-list-items.tsx b/features/conversation-requests-list/use-conversation-requests-list-items.tsx index 04e2af553..bb755a080 100644 --- a/features/conversation-requests-list/use-conversation-requests-list-items.tsx +++ b/features/conversation-requests-list/use-conversation-requests-list-items.tsx @@ -2,110 +2,66 @@ import { getV3SpamScore } from "@/data/helpers/conversations/spamScore"; import { useCurrentAccount } from "@/data/store/accountsStore"; import { getMessageStringContent } from "@/features/conversation/conversation-message/conversation-message.utils"; import { getUnknownConsentConversationsQueryOptions } from "@/queries/unknown-consent-conversations-query"; -import { captureError, captureErrorWithToast } from "@/utils/capture-error"; -import { ConversationWithCodecsType } from "@/utils/xmtpRN/client.types"; +import { captureError } from "@/utils/capture-error"; import { getMessageContentType } from "@/utils/xmtpRN/content-types/content-types"; -import { useQuery } from "@tanstack/react-query"; -import { useEffect, useState } from "react"; +import { useQueries, useQuery } from "@tanstack/react-query"; -// TODO: Put in react query - -export const useConversationRequestsListItem = () => { +export function useConversationRequestsListItem() { const currentAccount = useCurrentAccount(); - const [isProcessingConversations, setIsProcessingConversations] = - useState(false); - - const [likelyNotSpam, setLikelyNotSpam] = useState< - ConversationWithCodecsType[] - >([]); - const [likelySpam, setLikelySpam] = useState( - [] - ); - const { data: conversations, isLoading: isLoadingConversations } = useQuery( - getUnknownConsentConversationsQueryOptions({ + const { + data: unkownConsentConversations, + isLoading: unkownConsentConversationsLoading, + } = useQuery({ + ...getUnknownConsentConversationsQueryOptions({ account: currentAccount!, context: "useConversationRequestsListItem", - }) - ); - - const numberOfConversations = conversations?.length; - - useEffect(() => { - async function processConversations( - conversations: ConversationWithCodecsType[] - ) { - try { - setIsProcessingConversations(true); - const isSpamResults = await Promise.allSettled( - conversations.map(async (conversation) => { - try { - // ! since we check for lastMessage in the select, we can safely assume it's not undefined - const lastMessage = conversation.lastMessage!; - const messageText = getMessageStringContent(lastMessage); - - if (!messageText) { - return true; - } - - // Get spam score - const contentType = getMessageContentType( - lastMessage.contentTypeId! - ); - - if (!contentType) { - return true; - } - - const spamScore = await getV3SpamScore({ - messageText: messageText, - contentType, - }); - - if (spamScore === 0) { - return false; - } - - return true; - } catch (error) { - captureError(error); - return true; - } - }) - ); - - const notSpams: ConversationWithCodecsType[] = []; - const spams: ConversationWithCodecsType[] = []; - - isSpamResults.forEach((result, index) => { - if (result.status !== "fulfilled") { - return; - } - const conversation = conversations[index]; - const isSpam = result.value; - if (isSpam) { - spams.push(conversation); - } else { - notSpams.push(conversation); - } - }); - - setLikelyNotSpam(notSpams); - setLikelySpam(spams); - } catch (error) { - captureErrorWithToast(error); - } finally { - // Default to putting all conversations in likelySpam if we have an error - setLikelySpam(conversations); - setIsProcessingConversations(false); - } - } - - processConversations(conversations ?? []); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [numberOfConversations]); - - const isLoading = isLoadingConversations || isProcessingConversations; - - return { likelyNotSpam, likelySpam, isLoading }; -}; + }), + }); + + const spamQueries = useQueries({ + queries: (unkownConsentConversations ?? []).map((conversation) => ({ + queryKey: ["is-spam", conversation.topic], + queryFn: async () => { + const lastMessage = conversation.lastMessage!; + const messageText = getMessageStringContent(lastMessage); + + if (!messageText) { + return true; + } + + const contentType = getMessageContentType(lastMessage.contentTypeId!); + if (!contentType) { + return true; + } + + try { + const spamScore = await getV3SpamScore({ + messageText, + contentType, + }); + return spamScore !== 0; + } catch (error) { + captureError(error); + return true; + } + }, + enabled: !!conversation.lastMessage, + })), + }); + + const isLoading = + unkownConsentConversationsLoading || spamQueries.some((q) => q.isLoading); + const spamResults = spamQueries.map((q, i) => ({ + conversation: unkownConsentConversations?.[i], + isSpam: q.data ?? true, + })); + + return { + likelyNotSpam: + spamResults.filter((r) => !r.isSpam).map((r) => r.conversation) ?? [], + likelySpam: + spamResults.filter((r) => r.isSpam).map((r) => r.conversation) ?? [], + isLoading, + }; +}