From e9150090ff93e53af260d9fa25f371297cc92e90 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Wed, 28 Aug 2024 16:51:42 +0200 Subject: [PATCH] clean ups, and added DELETE_COMMENT --- src/libs/Network/SequentialQueue.ts | 7 ++++-- src/libs/actions/App.ts | 4 +--- src/libs/actions/PersistedRequests.ts | 13 ++++++++--- src/libs/actions/Report.ts | 33 ++++++++++++++++++++++++++- src/types/onyx/Request.ts | 17 +++++++++----- 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/libs/Network/SequentialQueue.ts b/src/libs/Network/SequentialQueue.ts index 9fd65602eca2..2bbaa4c34928 100644 --- a/src/libs/Network/SequentialQueue.ts +++ b/src/libs/Network/SequentialQueue.ts @@ -199,11 +199,14 @@ function push(newRequest: OnyxRequest) { const {checkAndFixConflictingRequest} = newRequest; if (checkAndFixConflictingRequest) { - const {conflictAction} = checkAndFixConflictingRequest(requests, newRequest); + const {conflictAction} = checkAndFixConflictingRequest(requests); + + // Don't try to serialize conflict resolution functions + delete newRequest.checkAndFixConflictingRequest; if (conflictAction.type === 'save') { PersistedRequests.save(newRequest); - } else { + } else if (conflictAction.type === 'update') { PersistedRequests.update(conflictAction.index, newRequest); } } else { diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index 7f7fc95ae5d4..65998c1f1b48 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -275,11 +275,10 @@ function reconnectApp(updateIDFrom: OnyxEntry = 0) { } API.write(WRITE_COMMANDS.RECONNECT_APP, params, getOnyxDataForOpenOrReconnect(), { - checkAndFixConflictingRequest: (persistedRequests, newRequest) => { + checkAndFixConflictingRequest: (persistedRequests) => { const index = persistedRequests.findIndex((request) => request.command === WRITE_COMMANDS.RECONNECT_APP); if (index === -1) { return { - request: newRequest, conflictAction: { type: 'save', }, @@ -287,7 +286,6 @@ function reconnectApp(updateIDFrom: OnyxEntry = 0) { } return { - request: newRequest, conflictAction: { type: 'update', index, diff --git a/src/libs/actions/PersistedRequests.ts b/src/libs/actions/PersistedRequests.ts index 18d66ee9ccb7..892b4fe631cc 100644 --- a/src/libs/actions/PersistedRequests.ts +++ b/src/libs/actions/PersistedRequests.ts @@ -1,12 +1,10 @@ import isEqual from 'lodash/isEqual'; import Onyx from 'react-native-onyx'; -import {WRITE_COMMANDS} from '@libs/API/types'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Request} from '@src/types/onyx'; let persistedRequests: Request[] = []; -const keepLastInstance: string[] = [WRITE_COMMANDS.RECONNECT_APP]; Onyx.connect({ key: ONYXKEYS.PERSISTED_REQUESTS, @@ -50,6 +48,15 @@ function remove(requestToRemove: Request) { }); } +function bulkRemove(requestsToRemove: Request[]) { + if (requestsToRemove.length === 0) { + return; + } + const requests = persistedRequests.filter((request) => !requestsToRemove.includes(request)); + persistedRequests = requests; + Onyx.set(ONYXKEYS.PERSISTED_REQUESTS, requests); +} + function update(oldRequestIndex: number, newRequest: Request) { const requests = [...persistedRequests]; requests.splice(oldRequestIndex, 1, newRequest); @@ -61,4 +68,4 @@ function getAll(): Request[] { return persistedRequests; } -export {clear, save, getAll, remove, update, getLength}; +export {clear, save, getAll, remove, update, getLength, bulkRemove}; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 7eb7e01d6edd..f52e7322beb7 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -82,6 +82,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import {doesReportBelongToWorkspace} from '@libs/ReportUtils'; import shouldSkipDeepLinkNavigation from '@libs/shouldSkipDeepLinkNavigation'; import Visibility from '@libs/Visibility'; +import * as PersistedRequests from '@userActions/PersistedRequests'; import CONFIG from '@src/CONFIG'; import type {OnboardingPurposeType} from '@src/CONST'; import CONST from '@src/CONST'; @@ -1510,7 +1511,37 @@ function deleteReportComment(reportID: string, reportAction: ReportAction) { CachedPDFPaths.clearByKey(reportActionID); - API.write(WRITE_COMMANDS.DELETE_COMMENT, parameters, {optimisticData, successData, failureData}); + let shouldRequestHappen = true; + + API.write( + WRITE_COMMANDS.DELETE_COMMENT, + parameters, + {optimisticData, successData, failureData}, + { + checkAndFixConflictingRequest: (persistedRequests) => { + const conflictingCommands = ( + isDeletedParentAction ? [WRITE_COMMANDS.UPDATE_COMMENT] : [WRITE_COMMANDS.ADD_COMMENT, WRITE_COMMANDS.ADD_ATTACHMENT, WRITE_COMMANDS.UPDATE_COMMENT] + ) as string[]; + + const conflictingRequests = persistedRequests.filter((request) => conflictingCommands.includes(request.command) && request.data?.reportActionID === reportActionID); + shouldRequestHappen = conflictingRequests.some((request) => request.command !== WRITE_COMMANDS.UPDATE_COMMENT); + const hasConflict = conflictingRequests.length > 0; + + // Delete the conflicting requests + PersistedRequests.bulkRemove(conflictingRequests); + + conflictingRequests.forEach(() => { + Onyx.update(successData); + }); + + const mustSave = !(!shouldRequestHappen && hasConflict); + + return { + conflictAction: mustSave ? {type: 'save'} : {type: 'noAction'}, + }; + }, + }, + ); // if we are linking to the report action, and we are deleting it, and it's not a deleted parent action, // we should navigate to its report in order to not show not found page diff --git a/src/types/onyx/Request.ts b/src/types/onyx/Request.ts index 0b583422f738..fb1ee4885170 100644 --- a/src/types/onyx/Request.ts +++ b/src/types/onyx/Request.ts @@ -84,18 +84,23 @@ type ConflictRequestSave = { }; /** - * An object that has the request and the action to take in case of a conflict. + * Model of a conflict request that no need to be updated or saved, in the request queue. */ -type ConflictActionData = { +type ConflictRequestNoAction = { /** - * The request that is conflicting with the new request. + * The action to take in case of a conflict. */ - request: Request; + type: 'noAction'; +}; +/** + * An object that has the request and the action to take in case of a conflict. + */ +type ConflictActionData = { /** * The action to take in case of a conflict. */ - conflictAction: ConflictRequestUpdate | ConflictRequestSave; + conflictAction: ConflictRequestUpdate | ConflictRequestSave | ConflictRequestNoAction; }; /** @@ -106,7 +111,7 @@ type RequestConflictResolver = { /** * A function that checks if a new request conflicts with any existing requests in the queue. */ - checkAndFixConflictingRequest?: (persistedRequest: Request[], request: Request) => ConflictActionData; + checkAndFixConflictingRequest?: (persistedRequest: Request[]) => ConflictActionData; }; /**