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 @@ -107,7 +107,8 @@ | InboundDMOperationSpecification; async function createMessagesToPeersFromDMOp( - operation: OutboundDMOperationSpecification, + operation: DMOperation, + recipients: OutboundDMOperationSpecificationRecipients, allPeerUserIDAndDeviceIDs: $ReadOnlyArray<{ +userID: string, +deviceID: string, @@ -120,25 +121,25 @@ } let peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs; - if (operation.recipients.type === 'self_devices') { + if (recipients.type === 'self_devices') { peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter( peer => peer.userID === currentUserInfo.id, ); - } else if (operation.recipients.type === 'some_users') { - const userIDs = new Set(operation.recipients.userIDs); + } else if (recipients.type === 'some_users') { + const userIDs = new Set(recipients.userIDs); peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => userIDs.has(peer.userID), ); - } else if (operation.recipients.type === 'all_thread_members') { - const members = threadInfos[operation.recipients.threadID]?.members ?? []; + } else if (recipients.type === 'all_thread_members') { + 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 (operation.recipients.type === 'some_devices') { - const deviceIDs = new Set(operation.recipients.deviceIDs); + } else if (recipients.type === 'some_devices') { + const deviceIDs = new Set(recipients.deviceIDs); peerUserIDAndDeviceIDs = allPeerUserIDAndDeviceIDs.filter(peer => deviceIDs.has(peer.deviceID), ); @@ -148,7 +149,7 @@ const targetPeers = peerUserIDAndDeviceIDs.filter( peer => peer.deviceID !== thisDeviceID, ); - return generateMessagesToPeers(operation.op, targetPeers); + return generateMessagesToPeers(operation, targetPeers); } function getCreateThickRawThreadInfoInputFromThreadInfo( 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 @@ -5,14 +5,14 @@ import * as React from 'react'; import uuid from 'uuid'; +import type { ProcessDMOperationUtilities } from './dm-op-spec.js'; import { dmOpSpecs } from './dm-op-specs.js'; -import type { - OutboundDMOperationSpecification, - DMOperationSpecification, -} from './dm-op-utils.js'; import { + type OutboundDMOperationSpecification, + type DMOperationSpecification, createMessagesToPeersFromDMOp, dmOperationSpecificationTypes, + type OutboundComposableDMOperationSpecification, } from './dm-op-utils.js'; import { processNewUserIDsActionType } from '../../actions/user-actions.js'; import { useLoggedInUserInfo } from '../../hooks/account-hooks.js'; @@ -40,21 +40,24 @@ import { messageSpecs } from '../messages/message-specs.js'; import { updateSpecs } from '../updates/update-specs.js'; -function useProcessDMOperation(): ( - dmOperationSpecification: DMOperationSpecification, - dmOpID: ?string, -) => Promise { +function useSendDMOperationUtils(): ProcessDMOperationUtilities { const fetchMessage = useGetLatestMessageEdit(); const threadInfos = useSelector(state => state.threadStore.threadInfos); - - const utilities = React.useMemo( + return React.useMemo( () => ({ fetchMessage, threadInfos, }), [fetchMessage, threadInfos], ); +} +function useProcessDMOperation(): ( + dmOperationSpecification: DMOperationSpecification, + dmOpID: ?string, +) => Promise { + const threadInfos = useSelector(state => state.threadStore.threadInfos); + const utilities = useSendDMOperationUtils(); const dispatchWithMetadata = useDispatchWithMetadata(); const loggedInUserInfo = useLoggedInUserInfo(); const viewerID = loggedInUserInfo?.id; @@ -80,7 +83,8 @@ dmOperationSpecification.type === dmOperationSpecificationTypes.OUTBOUND ) { outboundP2PMessages = await createMessagesToPeersFromDMOp( - dmOperationSpecification, + dmOp, + dmOperationSpecification.recipients, allPeerUserIDAndDeviceIDs, currentUserInfo, threadInfos, @@ -374,8 +378,68 @@ ); } +function useSendComposableDMOperation(): ( + dmOperationSpecification: OutboundComposableDMOperationSpecification, +) => Promise<$ReadOnlyArray> { + const threadInfos = useSelector(state => state.threadStore.threadInfos); + const { getDMOpsSendingPromise } = usePeerToPeerCommunication(); + const dispatchWithMetadata = useDispatchWithMetadata(); + const allPeerUserIDAndDeviceIDs = useSelector(getAllPeerUserIDAndDeviceIDs); + const currentUserInfo = useSelector(state => state.currentUserInfo); + const utilities = useSendDMOperationUtils(); + + return React.useCallback( + async ( + dmOperationSpecification: OutboundComposableDMOperationSpecification, + ): Promise<$ReadOnlyArray> => { + const { promise, dmOpID } = getDMOpsSendingPromise(); + + const { op, composableMessageID, recipients } = dmOperationSpecification; + + const outboundP2PMessages = await createMessagesToPeersFromDMOp( + op, + recipients, + allPeerUserIDAndDeviceIDs, + currentUserInfo, + threadInfos, + ); + + const notificationsCreationData = await dmOpSpecs[ + op.type + ].notificationsCreationData?.(op, utilities); + + dispatchWithMetadata( + { + type: processDMOpsActionType, + payload: { + rawMessageInfos: [], + updateInfos: [], + outboundP2PMessages, + composableMessageID, + notificationsCreationData, + }, + }, + { + dmOpID, + }, + ); + + return promise; + }, + [ + allPeerUserIDAndDeviceIDs, + currentUserInfo, + dispatchWithMetadata, + getDMOpsSendingPromise, + threadInfos, + utilities, + ], + ); +} + export { useProcessDMOperation, useProcessAndSendDMOperation, useRetrySendDMOperation, + useSendComposableDMOperation, };