Skip to content

Commit dbc3de5

Browse files
authored
Merge pull request #55942 from Expensify/revert-53849-enabling-receipt-drop-inside-confirm-step
[CP Staging] Revert "Enabling Receipt drag and drop inside the confirmation step"
2 parents 3800df7 + ff4468d commit dbc3de5

14 files changed

+186
-341
lines changed

src/components/EReceiptThumbnail.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type IconSize = 'x-small' | 'small' | 'medium' | 'large';
2121

2222
type EReceiptThumbnailProps = {
2323
/** TransactionID of the transaction this EReceipt corresponds to. */
24-
transactionID?: string;
24+
transactionID: string;
2525

2626
/** Border radius to be applied on the parent view. */
2727
borderRadius?: number;

src/components/MoneyRequestConfirmationListFooter.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ import {hasEnabledTags} from '@libs/TagsOptionsListUtils';
2222
import {getTagForDisplay, getTaxAmount, getTaxName, isAmountMissing, isCreatedMissing, shouldShowAttendees as shouldShowAttendeesTransactionUtils} from '@libs/TransactionUtils';
2323
import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot';
2424
import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow';
25-
import type {IOUAction, IOUType} from '@src/CONST';
2625
import CONST from '@src/CONST';
26+
import type {IOUAction, IOUType} from '@src/CONST';
2727
import ONYXKEYS from '@src/ONYXKEYS';
2828
import ROUTES from '@src/ROUTES';
2929
import type * as OnyxTypes from '@src/types/onyx';
@@ -827,7 +827,6 @@ function MoneyRequestConfirmationListFooter({
827827
? receiptThumbnailContent
828828
: shouldShowReceiptEmptyState && (
829829
<ReceiptEmptyState
830-
transactionID={transactionID}
831830
onPress={() => {
832831
if (!transactionID) {
833832
return;
@@ -837,7 +836,6 @@ function MoneyRequestConfirmationListFooter({
837836
ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams()),
838837
);
839838
}}
840-
shouldAllowReceiptDrop
841839
/>
842840
))}
843841
{primaryFields}

src/components/ReceiptEmptyState.tsx

+3-110
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
1-
import {Str} from 'expensify-common';
2-
import React, {useState} from 'react';
1+
import React from 'react';
32
import {View} from 'react-native';
43
import useLocalize from '@hooks/useLocalize';
54
import useTheme from '@hooks/useTheme';
65
import useThemeStyles from '@hooks/useThemeStyles';
7-
import {setMoneyRequestReceipt} from '@libs/actions/IOU';
8-
import {resizeImageIfNeeded} from '@libs/fileDownload/FileUtils';
9-
import {validateReceipt} from '@libs/ReceiptUtils';
10-
import ReceiptDropUI from '@pages/iou/ReceiptDropUI';
116
import variables from '@styles/variables';
12-
import CONST from '@src/CONST';
13-
import type {TranslationPaths} from '@src/languages/types';
14-
import type {FileObject} from './AttachmentModal';
15-
import ConfirmModal from './ConfirmModal';
16-
import FullScreenLoadingIndicator from './FullscreenLoadingIndicator';
177
import Icon from './Icon';
188
import * as Expensicons from './Icon/Expensicons';
19-
import PDFThumbnail from './PDFThumbnail';
209
import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback';
2110

2211
type ReceiptEmptyStateProps = {
@@ -29,85 +18,13 @@ type ReceiptEmptyStateProps = {
2918
disabled?: boolean;
3019

3120
isThumbnail?: boolean;
32-
33-
shouldAllowReceiptDrop?: boolean;
34-
35-
transactionID: string | undefined;
3621
};
3722

3823
// Returns an SVG icon indicating that the user should attach a receipt
39-
function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumbnail = false, shouldAllowReceiptDrop = false, transactionID}: ReceiptEmptyStateProps) {
24+
function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumbnail = false}: ReceiptEmptyStateProps) {
4025
const styles = useThemeStyles();
4126
const {translate} = useLocalize();
4227
const theme = useTheme();
43-
const [isAttachmentInvalid, setIsAttachmentInvalid] = useState(false);
44-
const [attachmentInvalidReasonTitle, setAttachmentInvalidReasonTitle] = useState<TranslationPaths>();
45-
const [attachmentInvalidReason, setAttachmentValidReason] = useState<TranslationPaths>();
46-
const [pdfFile, setPdfFile] = useState<null | FileObject>(null);
47-
const [isLoadingReceipt, setIsLoadingReceipt] = useState(false);
48-
49-
/**
50-
* Sets the upload receipt error modal content when an invalid receipt is uploaded
51-
*/
52-
const setUploadReceiptError = (isInvalid: boolean, title: TranslationPaths, reason: TranslationPaths) => {
53-
setIsAttachmentInvalid(isInvalid);
54-
setAttachmentInvalidReasonTitle(title);
55-
setAttachmentValidReason(reason);
56-
setPdfFile(null);
57-
};
58-
59-
const setReceipt = (originalFile: FileObject, isPdfValidated?: boolean) => {
60-
validateReceipt(originalFile).then((result) => {
61-
if (!result.isValid) {
62-
if (result.title && result.reason) {
63-
setUploadReceiptError(true, result.title, result.reason);
64-
}
65-
return;
66-
}
67-
68-
// If we have a pdf file and if it is not validated then set the pdf file for validation and return
69-
if (Str.isPDF(originalFile.name ?? '') && !isPdfValidated) {
70-
setPdfFile(originalFile);
71-
return;
72-
}
73-
74-
// With the image size > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE, we use manipulateAsync to resize the image.
75-
// It takes a long time so we should display a loading indicator while the resize image progresses.
76-
if (Str.isImage(originalFile.name ?? '') && (originalFile?.size ?? 0) > CONST.API_ATTACHMENT_VALIDATIONS.MAX_SIZE) {
77-
setIsLoadingReceipt(true);
78-
}
79-
80-
resizeImageIfNeeded(originalFile).then((file) => {
81-
setIsLoadingReceipt(false);
82-
const source = URL.createObjectURL(file as Blob);
83-
if (transactionID) {
84-
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
85-
setMoneyRequestReceipt(transactionID, source, file.name || '', true);
86-
}
87-
});
88-
});
89-
};
90-
91-
const hideReceiptModal = () => {
92-
setIsAttachmentInvalid(false);
93-
};
94-
95-
const PDFThumbnailView = pdfFile ? (
96-
<PDFThumbnail
97-
style={styles.invisiblePDF}
98-
previewSourceURL={pdfFile.uri ?? ''}
99-
onLoadSuccess={() => {
100-
setPdfFile(null);
101-
setReceipt(pdfFile, true);
102-
}}
103-
onPassword={() => {
104-
setUploadReceiptError(true, 'attachmentPicker.attachmentError', 'attachmentPicker.protectedPDFNotSupported');
105-
}}
106-
onLoadError={() => {
107-
setUploadReceiptError(true, 'attachmentPicker.attachmentError', 'attachmentPicker.errorWhileSelectingCorruptedAttachment');
108-
}}
109-
/>
110-
) : null;
11128

11229
const Wrapper = onPress ? PressableWithoutFeedback : View;
11330

@@ -121,14 +38,11 @@ function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumb
12138
style={[
12239
styles.alignItemsCenter,
12340
styles.justifyContentCenter,
124-
styles.moneyRequestImage,
41+
styles.moneyRequestViewImage,
12542
isThumbnail ? styles.moneyRequestAttachReceiptThumbnail : styles.moneyRequestAttachReceipt,
12643
hasError && styles.borderColorDanger,
12744
]}
12845
>
129-
{isLoadingReceipt && <FullScreenLoadingIndicator />}
130-
{PDFThumbnailView}
131-
13246
<View>
13347
<Icon
13448
fill={theme.border}
@@ -145,27 +59,6 @@ function ReceiptEmptyState({hasError = false, onPress, disabled = false, isThumb
14559
/>
14660
)}
14761
</View>
148-
149-
{shouldAllowReceiptDrop && !disabled && (
150-
<ReceiptDropUI
151-
onDrop={(e) => {
152-
const file = e?.dataTransfer?.files[0];
153-
if (file) {
154-
file.uri = URL.createObjectURL(file);
155-
setReceipt(file);
156-
}
157-
}}
158-
/>
159-
)}
160-
<ConfirmModal
161-
title={attachmentInvalidReasonTitle ? translate(attachmentInvalidReasonTitle) : ''}
162-
onConfirm={hideReceiptModal}
163-
onCancel={hideReceiptModal}
164-
isVisible={isAttachmentInvalid}
165-
prompt={attachmentInvalidReason ? translate(attachmentInvalidReason) : ''}
166-
confirmText={translate('common.close')}
167-
shouldShowCancelButton={false}
168-
/>
16962
</Wrapper>
17063
);
17164
}

