diff --git a/lib/shared/dm-ops/dm-op-utils.js b/lib/shared/dm-ops/dm-op-utils.js --- a/lib/shared/dm-ops/dm-op-utils.js +++ b/lib/shared/dm-ops/dm-op-utils.js @@ -15,6 +15,7 @@ import { useLoggedInUserInfo } from '../../hooks/account-hooks.js'; import { useGetLatestMessageEdit } from '../../hooks/latest-message-edit.js'; import { mergeUpdatesWithMessageInfos } from '../../reducers/message-reducer.js'; +import { getAllPeerUserIDAndDeviceIDs } from '../../selectors/user-selectors.js'; import type { CreateThickRawThreadInfoInput, DMAddMembersOperation, @@ -120,58 +121,64 @@ | OutboundDMOperationSpecification | InboundDMOperationSpecification; -async function createMessagesToPeersFromDMOp( +function useCreateMessagesToPeersFromDMOp(): ( operation: DMOperation, recipients: OutboundDMOperationSpecificationRecipients, - allPeerUserIDAndDeviceIDs: $ReadOnlyArray<{ - +userID: string, - +deviceID: string, - }>, - utilities: ProcessDMOperationUtilities, -): Promise<$ReadOnlyArray> { - const { viewerID, threadInfos } = utilities; - if (!viewerID) { - return []; - } +) => Promise<$ReadOnlyArray> { + const allPeerUserIDAndDeviceIDs = useSelector(getAllPeerUserIDAndDeviceIDs); + const utilities = useSendDMOperationUtils(); - let peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs; - if (recipients.type === 'self_devices') { - peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter( - peer => peer.userID === viewerID, - ); - } else if (recipients.type === 'some_users') { - const userIDs = new Set(recipients.userIDs); - peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => - userIDs.has(peer.userID), - ); - } else if (recipients.type === 'all_thread_members') { - const { threadID } = recipients; - if (!threadInfos[threadID]) { - console.log( - `all_thread_members called for threadID ${threadID}, which is ` + - 'missing from the ThreadStore. if sending a message soon after ' + - 'thread creation, consider some_users instead', + return React.useCallback( + async ( + operation: DMOperation, + recipients: OutboundDMOperationSpecificationRecipients, + ): Promise<$ReadOnlyArray> => { + const { viewerID, threadInfos } = utilities; + if (!viewerID) { + return []; + } + + let peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs; + if (recipients.type === 'self_devices') { + peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter( + peer => peer.userID === viewerID, + ); + } else if (recipients.type === 'some_users') { + const userIDs = new Set(recipients.userIDs); + peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => + userIDs.has(peer.userID), + ); + } else if (recipients.type === 'all_thread_members') { + const { threadID } = recipients; + if (!threadInfos[threadID]) { + console.log( + `all_thread_members called for threadID ${threadID}, which is ` + + 'missing from the ThreadStore. if sending a message soon after ' + + 'thread creation, consider some_users instead', + ); + } + const members = threadInfos[recipients.threadID]?.members ?? []; + const memberIDs = members.map(member => member.id); + + const userIDs = new Set(memberIDs); + peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => + userIDs.has(peer.userID), + ); + } else if (recipients.type === 'some_devices') { + const deviceIDs = new Set(recipients.deviceIDs); + peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => + deviceIDs.has(peer.deviceID), + ); + } + + const thisDeviceID = await getContentSigningKey(); + const targetPeers = peerUserIDAndDeviceIDs.filter( + peer => peer.deviceID !== thisDeviceID, ); - } - const members = threadInfos[recipients.threadID]?.members ?? []; - const memberIDs = members.map(member => member.id); - - const userIDs = new Set(memberIDs); - peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => - userIDs.has(peer.userID), - ); - } else if (recipients.type === 'some_devices') { - const deviceIDs = new Set(recipients.deviceIDs); - peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => - deviceIDs.has(peer.deviceID), - ); - } - - const thisDeviceID = await getContentSigningKey(); - const targetPeers = peerUserIDAndDeviceIDs.filter( - peer => peer.deviceID !== thisDeviceID, + return generateMessagesToPeers(operation, targetPeers); + }, + [allPeerUserIDAndDeviceIDs, utilities], ); - return generateMessagesToPeers(operation, targetPeers); } function getCreateThickRawThreadInfoInputFromThreadInfo( @@ -417,7 +424,7 @@ } export { - createMessagesToPeersFromDMOp, + useCreateMessagesToPeersFromDMOp, useAddDMThreadMembers, getCreateThickRawThreadInfoInputFromThreadInfo, getThreadUpdatesForNewMessages, diff --git a/lib/shared/dm-ops/process-dm-ops.js b/lib/shared/dm-ops/process-dm-ops.js --- a/lib/shared/dm-ops/process-dm-ops.js +++ b/lib/shared/dm-ops/process-dm-ops.js @@ -8,7 +8,7 @@ import { type OutboundDMOperationSpecification, type DMOperationSpecification, - createMessagesToPeersFromDMOp, + useCreateMessagesToPeersFromDMOp, dmOperationSpecificationTypes, type OutboundComposableDMOperationSpecification, getThreadUpdatesForNewMessages, @@ -18,7 +18,6 @@ import { useProcessBlobHolders } from '../../actions/holder-actions.js'; import { processNewUserIDsActionType } from '../../actions/user-actions.js'; import { useDispatchWithMetadata } from '../../hooks/ops-hooks.js'; -import { getAllPeerUserIDAndDeviceIDs } from '../../selectors/user-selectors.js'; import { usePeerToPeerCommunication, type ProcessOutboundP2PMessagesResult, @@ -40,8 +39,8 @@ ) => Promise { const baseUtilities = useSendDMOperationUtils(); const dispatchWithMetadata = useDispatchWithMetadata(); - const allPeerUserIDAndDeviceIDs = useSelector(getAllPeerUserIDAndDeviceIDs); const processBlobHolders = useProcessBlobHolders(); + const createMessagesToPeersFromDMOp = useCreateMessagesToPeersFromDMOp(); const dispatch = useDispatch(); @@ -69,8 +68,6 @@ outboundP2PMessages = await createMessagesToPeersFromDMOp( dmOp, dmOperationSpecification.recipients, - allPeerUserIDAndDeviceIDs, - utilities, ); } @@ -250,10 +247,10 @@ }, [ baseUtilities, + processBlobHolders, dispatchWithMetadata, - allPeerUserIDAndDeviceIDs, + createMessagesToPeersFromDMOp, dispatch, - processBlobHolders, ], ); } @@ -279,10 +276,10 @@ ) => Promise { const { getDMOpsSendingPromise } = usePeerToPeerCommunication(); const dispatchWithMetadata = useDispatchWithMetadata(); - const allPeerUserIDAndDeviceIDs = useSelector(getAllPeerUserIDAndDeviceIDs); const baseUtilities = useSendDMOperationUtils(); const { processOutboundMessages } = usePeerToPeerCommunication(); const localMessageInfos = useSelector(state => state.messageStore.local); + const createMessagesToPeersFromDMOp = useCreateMessagesToPeersFromDMOp(); return React.useCallback( async ( @@ -329,8 +326,6 @@ const outboundP2PMessages = await createMessagesToPeersFromDMOp( op, recipients, - allPeerUserIDAndDeviceIDs, - utilities, ); const spec = dmOpSpecs[op.type]; @@ -384,12 +379,12 @@ } }, [ - allPeerUserIDAndDeviceIDs, - dispatchWithMetadata, + baseUtilities, getDMOpsSendingPromise, localMessageInfos, + createMessagesToPeersFromDMOp, + dispatchWithMetadata, processOutboundMessages, - baseUtilities, ], ); }