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 @@ -12,6 +12,7 @@ pruneDMOpsQueueActionType, type QueuedDMOperations, queueDMOpsActionType, + reportUnshimmingOperationCompletedActionType, saveUnsupportedOperationActionType, } from '../types/dm-ops.js'; import type { BaseAction } from '../types/redux-types.js'; @@ -188,6 +189,23 @@ }, ], }; + } else if (action.type === reportUnshimmingOperationCompletedActionType) { + return { + store: { + ...store, + shimmedOperations: store.shimmedOperations.filter( + op => op.id !== action.payload.id, + ), + }, + operations: [ + { + type: 'remove_dm_operations', + payload: { + ids: [action.payload.id], + }, + }, + ], + }; } return { store, operations: [] }; } diff --git a/lib/shared/dm-ops/dm-ops-queue-handler.react.js b/lib/shared/dm-ops/dm-ops-queue-handler.react.js --- a/lib/shared/dm-ops/dm-ops-queue-handler.react.js +++ b/lib/shared/dm-ops/dm-ops-queue-handler.react.js @@ -16,6 +16,7 @@ clearQueuedMessageDMOpsActionType, clearQueuedThreadDMOpsActionType, pruneDMOpsQueueActionType, + reportUnshimmingOperationCompletedActionType, } from '../../types/dm-ops.js'; import type { DMOperation } from '../../types/dm-ops.js'; import type { BaseAction } from '../../types/redux-types.js'; @@ -271,6 +272,36 @@ } }, [dispatch, enqueue, queuedMembershipOperations, threadInfos]); + const shimmedOperations = useSelector( + state => state.queuedDMOperations.shimmedOperations, + ); + const unshimmingStarted = React.useRef<boolean>(false); + React.useEffect(() => { + if (unshimmingStarted.current || shimmedOperations.length === 0) { + return; + } + + // We never set it to false to make sure we're unshimming only once + unshimmingStarted.current = true; + for (const operation of shimmedOperations) { + enqueue([ + { + type: 'operation', + operation: operation.operation, + }, + { + type: 'action', + action: { + type: reportUnshimmingOperationCompletedActionType, + payload: { + id: operation.id, + }, + }, + }, + ]); + } + }, [enqueue, shimmedOperations]); + return null; } 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 @@ -592,6 +592,12 @@ +id: string, }; +export const reportUnshimmingOperationCompletedActionType = + 'REPORT_UNSHIMMING_OPERATION_COMPLETED'; +export type ReportUnshimmingOperationCompletedPayload = { + +id: string, +}; + export type OperationsQueue = $ReadOnlyArray<{ +operation: DMOperation, +timestamp: number, @@ -612,4 +618,5 @@ +[memberID: string]: OperationsQueue, }, }, + +shimmedOperations: $ReadOnlyArray<SaveUnsupportedOperationPayload>, }; 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 @@ -54,6 +54,7 @@ ClearQueuedEntryDMOpsPayload, ClearQueuedMembershipDMOpsPayload, SaveUnsupportedOperationPayload, + ReportUnshimmingOperationCompletedPayload, } from './dm-ops.js'; import type { DraftStore } from './draft-types.js'; import type { EnabledApps, SupportedApps } from './enabled-apps.js'; @@ -1686,6 +1687,10 @@ | { +type: 'SAVE_UNSUPPORTED_DM_OPERATION', +payload: SaveUnsupportedOperationPayload, + } + | { + +type: 'REPORT_UNSHIMMING_OPERATION_COMPLETED', + +payload: ReportUnshimmingOperationCompletedPayload, }, }>; diff --git a/lib/utils/reducers-utils.test.js b/lib/utils/reducers-utils.test.js --- a/lib/utils/reducers-utils.test.js +++ b/lib/utils/reducers-utils.test.js @@ -104,6 +104,7 @@ messageQueue: {}, entryQueue: {}, membershipQueue: {}, + shimmedOperations: [], }, holderStore: { storedHolders: {}, diff --git a/native/redux/default-state.js b/native/redux/default-state.js --- a/native/redux/default-state.js +++ b/native/redux/default-state.js @@ -104,6 +104,7 @@ messageQueue: {}, entryQueue: {}, membershipQueue: {}, + shimmedOperations: [], }, holderStore: { storedHolders: {}, diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -1506,6 +1506,16 @@ [messageTypes.MULTIMEDIA], handleReduxMigrationFailure, ): MigrationFunction<NavInfo, AppState>), + [86]: (async (state: AppState) => ({ + state: { + ...state, + queuedDMOperations: { + ...state.queuedDMOperations, + shimmedOperations: [], + }, + }, + ops: {}, + }): MigrationFunction<NavInfo, AppState>), }); // NOTE: renaming this object, and especially the `version` property @@ -1516,7 +1526,7 @@ storage: AsyncStorage, blacklist: persistBlacklist, debug: __DEV__, - version: 85, + version: 86, transforms: [ messageStoreMessagesBlocklistTransform, reportStoreTransform, diff --git a/web/redux/default-state.js b/web/redux/default-state.js --- a/web/redux/default-state.js +++ b/web/redux/default-state.js @@ -100,6 +100,7 @@ messageQueue: {}, entryQueue: {}, membershipQueue: {}, + shimmedOperations: [], }, holderStore: { storedHolders: {}, diff --git a/web/redux/persist-constants.js b/web/redux/persist-constants.js --- a/web/redux/persist-constants.js +++ b/web/redux/persist-constants.js @@ -3,6 +3,6 @@ const rootKey = 'root'; const rootKeyPrefix = 'persist:'; const completeRootKey = `${rootKeyPrefix}${rootKey}`; -const storeVersion = 85; +const storeVersion = 86; export { rootKey, rootKeyPrefix, completeRootKey, storeVersion }; diff --git a/web/redux/persist.js b/web/redux/persist.js --- a/web/redux/persist.js +++ b/web/redux/persist.js @@ -722,6 +722,16 @@ state, ops: {}, }): MigrationFunction<WebNavInfo, AppState>), + [86]: (async (state: AppState) => ({ + state: { + ...state, + queuedDMOperations: { + ...state.queuedDMOperations, + shimmedOperations: [], + }, + }, + ops: {}, + }): MigrationFunction<WebNavInfo, AppState>), }; const persistConfig: PersistConfig = {