src/components/ReceiptImage.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ function ReceiptImage({
114114
isThumbnail
115115
onPress={onPress}
116116
disabled={!onPress}
117-
transactionID={transactionID}
118117
/>
119118
);
120119
}
@@ -133,7 +132,7 @@ function ReceiptImage({
133132
return (
134133
<View style={style ?? [styles.w100, styles.h100]}>
135134
<EReceiptThumbnail
136-
transactionID={transactionID}
135+
transactionID={transactionID ?? '-1'}
137136
iconSize={iconSize}
138137
// eslint-disable-next-line react/jsx-props-no-spreading
139138
{...props}

src/components/ReportActionItem/MoneyRequestView.tsx

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, {useCallback, useMemo} from 'react';
22
import {View} from 'react-native';
3-
import type {OnyxEntry} from 'react-native-onyx';
43
import {useOnyx} from 'react-native-onyx';
4+
import type {OnyxEntry} from 'react-native-onyx';
55
import * as Expensicons from '@components/Icon/Expensicons';
66
import MenuItem from '@components/MenuItem';
77
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
@@ -16,15 +16,14 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'
1616
import useLocalize from '@hooks/useLocalize';
1717
import useNetwork from '@hooks/useNetwork';
1818
import useThemeStyles from '@hooks/useThemeStyles';
19-
import type {ViolationField} from '@hooks/useViolations';
2019
import useViolations from '@hooks/useViolations';
20+
import type {ViolationField} from '@hooks/useViolations';
2121
import {convertToDisplayString} from '@libs/CurrencyUtils';
2222
import DistanceRequestUtils from '@libs/DistanceRequestUtils';
2323
import {hasEnabledOptions} from '@libs/OptionsListUtils';
2424
import {getTagLists, hasDependentTags, isTaxTrackingEnabled} from '@libs/PolicyUtils';
2525
import {getThumbnailAndImageURIs} from '@libs/ReceiptUtils';
2626
import {getOriginalMessage, isMoneyRequestAction, isPayAction} from '@libs/ReportActionsUtils';
27-
import type {TransactionDetails} from '@libs/ReportUtils';
2827
import {
2928
canEditFieldOfMoneyRequest,
3029
canEditMoneyRequest,
@@ -40,6 +39,7 @@ import {
4039
isSettled as isSettledReportUtils,
4140
isTrackExpenseReport,
4241
} from '@libs/ReportUtils';
42+
import type {TransactionDetails} from '@libs/ReportUtils';
4343
import {hasEnabledTags} from '@libs/TagsOptionsListUtils';
4444
import {
4545
didReceiptScanSucceed as didReceiptScanSucceedTransactionUtils,
@@ -70,13 +70,13 @@ import CONST from '@src/CONST';
7070
import type {TranslationPaths} from '@src/languages/types';
7171
import ONYXKEYS from '@src/ONYXKEYS';
7272
import ROUTES from '@src/ROUTES';
73-
import type {Report, Transaction, TransactionViolation, ViolationName} from '@src/types/onyx';
73+
import type * as OnyxTypes from '@src/types/onyx';
7474
import type {TransactionPendingFieldsKey} from '@src/types/onyx/Transaction';
7575
import ReportActionItemImage from './ReportActionItemImage';
7676

7777
type MoneyRequestViewProps = {
7878
/** The report currently being looked at */
79-
report: OnyxEntry<Report>;
79+
report: OnyxEntry<OnyxTypes.Report>;
8080

8181
/** Whether we should display the animated banner above the component */
8282
shouldShowAnimatedBackground: boolean;
@@ -88,17 +88,17 @@ type MoneyRequestViewProps = {
8888
isFromReviewDuplicates?: boolean;
8989

9090
/** Updated transaction to show in duplicate transaction flow */
91-
updatedTransaction?: OnyxEntry<Transaction>;
91+
updatedTransaction?: OnyxEntry<OnyxTypes.Transaction>;
9292
};
9393

94-
const receiptImageViolationNames: ViolationName[] = [
94+
const receiptImageViolationNames: OnyxTypes.ViolationName[] = [
9595
CONST.VIOLATIONS.RECEIPT_REQUIRED,
9696
CONST.VIOLATIONS.RECEIPT_NOT_SMART_SCANNED,
9797
CONST.VIOLATIONS.CASH_EXPENSE_WITH_NO_RECEIPT,
9898
CONST.VIOLATIONS.SMARTSCAN_FAILED,
9999
];
100100

101-
const receiptFieldViolationNames: ViolationName[] = [CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE];
101+
const receiptFieldViolationNames: OnyxTypes.ViolationName[] = [CONST.VIOLATIONS.MODIFIED_AMOUNT, CONST.VIOLATIONS.MODIFIED_DATE];
102102

103103
function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = false, updatedTransaction, isFromReviewDuplicates = false}: MoneyRequestViewProps) {
104104
const styles = useThemeStyles();
@@ -219,7 +219,7 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals
219219

220220
const {getViolationsForField} = useViolations(transactionViolations ?? [], isReceiptBeingScanned || !isPaidGroupPolicy(report));
221221
const hasViolations = useCallback(
222-
(field: ViolationField, data?: TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string): boolean =>
222+
(field: ViolationField, data?: OnyxTypes.TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string): boolean =>
223223
getViolationsForField(field, data, policyHasDependentTags, tagValue).length > 0,
224224
[getViolationsForField],
225225
);
@@ -293,7 +293,7 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals
293293
const getPendingFieldAction = (fieldPath: TransactionPendingFieldsKey) => (pendingAction ? undefined : transaction?.pendingFields?.[fieldPath]);
294294

295295
const getErrorForField = useCallback(
296-
(field: ViolationField, data?: TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string) => {
296+
(field: ViolationField, data?: OnyxTypes.TransactionViolation['data'], policyHasDependentTags = false, tagValue?: string) => {
297297
// Checks applied when creating a new expense
298298
// NOTE: receipt field can return multiple violations, so we need to handle it separately
299299
const fieldChecks: Partial<Record<ViolationField, {isError: boolean; translationPath: TranslationPaths}>> = {
@@ -538,7 +538,6 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals
538538
<ReceiptEmptyState
539539
hasError={hasErrors}
540540
disabled={!canEditReceipt}
541-
transactionID={transaction?.transactionID}
542541
onPress={() => {
543542
if (!transaction?.transactionID || !report?.reportID) {
544543
return;

0 commit comments

Comments
 (0)