diff --git a/lib/reducers/dm-operations-queue-reducer.js b/lib/reducers/dm-operations-queue-reducer.js --- a/lib/reducers/dm-operations-queue-reducer.js +++ b/lib/reducers/dm-operations-queue-reducer.js @@ -3,6 +3,9 @@ import _mapValues from 'lodash/fp/mapValues.js'; import { + clearQueuedEntryDMOpsActionType, + clearQueuedMembershipDMOpsActionType, + clearQueuedMessageDMOpsActionType, clearQueuedThreadDMOpsActionType, type OperationsQueue, pruneDMOpsQueueActionType, @@ -16,15 +19,59 @@ action: BaseAction, ): QueuedDMOperations { if (action.type === queueDMOpsActionType) { - const { threadID, operation, timestamp } = action.payload; + const { condition, operation, timestamp } = action.payload; + + if (condition.type === 'thread') { + return { + ...store, + threadQueue: { + ...store.threadQueue, + [condition.threadID]: [ + ...(store.threadQueue[condition.threadID] ?? []), + { operation, timestamp }, + ], + }, + }; + } + + if (condition.type === 'entry') { + return { + ...store, + entryQueue: { + ...store.entryQueue, + [condition.entryID]: [ + ...(store.entryQueue[condition.entryID] ?? []), + { operation, timestamp }, + ], + }, + }; + } + + if (condition.type === 'message') { + return { + ...store, + messageQueue: { + ...store.messageQueue, + [condition.messageID]: [ + ...(store.messageQueue[condition.messageID] ?? []), + { operation, timestamp }, + ], + }, + }; + } + return { ...store, - threadQueue: { - ...store.threadQueue, - [threadID]: [ - ...(store.threadQueue[threadID] ?? []), - { operation, timestamp }, - ], + membershipQueue: { + ...store.membershipQueue, + [condition.threadID]: { + ...(store.membershipQueue[condition.threadID] ?? {}), + [condition.userID]: [ + ...(store.membershipQueue[condition.threadID]?.[condition.userID] ?? + []), + { operation, timestamp }, + ], + }, }, }; } else if (action.type === pruneDMOpsQueueActionType) { @@ -54,6 +101,43 @@ ...store, threadQueue, }; + } else if (action.type === clearQueuedMessageDMOpsActionType) { + const { [action.payload.messageID]: removed, ...messageQueue } = + store.messageQueue; + return { + ...store, + messageQueue, + }; + } else if (action.type === clearQueuedEntryDMOpsActionType) { + const { [action.payload.entryID]: removed, ...entryQueue } = + store.entryQueue; + return { + ...store, + entryQueue, + }; + } else if (action.type === clearQueuedMembershipDMOpsActionType) { + const threadQueue = store.membershipQueue[action.payload.threadID]; + if (!threadQueue) { + return store; + } + + const { [action.payload.userID]: removed, ...queue } = threadQueue; + if (Object.keys(queue).length === 0) { + const { [action.payload.threadID]: removedThread, ...membershipQueue } = + store.membershipQueue; + return { + ...store, + membershipQueue, + }; + } + + return { + ...store, + membershipQueue: { + ...store.membershipQueue, + [action.payload.userID]: queue, + }, + }; } return store; } 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 @@ -154,8 +154,11 @@ type: queueDMOpsActionType, payload: { operation: dmOp, - threadID: processingCheckResult.reason.threadID, timestamp: Date.now(), + condition: { + type: 'thread', + threadID: processingCheckResult.reason.threadID, + }, }, }, dispatchMetadata, 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 @@ -507,8 +507,25 @@ export const queueDMOpsActionType = 'QUEUE_DM_OPS'; export type QueueDMOpsPayload = { +operation: DMOperation, - +threadID: string, +timestamp: number, + +condition: + | { + +type: 'thread', + +threadID: string, + } + | { + +type: 'entry', + +entryID: string, + } + | { + +type: 'message', + +messageID: string, + } + | { + +type: 'membership', + +threadID: string, + +userID: string, + }, }; export const pruneDMOpsQueueActionType = 'PRUNE_DM_OPS_QUEUE'; @@ -521,6 +538,23 @@ +threadID: string, }; +export const clearQueuedMessageDMOpsActionType = 'CLEAR_QUEUED_MESSAGE_DM_OPS'; +export type ClearQueuedMessageDMOpsPayload = { + +messageID: string, +}; + +export const clearQueuedEntryDMOpsActionType = 'CLEAR_QUEUED_ENTRY_DM_OPS'; +export type ClearQueuedEntryDMOpsPayload = { + +entryID: string, +}; + +export const clearQueuedMembershipDMOpsActionType = + 'CLEAR_QUEUED_MEMBERSHIP_DM_OPS'; +export type ClearQueuedMembershipDMOpsPayload = { + +threadID: string, + +userID: string, +}; + export type OperationsQueue = $ReadOnlyArray<{ +operation: DMOperation, +timestamp: number, diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -47,6 +47,9 @@ QueueDMOpsPayload, PruneDMOpsQueuePayload, ClearQueuedThreadDMOpsPayload, + ClearQueuedMessageDMOpsPayload, + ClearQueuedEntryDMOpsPayload, + ClearQueuedMembershipDMOpsPayload, } from './dm-ops.js'; import type { DraftStore } from './draft-types.js'; import type { EnabledApps, SupportedApps } from './enabled-apps.js'; @@ -1591,6 +1594,18 @@ | { +type: 'CLEAR_QUEUED_THREAD_DM_OPS', +payload: ClearQueuedThreadDMOpsPayload, + } + | { + +type: 'CLEAR_QUEUED_MESSAGE_DM_OPS', + +payload: ClearQueuedMessageDMOpsPayload, + } + | { + +type: 'CLEAR_QUEUED_ENTRY_DM_OPS', + +payload: ClearQueuedEntryDMOpsPayload, + } + | { + +type: 'CLEAR_QUEUED_MEMBERSHIP_DM_OPS', + +payload: ClearQueuedMembershipDMOpsPayload, }, }>;