diff --git a/lib/shared/dm-ops/add-members-spec.js b/lib/shared/dm-ops/add-members-spec.js --- a/lib/shared/dm-ops/add-members-spec.js +++ b/lib/shared/dm-ops/add-members-spec.js @@ -170,6 +170,16 @@ ); return { rawMessageInfos, updateInfos }; }, + canBeApplied( + dmOperation: DMAddMembersOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return ( + !!utilities.threadInfos[dmOperation.existingThreadDetails.threadID] || + dmOperation.addedUserIDs.includes(viewerID) + ); + }, }); export { addMembersSpec, createAddNewMembersResults }; diff --git a/lib/shared/dm-ops/change-thread-settings-spec.js b/lib/shared/dm-ops/change-thread-settings-spec.js --- a/lib/shared/dm-ops/change-thread-settings-spec.js +++ b/lib/shared/dm-ops/change-thread-settings-spec.js @@ -1,8 +1,12 @@ // @flow +import invariant from 'invariant'; import uuid from 'uuid'; -import { createAddNewMembersResults } from './add-members-spec.js'; +import { + addMembersSpec, + createAddNewMembersResults, +} from './add-members-spec.js'; import type { DMOperationSpec, ProcessDMOperationUtilities, @@ -17,6 +21,25 @@ import type { ClientUpdateInfo } from '../../types/update-types.js'; import { values } from '../../utils/objects.js'; +function createAddMembersOperation( + dmOperation: DMChangeThreadSettingsOperation, +) { + const { editorID, time, messageIDsPrefix, changes, existingThreadDetails } = + dmOperation; + const newMemberIDs = + changes.newMemberIDs && changes.newMemberIDs.length > 0 + ? [...new Set(changes.newMemberIDs)] + : []; + return { + type: 'add_members', + editorID, + time, + messageID: `${messageIDsPrefix}/add_members`, + addedUserIDs: newMemberIDs, + existingThreadDetails, + }; +} + const changeThreadSettingsSpec: DMOperationSpec = Object.freeze({ processDMOperation: async ( @@ -41,34 +64,15 @@ } = changes; const threadID = existingThreadDetails.threadID; - const newMemberIDs = - changes.newMemberIDs && changes.newMemberIDs.length > 0 - ? [...new Set(changes.newMemberIDs)] - : null; - let threadInfoToUpdate: ?(RawThreadInfo | LegacyRawThreadInfo) = utilities.threadInfos[threadID]; - if (!threadInfoToUpdate && !newMemberIDs?.includes(viewerID)) { - // We can't perform this operation now. It should be queued for later. - return { - rawMessageInfos: [], - updateInfos: [], - }; - } - const updateInfos: Array = []; const rawMessageInfos: Array = []; - if (newMemberIDs) { + if (changes.newMemberIDs && changes.newMemberIDs.length > 0) { + const addMembersOperation = createAddMembersOperation(dmOperation); const addMembersResult = createAddNewMembersResults( - { - type: 'add_members', - editorID, - time, - messageID: `${messageIDsPrefix}/add_members`, - addedUserIDs: newMemberIDs, - existingThreadDetails, - }, + addMembersOperation, viewerID, utilities, ); @@ -79,13 +83,7 @@ rawMessageInfos.push(...addMembersResult.rawMessageInfos); } - if (!threadInfoToUpdate || !threadInfoToUpdate.thick) { - // We can't perform this operation now. It should be queued for later. - return { - rawMessageInfos: [], - updateInfos: [], - }; - } + invariant(threadInfoToUpdate?.thick, 'Thread should be thick'); const changedFields: { [string]: string | number } = {}; @@ -168,6 +166,17 @@ updateInfos, }; }, + canBeApplied( + dmOperation: DMChangeThreadSettingsOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return addMembersSpec.canBeApplied( + createAddMembersOperation(dmOperation), + viewerID, + utilities, + ); + }, }); export { changeThreadSettingsSpec }; diff --git a/lib/shared/dm-ops/create-sidebar-spec.js b/lib/shared/dm-ops/create-sidebar-spec.js --- a/lib/shared/dm-ops/create-sidebar-spec.js +++ b/lib/shared/dm-ops/create-sidebar-spec.js @@ -105,6 +105,9 @@ updateInfos: [threadJoinUpdateInfo], }; }, + canBeApplied() { + return true; + }, }); export { createSidebarSpec }; diff --git a/lib/shared/dm-ops/create-thread-spec.js b/lib/shared/dm-ops/create-thread-spec.js --- a/lib/shared/dm-ops/create-thread-spec.js +++ b/lib/shared/dm-ops/create-thread-spec.js @@ -185,6 +185,9 @@ updateInfos: [threadJoinUpdateInfo], }; }, + canBeApplied() { + return true; + }, }); export { diff --git a/lib/shared/dm-ops/dm-op-spec.js b/lib/shared/dm-ops/dm-op-spec.js --- a/lib/shared/dm-ops/dm-op-spec.js +++ b/lib/shared/dm-ops/dm-op-spec.js @@ -16,4 +16,9 @@ viewerID: string, utilities: ProcessDMOperationUtilities, ) => Promise, + +canBeApplied: ( + dmOp: DMOp, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) => boolean, }; diff --git a/lib/shared/dm-ops/join-thread-spec.js b/lib/shared/dm-ops/join-thread-spec.js --- a/lib/shared/dm-ops/join-thread-spec.js +++ b/lib/shared/dm-ops/join-thread-spec.js @@ -18,10 +18,7 @@ messageTruncationStatus, type RawMessageInfo, } from '../../types/message-types.js'; -import { - minimallyEncodeMemberInfo, - type ThickRawThreadInfo, -} from '../../types/minimally-encoded-thread-permissions-types.js'; +import { minimallyEncodeMemberInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; import { joinThreadSubscription } from '../../types/subscription-types.js'; import type { ThickMemberInfo } from '../../types/thread-types.js'; import { updateTypes } from '../../types/update-types-enum.js'; @@ -37,9 +34,9 @@ ) => { const { editorID, time, messageID, existingThreadDetails } = dmOperation; - const currentThreadInfoOptional = + const currentThreadInfo = utilities.threadInfos[existingThreadDetails.threadID]; - if (userIsMember(currentThreadInfoOptional, editorID)) { + if (userIsMember(currentThreadInfo, editorID)) { return { rawMessageInfos: [], updateInfos: [], @@ -89,14 +86,7 @@ updateInfos.push(repliesCountUpdate); } } else { - if (!currentThreadInfoOptional || !currentThreadInfoOptional.thick) { - // We can't perform this operation now. It should be queued for later. - return { - rawMessageInfos: [], - updateInfos: [], - }; - } - const currentThreadInfo: ThickRawThreadInfo = currentThreadInfoOptional; + invariant(currentThreadInfo.thick, 'Thread should be thick'); rawMessageInfos.push(joinThreadMessage); if (!userIsMember(currentThreadInfo, editorID)) { @@ -148,6 +138,13 @@ updateInfos, }; }, + canBeApplied( + dmOperation: DMJoinThreadOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return !!utilities.threadInfos[dmOperation.existingThreadDetails.threadID]; + }, }); export { joinThreadSpec }; diff --git a/lib/shared/dm-ops/leave-thread-spec.js b/lib/shared/dm-ops/leave-thread-spec.js --- a/lib/shared/dm-ops/leave-thread-spec.js +++ b/lib/shared/dm-ops/leave-thread-spec.js @@ -1,5 +1,6 @@ // @flow +import invariant from 'invariant'; import uuid from 'uuid'; import type { @@ -9,7 +10,6 @@ import { createUpdateUnreadCountUpdate } from './dm-op-utils.js'; import type { DMLeaveThreadOperation } from '../../types/dm-ops.js'; import { messageTypes } from '../../types/message-types-enum.js'; -import type { ThickRawThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; import { threadTypes } from '../../types/thread-types-enum.js'; import { updateTypes } from '../../types/update-types-enum.js'; import type { ClientUpdateInfo } from '../../types/update-types.js'; @@ -23,15 +23,8 @@ ) => { const { editorID, time, messageID, threadID } = dmOperation; - const threadInfoOptional = utilities.threadInfos[threadID]; - if (!threadInfoOptional || !threadInfoOptional.thick) { - // We can't perform this operation now. It should be queued for later. - return { - rawMessageInfos: [], - updateInfos: [], - }; - } - const threadInfo: ThickRawThreadInfo = threadInfoOptional; + const threadInfo = utilities.threadInfos[threadID]; + invariant(threadInfo.thick, 'Thread should be thick'); const leaveThreadMessage = { type: messageTypes.LEAVE_THREAD, @@ -86,6 +79,13 @@ updateInfos, }; }, + canBeApplied( + dmOperation: DMLeaveThreadOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return !!utilities.threadInfos[dmOperation.threadID]; + }, }); export { leaveThreadSpec }; 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 @@ -32,6 +32,10 @@ console.log('ignored DMOperation because logged out'); return; } + if (!dmOpSpecs[dmOp.type].canBeApplied(dmOp, viewerID, utilities)) { + // TODO queue for later + return; + } const { rawMessageInfos, updateInfos } = await dmOpSpecs[ dmOp.type ].processDMOperation(dmOp, viewerID, utilities); diff --git a/lib/shared/dm-ops/remove-members-spec.js b/lib/shared/dm-ops/remove-members-spec.js --- a/lib/shared/dm-ops/remove-members-spec.js +++ b/lib/shared/dm-ops/remove-members-spec.js @@ -1,5 +1,6 @@ // @flow +import invariant from 'invariant'; import uuid from 'uuid'; import type { @@ -9,7 +10,6 @@ import { createUpdateUnreadCountUpdate } from './dm-op-utils.js'; import type { DMRemoveMembersOperation } from '../../types/dm-ops.js'; import { messageTypes } from '../../types/message-types-enum.js'; -import type { ThickRawThreadInfo } from '../../types/minimally-encoded-thread-permissions-types.js'; import { threadTypes } from '../../types/thread-types-enum.js'; import { updateTypes } from '../../types/update-types-enum.js'; import type { ClientUpdateInfo } from '../../types/update-types.js'; @@ -24,15 +24,8 @@ const { editorID, time, messageID, threadID, removedUserIDs } = dmOperation; - const threadInfoOptional = utilities.threadInfos[threadID]; - if (!threadInfoOptional || !threadInfoOptional.thick) { - // We can't perform this operation now. It should be queued for later. - return { - rawMessageInfos: [], - updateInfos: [], - }; - } - const threadInfo: ThickRawThreadInfo = threadInfoOptional; + const threadInfo = utilities.threadInfos[threadID]; + invariant(threadInfo.thick, 'Thread should be thick'); const removeMembersMessage = { type: messageTypes.REMOVE_MEMBERS, @@ -90,6 +83,13 @@ updateInfos, }; }, + canBeApplied( + dmOperation: DMRemoveMembersOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return !!utilities.threadInfos[dmOperation.threadID]; + }, }); export { removeMembersSpec }; diff --git a/lib/shared/dm-ops/send-edit-message-spec.js b/lib/shared/dm-ops/send-edit-message-spec.js --- a/lib/shared/dm-ops/send-edit-message-spec.js +++ b/lib/shared/dm-ops/send-edit-message-spec.js @@ -42,19 +42,24 @@ }); } const threadInfo = utilities.threadInfos[threadID]; - if (threadInfo) { - const repliesCountUpdate = createUpdateUnreadCountUpdate(threadInfo, [ - editMessage, - ]); - if (repliesCountUpdate) { - updateInfos.push(repliesCountUpdate); - } + const repliesCountUpdate = createUpdateUnreadCountUpdate(threadInfo, [ + editMessage, + ]); + if (repliesCountUpdate) { + updateInfos.push(repliesCountUpdate); } return { rawMessageInfos: [editMessage], updateInfos, }; }, + canBeApplied( + dmOperation: DMSendEditMessageOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return !!utilities.threadInfos[dmOperation.threadID]; + }, }); export { sendEditMessageSpec }; diff --git a/lib/shared/dm-ops/send-reaction-message-spec.js b/lib/shared/dm-ops/send-reaction-message-spec.js --- a/lib/shared/dm-ops/send-reaction-message-spec.js +++ b/lib/shared/dm-ops/send-reaction-message-spec.js @@ -50,19 +50,24 @@ }); } const threadInfo = utilities.threadInfos[threadID]; - if (threadInfo) { - const repliesCountUpdate = createUpdateUnreadCountUpdate(threadInfo, [ - reactionMessage, - ]); - if (repliesCountUpdate) { - updateInfos.push(repliesCountUpdate); - } + const repliesCountUpdate = createUpdateUnreadCountUpdate(threadInfo, [ + reactionMessage, + ]); + if (repliesCountUpdate) { + updateInfos.push(repliesCountUpdate); } return { rawMessageInfos: [reactionMessage], updateInfos, }; }, + canBeApplied( + dmOperation: DMSendReactionMessageOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return !!utilities.threadInfos[dmOperation.threadID]; + }, }); export { sendReactionMessageSpec }; diff --git a/lib/shared/dm-ops/send-text-message-spec.js b/lib/shared/dm-ops/send-text-message-spec.js --- a/lib/shared/dm-ops/send-text-message-spec.js +++ b/lib/shared/dm-ops/send-text-message-spec.js @@ -39,19 +39,24 @@ }); } const threadInfo = utilities.threadInfos[threadID]; - if (threadInfo) { - const repliesCountUpdate = createUpdateUnreadCountUpdate(threadInfo, [ - textMessage, - ]); - if (repliesCountUpdate) { - updateInfos.push(repliesCountUpdate); - } + const repliesCountUpdate = createUpdateUnreadCountUpdate(threadInfo, [ + textMessage, + ]); + if (repliesCountUpdate) { + updateInfos.push(repliesCountUpdate); } return { rawMessageInfos: [textMessage], updateInfos, }; }, + canBeApplied( + dmOperation: DMSendTextMessageOperation, + viewerID: string, + utilities: ProcessDMOperationUtilities, + ) { + return !!utilities.threadInfos[dmOperation.threadID]; + }, }); export { sendTextMessageSpec }; diff --git a/lib/types/dm-ops.js b/lib/types/dm-ops.js --- a/lib/types/dm-ops.js +++ b/lib/types/dm-ops.js @@ -286,8 +286,8 @@ ]); export type DMOperationResult = { - rawMessageInfos: Array, - updateInfos: Array, + +rawMessageInfos: Array, + +updateInfos: Array, }; export const processDMOpsActionType = 'PROCESS_DM_OPS';