Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions src/components/ReportActionItem/ReportActionItemImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,21 @@ function ReportActionItemImage({
);
}

const originalImageSource = tryResolveUrlFromApiRoot(image ?? '');
const thumbnailSource = tryResolveUrlFromApiRoot(thumbnail ?? '');
const localSource = transaction?.receipt?.localSource;
const effectiveIsLocalFile = isLocalFile || !!localSource;
const effectiveThumbnail = localSource ?? thumbnail;
const effectiveImage = localSource !== undefined && typeof image === 'string' ? localSource : image;

const originalImageSource = tryResolveUrlFromApiRoot(effectiveImage ?? '');
const thumbnailSource = tryResolveUrlFromApiRoot(effectiveThumbnail ?? '');
const isEReceipt = transaction && !hasReceiptSource(transaction) && hasEReceipt(transaction);
const isPDF = filename && Str.isPDF(filename);

let propsObj: ReceiptImageProps;

if (isEReceipt) {
propsObj = {isEReceipt: true, transactionID: transaction.transactionID, iconSize: isSingleImage ? 'medium' : ('small' as IconSize), shouldUseFullHeight};
} else if (thumbnail && !isLocalFile) {
} else if (effectiveThumbnail && !effectiveIsLocalFile) {
propsObj = {
shouldUseThumbnailImage: shouldUseThumbnailImage ?? true,

Expand All @@ -158,15 +163,15 @@ function ReportActionItemImage({
// If the image is full height, use initial position to make sure it will grow properly to fill the container
shouldUseInitialObjectPosition: isMapDistanceRequest && !shouldUseFullHeight,
};
} else if (isLocalFile && isPDF && typeof originalImageSource === 'string') {
} else if (effectiveIsLocalFile && isPDF && typeof originalImageSource === 'string') {
propsObj = {isPDFThumbnail: true, source: originalImageSource};
} else {
propsObj = {
isThumbnail,
...(isThumbnail && {iconSize: (isSingleImage ? 'medium' : 'small') as IconSize, fileExtension}),
shouldUseThumbnailImage: shouldUseThumbnailImage ?? true,
isAuthTokenRequired: false,
source: shouldUseThumbnailImage ? (thumbnail ?? image ?? '') : originalImageSource,
source: shouldUseThumbnailImage ? (effectiveThumbnail ?? effectiveImage ?? '') : originalImageSource,

// If the image is full height, use initial position to make sure it will grow properly to fill the container
shouldUseInitialObjectPosition: isMapDistanceRequest && !shouldUseFullHeight,
Expand Down
2 changes: 2 additions & 0 deletions src/libs/DebugUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ function validateReportActionDraftProperty(key: keyof ReportAction, value: strin
name: 'string',
receiptID: 'string',
source: 'string',
localSource: 'string',
filename: 'string',
reservationList: 'string',
isTestReceipt: 'boolean',
Expand Down Expand Up @@ -1138,6 +1139,7 @@ function validateTransactionDraftProperty(key: keyof Transaction, value: string)
return validateObject<ObjectElement<Transaction, 'receipt'>>(value, {
type: 'string',
source: 'string',
localSource: 'string',
name: 'string',
filename: 'string',
state: CONST.IOU.RECEIPT_STATE,
Expand Down
20 changes: 15 additions & 5 deletions src/libs/actions/IOU/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import {registerDeferredWrite} from '@libs/deferredLayoutWrite';
import DistanceRequestUtils from '@libs/DistanceRequestUtils';
import {getMicroSecondOnyxErrorObject, getMicroSecondOnyxErrorWithTranslationKey} from '@libs/ErrorUtils';
import {readFileAsync} from '@libs/fileDownload/FileUtils';
import {isLocalFile, readFileAsync} from '@libs/fileDownload/FileUtils';
import type {MinimalTransaction} from '@libs/Formula';
import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import GoogleTagManager from '@libs/GoogleTagManager';
Expand Down Expand Up @@ -790,7 +790,7 @@
});

type StartSplitBilActionParams = {
participants: Participant[];

Check warning on line 793 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
currentUserLogin: string;
currentUserAccountID: number;
comment: string;
Expand Down Expand Up @@ -923,7 +923,7 @@
allTransactions = {};
return;
}

Check warning on line 926 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
allTransactions = value;
},
});
Expand All @@ -937,7 +937,7 @@
},
});

