Organize code

This commit is contained in:
Nicola Benaglia 2025-05-11 00:00:36 +02:00
parent ccd348100e
commit 5820f8123c
3 changed files with 88 additions and 63 deletions

View File

@ -1,12 +1,17 @@
import React, { createContext, useContext, useState, useCallback, useRef } from 'react'; import {
import ShortUniqueId from "short-unique-id"; createContext,
useContext,
useState,
useCallback,
useRef,
} from 'react';
import ShortUniqueId from 'short-unique-id';
const MessageQueueContext = createContext(null); const MessageQueueContext = createContext(null);
const uid = new ShortUniqueId({ length: 8 });
export const useMessageQueue = () => useContext(MessageQueueContext); export const useMessageQueue = () => useContext(MessageQueueContext);
const uid = new ShortUniqueId({ length: 8 });
export const MessageQueueProvider = ({ children }) => { export const MessageQueueProvider = ({ children }) => {
const messageQueueRef = useRef([]); const messageQueueRef = useRef([]);
const [queueChats, setQueueChats] = useState({}); // Stores chats and status for display const [queueChats, setQueueChats] = useState({}); // Stores chats and status for display
@ -21,39 +26,41 @@ export const MessageQueueProvider = ({ children }) => {
const processingPromiseRef = useRef(Promise.resolve()); const processingPromiseRef = useRef(Promise.resolve());
// Function to add a message to the queue // Function to add a message to the queue
const addToQueue = useCallback((sendMessageFunc, messageObj, type, groupDirectId) => { const addToQueue = useCallback(
const tempId = uid.rnd(); (sendMessageFunc, messageObj, type, groupDirectId) => {
const chatData = { const tempId = uid.rnd();
...messageObj, const chatData = {
type, ...messageObj,
groupDirectId, type,
signature: uid.rnd(), groupDirectId,
identifier: tempId, signature: uid.rnd(),
retries: 0, // Retry count for display purposes identifier: tempId,
status: 'pending' // Initial status is 'pending' retries: 0, // Retry count for display purposes
}; status: 'pending', // Initial status is 'pending'
};
// Add chat data to queueChats for status tracking // Add chat data to queueChats for status tracking
setQueueChats((prev) => ({ setQueueChats((prev) => ({
...prev, ...prev,
[groupDirectId]: [...(prev[groupDirectId] || []), chatData] [groupDirectId]: [...(prev[groupDirectId] || []), chatData],
})); }));
// Add the message to the global messageQueueRef // Add the message to the global messageQueueRef
messageQueueRef.current.push({ messageQueueRef.current.push({
func: sendMessageFunc, func: sendMessageFunc,
identifier: tempId, identifier: tempId,
groupDirectId, groupDirectId,
specialId: messageObj?.message?.specialId specialId: messageObj?.message?.specialId,
}); });
// Start processing the queue // Start processing the queue
processQueue([], groupDirectId); processQueue([], groupDirectId);
}, []); },
[]
);
// Function to process the message queue // Function to process the message queue
const processQueue = useCallback((newMessages = [], groupDirectId) => { const processQueue = useCallback((newMessages = [], groupDirectId) => {
processingPromiseRef.current = processingPromiseRef.current processingPromiseRef.current = processingPromiseRef.current
.then(() => processQueueInternal(newMessages, groupDirectId)) .then(() => processQueueInternal(newMessages, groupDirectId))
.catch((err) => console.error('Error in processQueue:', err)); .catch((err) => console.error('Error in processQueue:', err));
@ -62,7 +69,7 @@ export const MessageQueueProvider = ({ children }) => {
// Internal function to handle queue processing // Internal function to handle queue processing
const processQueueInternal = async (newMessages, groupDirectId) => { const processQueueInternal = async (newMessages, groupDirectId) => {
// Remove any messages from the queue that match the specialId from newMessages // Remove any messages from the queue that match the specialId from newMessages
// If the queue is empty, no need to process // If the queue is empty, no need to process
if (messageQueueRef.current.length === 0) return; if (messageQueueRef.current.length === 0) return;
@ -92,7 +99,6 @@ export const MessageQueueProvider = ({ children }) => {
// Remove the message from the queue after successful sending // Remove the message from the queue after successful sending
messageQueueRef.current.shift(); messageQueueRef.current.shift();
} catch (error) { } catch (error) {
console.error('Message sending failed', error); console.error('Message sending failed', error);
@ -110,7 +116,8 @@ export const MessageQueueProvider = ({ children }) => {
updatedChats[groupDirectId][chatIndex].status = 'failed'; updatedChats[groupDirectId][chatIndex].status = 'failed';
} else { } else {
// Max retries reached, set status to 'failed-permanent' // Max retries reached, set status to 'failed-permanent'
updatedChats[groupDirectId][chatIndex].status = 'failed-permanent'; updatedChats[groupDirectId][chatIndex].status =
'failed-permanent';
// Remove the message from the queue after max retries // Remove the message from the queue after max retries
messageQueueRef.current.shift(); messageQueueRef.current.shift();
@ -127,33 +134,39 @@ export const MessageQueueProvider = ({ children }) => {
// Method to process with new messages and groupDirectId // Method to process with new messages and groupDirectId
const processWithNewMessages = (newMessages, groupDirectId) => { const processWithNewMessages = (newMessages, groupDirectId) => {
let updatedNewMessages = newMessages let updatedNewMessages = newMessages;
if (newMessages.length > 0) { if (newMessages.length > 0) {
// Remove corresponding entries in queueChats for the provided groupDirectId // Remove corresponding entries in queueChats for the provided groupDirectId
setQueueChats((prev) => { setQueueChats((prev) => {
const updatedChats = { ...prev }; const updatedChats = { ...prev };
if (updatedChats[groupDirectId]) { if (updatedChats[groupDirectId]) {
updatedNewMessages = newMessages?.map((msg) => {
updatedNewMessages = newMessages?.map((msg)=> { const findTempMsg = updatedChats[groupDirectId]?.find(
const findTempMsg = updatedChats[groupDirectId]?.find((msg2)=> msg2?.message?.specialId === msg?.specialId) (msg2) => msg2?.message?.specialId === msg?.specialId
if(findTempMsg){ );
if (findTempMsg) {
return { return {
...msg, ...msg,
tempSignature: findTempMsg?.signature tempSignature: findTempMsg?.signature,
} };
} }
return msg return msg;
})
updatedChats[groupDirectId] = updatedChats[groupDirectId].filter((chat) => {
return !newMessages.some(newMsg => newMsg?.specialId === chat?.message?.specialId);
}); });
updatedChats[groupDirectId] = updatedChats[groupDirectId].filter(
(chat) => {
return !newMessages.some(
(newMsg) => newMsg?.specialId === chat?.message?.specialId
);
}
);
// Remove messages with status 'failed-permanent' // Remove messages with status 'failed-permanent'
updatedChats[groupDirectId] = updatedChats[groupDirectId].filter((chat) => { updatedChats[groupDirectId] = updatedChats[groupDirectId].filter(
return chat?.status !== 'failed-permanent'; (chat) => {
}); return chat?.status !== 'failed-permanent';
}
);
// If no more chats for this group, delete the groupDirectId entry // If no more chats for this group, delete the groupDirectId entry
if (updatedChats[groupDirectId].length === 0) { if (updatedChats[groupDirectId].length === 0) {
@ -162,27 +175,36 @@ export const MessageQueueProvider = ({ children }) => {
} }
return updatedChats; return updatedChats;
}); });
} }
setTimeout(() => { setTimeout(() => {
if(!messageQueueRef.current.find((msg) => msg?.groupDirectId === groupDirectId)){ if (
!messageQueueRef.current.find(
(msg) => msg?.groupDirectId === groupDirectId
)
) {
setQueueChats((prev) => { setQueueChats((prev) => {
const updatedChats = { ...prev }; const updatedChats = { ...prev };
if (updatedChats[groupDirectId]) { if (updatedChats[groupDirectId]) {
delete updatedChats[groupDirectId] delete updatedChats[groupDirectId];
} }
return updatedChats return updatedChats;
} });
)
} }
}, 300); }, 300);
return updatedNewMessages return updatedNewMessages;
}; };
return ( return (
<MessageQueueContext.Provider value={{ addToQueue, queueChats, clearStatesMessageQueueProvider, processWithNewMessages }}> <MessageQueueContext.Provider
value={{
addToQueue,
queueChats,
clearStatesMessageQueueProvider,
processWithNewMessages,
}}
>
{children} {children}
</MessageQueueContext.Provider> </MessageQueueContext.Provider>
); );

View File

@ -7,11 +7,9 @@ import { subscribeToEvent, unsubscribeFromEvent } from '../utils/events';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
export const useHandlePaymentNotification = (address) => { export const useHandlePaymentNotification = (address) => {
const [latestTx, setLatestTx] = useState(null);
const nameAddressOfSender = useRef({}); const nameAddressOfSender = useRef({});
const isFetchingName = useRef({}); const isFetchingName = useRef({});
const [latestTx, setLatestTx] = useState(null);
const [lastEnteredTimestampPayment, setLastEnteredTimestampPayment] = useAtom( const [lastEnteredTimestampPayment, setLastEnteredTimestampPayment] = useAtom(
lastPaymentSeenTimestampAtom lastPaymentSeenTimestampAtom
); );
@ -63,6 +61,7 @@ export const useHandlePaymentNotification = (address) => {
const key = `last-seen-payment-${address}`; const key = `last-seen-payment-${address}`;
const res = await getData<any>(key).catch(() => null); const res = await getData<any>(key).catch(() => null);
if (res) { if (res) {
setLastEnteredTimestampPayment(res); setLastEnteredTimestampPayment(res);
} }
@ -76,6 +75,7 @@ export const useHandlePaymentNotification = (address) => {
const latestTx = responseData.filter( const latestTx = responseData.filter(
(tx) => tx?.creatorAddress !== address && tx?.recipient === address (tx) => tx?.creatorAddress !== address && tx?.recipient === address
)[0]; )[0];
if (!latestTx) { if (!latestTx) {
return; // continue to the next group return; // continue to the next group
} }
@ -128,6 +128,7 @@ export const useHandlePaymentNotification = (address) => {
); );
}; };
}, [setLastEnteredTimestampPaymentEventFunc]); }, [setLastEnteredTimestampPaymentEventFunc]);
return { return {
latestTx, latestTx,
getNameOrAddressOfSenderMiddle, getNameOrAddressOfSenderMiddle,

View File

@ -5,6 +5,7 @@ interface NameListItem {
name: string; name: string;
address: string; address: string;
} }
export const useNameSearch = (value: string, limit = 20) => { export const useNameSearch = (value: string, limit = 20) => {
const [nameList, setNameList] = useState<NameListItem[]>([]); const [nameList, setNameList] = useState<NameListItem[]>([]);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
@ -48,6 +49,7 @@ export const useNameSearch = (value: string, limit = 20) => {
clearTimeout(handler); clearTimeout(handler);
}; };
}, [value, limit, checkIfNameExisits]); }, [value, limit, checkIfNameExisits]);
return { return {
isLoading, isLoading,
results: nameList, results: nameList,