Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Recreate a receipt #54358

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
65 changes: 55 additions & 10 deletions src/libs/HttpUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,26 +150,71 @@ function processHTTPRequest(url: string, method: RequestType = 'get', body: Form
});
}

function processFormData(data: Record<string, unknown>, initiatedOffline: boolean): Promise<FormData> {
const formData = new FormData();
let promiseChain = Promise.resolve();

Object.keys(data).forEach((key) => {
promiseChain = promiseChain.then(() => {
if (typeof data[key] === 'undefined') {
return Promise.resolve();
}

if (key === CONST.SEARCH.TABLE_COLUMNS.RECEIPT && initiatedOffline) {
const {uri: path = '', source} = data[key] as File;

console.debug('[dev] 2. data[key]:', data[key]);
console.debug('[dev] 3. path', path);
console.debug('[dev] 4. source', source);

return import('./fileDownload/FileUtils')
.then(({readFileAsync}) => {
console.debug('[dev] 5. readFileAsync', readFileAsync);
return readFileAsync(source, path, () => {});
})
.then((file) => {
console.debug('[dev] 6. file', file);
if (file) {
formData.append(key, file);
}
})
.catch(() => {
console.debug('[dev] Error reading photo');
});
}

formData.append(key, data[key] as string | Blob);

return Promise.resolve();
});
});

return promiseChain.then(() => formData);
}

/**
* Makes XHR request
* @param command the name of the API command
* @param data parameters for the API command
* @param type HTTP request type (get/post)
* @param shouldUseSecure should we use the secure server
*/
function xhr(command: string, data: Record<string, unknown>, type: RequestType = CONST.NETWORK.METHOD.POST, shouldUseSecure = false): Promise<Response> {
const formData = new FormData();
Object.keys(data).forEach((key) => {
if (typeof data[key] === 'undefined') {
return;
function xhr(command: string, data: Record<string, unknown>, type: RequestType = CONST.NETWORK.METHOD.POST, shouldUseSecure = false, initiatedOffline = false): Promise<Response> {
if (command === 'RequestMoney') {
console.debug('[dev] 1. data:', data);
}

return processFormData(data, initiatedOffline).then((formData) => {
if (command === 'RequestMoney') {
console.debug('[dev] 7. formData:', formData);
console.debug("[dev] 8. formData.getAll('receipt'):", formData.getAll('receipt'));
}
formData.append(key, data[key] as string | Blob);
});

const url = ApiUtils.getCommandURL({shouldUseSecure, command});
const url = ApiUtils.getCommandURL({shouldUseSecure, command});
const abortSignalController = data.canCancel ? abortControllerMap.get(command as AbortCommand) ?? abortControllerMap.get(ABORT_COMMANDS.All) : undefined;

const abortSignalController = data.canCancel ? abortControllerMap.get(command as AbortCommand) ?? abortControllerMap.get(ABORT_COMMANDS.All) : undefined;
return processHTTPRequest(url, type, formData, abortSignalController?.signal);
return processHTTPRequest(url, type, formData, abortSignalController?.signal);
});
}

function cancelPendingRequests(command: AbortCommand = ABORT_COMMANDS.All) {
Expand Down
10 changes: 6 additions & 4 deletions src/libs/Network/SequentialQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ function handleConflictActions(conflictAction: ConflictData, newRequest: OnyxReq

function push(newRequest: OnyxRequest) {
const {checkAndFixConflictingRequest} = newRequest;
const isOffline = NetworkStore.isOffline();
const updatedRequest = {...newRequest, initiatedOffline: isOffline};

if (checkAndFixConflictingRequest) {
const requests = PersistedRequests.getAll();
Expand All @@ -240,15 +242,15 @@ function push(newRequest: OnyxRequest) {

// don't try to serialize a function.
// eslint-disable-next-line no-param-reassign
delete newRequest.checkAndFixConflictingRequest;
handleConflictActions(conflictAction, newRequest);
delete updatedRequest.checkAndFixConflictingRequest;
handleConflictActions(conflictAction, updatedRequest);
} else {
// Add request to Persisted Requests so that it can be retried if it fails
PersistedRequests.save(newRequest);
PersistedRequests.save(updatedRequest);
}

// If we are offline we don't need to trigger the queue to empty as it will happen when we come back online
if (NetworkStore.isOffline()) {
if (isOffline) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/libs/Request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function makeXHR(request: Request): Promise<Response | void> {
});
}

return HttpUtils.xhr(request.command, finalParameters, request.type, request.shouldUseSecure);
return HttpUtils.xhr(request.command, finalParameters, request.type, request.shouldUseSecure, request.initiatedOffline);
});
}

Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ type RequestData = {

/** Whether the app should skip the web proxy to connect to API endpoints */
shouldSkipWebProxy?: boolean;

/** Whether the request is initiated offline */
initiatedOffline?: boolean;
};

/**
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/SequentialQueueTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ describe('SequentialQueue', () => {

// I need to test now when moving the request from the queue to the ongoing request the PERSISTED_REQUESTS is decreased and PERSISTED_ONGOING_REQUESTS has the new request
it('should move the request from the queue to the ongoing request and save it into Onyx', () => {
const persistedRequest = {...request, persistWhenOngoing: true};
const persistedRequest = {...request, persistWhenOngoing: true, initiatedOffline: false};
SequentialQueue.push(persistedRequest);

const connectionId = Onyx.connect({
Expand All @@ -248,7 +248,7 @@ describe('SequentialQueue', () => {
});

it('should get the ongoing request from onyx and start processing it', async () => {
const persistedRequest = {...request, persistWhenOngoing: true};
const persistedRequest = {...request, persistWhenOngoing: true, initiatedOffline: false};
Onyx.set(ONYXKEYS.PERSISTED_ONGOING_REQUESTS, persistedRequest);
SequentialQueue.push({command: 'OpenReport'});

Expand Down
Loading