let allTransactionViolations: NonNullable<OnyxCollection<OnyxTypes.TransactionViolations>> = {};

Check warning on line 940 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
Onyx.connect({
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
waitForCollectionCallback: true,
Expand All @@ -946,7 +946,7 @@
allTransactionViolations = {};
return;
}

Check warning on line 949 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
allTransactionViolations = value;
},
});
Expand All @@ -960,7 +960,7 @@
allPolicyTags = {};
return;
}
allPolicyTags = value;

Check warning on line 963 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
},
});

Expand All @@ -973,7 +973,7 @@
},
});

let allReportNameValuePairs: OnyxCollection<OnyxTypes.ReportNameValuePairs>;

Check warning on line 976 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS,
waitForCollectionCallback: true,
Expand All @@ -982,7 +982,7 @@
},
});

let userAccountID = -1;

Check warning on line 985 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
let currentUserEmail = '';
Onyx.connect({
key: ONYXKEYS.SESSION,
Expand All @@ -992,7 +992,7 @@
},
});

let deprecatedCurrentUserPersonalDetails: OnyxEntry<OnyxTypes.PersonalDetails>;

Check warning on line 995 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
Onyx.connect({
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
Expand All @@ -1001,7 +1001,7 @@
});

let allReportActions: OnyxCollection<OnyxTypes.ReportActions>;
Onyx.connect({

Check warning on line 1004 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
waitForCollectionCallback: true,
callback: (actions) => {
Expand All @@ -1009,7 +1009,7 @@
return;
}
allReportActions = actions;
},

Check warning on line 1012 in src/libs/actions/IOU/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
});

let personalDetailsList: OnyxEntry<OnyxTypes.PersonalDetailsList>;
Expand Down Expand Up @@ -1888,6 +1888,18 @@
| typeof ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE
| typeof ONYXKEYS.COLLECTION.SNAPSHOT;

/**
* When a receipt is a local file (e.g. taken from camera or picked from gallery), its `source` is a local URI
* that will be lost once the optimistic transaction is replaced by the server response. We stash it in
* `localSource` so the UI can continue showing the local image while SmartScan is in progress.
*/
function getTransactionWithPreservedLocalReceiptSource(transaction: OnyxTypes.Transaction, isScanRequest: boolean): OnyxTypes.Transaction {
if (isScanRequest && isLocalFile(transaction.receipt?.source)) {
return {...transaction, receipt: {...transaction.receipt, localSource: String(transaction.receipt?.source)}};
}
return transaction;
}

/** Builds the Onyx data for an expense */
function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyRequestParams): OnyxData<BuildOnyxDataForMoneyRequestKeys> {
const {
Expand Down Expand Up @@ -1925,7 +1937,6 @@
const outstandingChildRequest = getOutstandingChildRequest(iou.report);
const clearedPendingFields = Object.fromEntries(Object.keys(transaction.pendingFields ?? {}).map((key) => [key, null]));
const isMoneyRequestToManagerMcTest = isTestTransactionReport(iou.report);

const onyxData: OnyxData<BuildOnyxDataForMoneyRequestKeys> = {
optimisticData: [],
successData: [],
Expand Down Expand Up @@ -1980,7 +1991,7 @@
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`,
value: transaction,
value: getTransactionWithPreservedLocalReceiptSource(transaction, isScanRequest),
},
isNewChatReport
? {
Expand Down Expand Up @@ -2615,7 +2626,6 @@
const isScanRequest = isScanRequestTransactionUtils(transaction);
const isDistanceRequest = isDistanceRequestTransactionUtils(transaction);
const clearedPendingFields = Object.fromEntries(Object.keys(transaction.pendingFields ?? {}).map((key) => [key, null]));

const onyxData: OnyxData<BuildOnyxDataForTrackExpenseKeys> = {
optimisticData: [],
successData: [],
Expand Down Expand Up @@ -2750,7 +2760,7 @@
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`,
value: transaction,
value: getTransactionWithPreservedLocalReceiptSource(transaction, isScanRequest),
},
{
onyxMethod: Onyx.METHOD.MERGE,
Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ type Receipt = {
/** Path of the receipt file */
source?: ReceiptSource;

/** Local file URI preserved on the creating device so the remote source from the server does not cause a reload */
localSource?: string;

/** Name of receipt file */
filename?: string;

Expand Down
Loading