Skip to content

Commit 4092be2

Browse files
Merge pull request Expensify#75374 from Krishna2323/krishna2323/issue/74656
fix: Tags - App freezes on import tags page when download backup is cancelled.
2 parents 4c7c3d4 + f14e908 commit 4092be2

3 files changed

Lines changed: 57 additions & 15 deletions

File tree

src/libs/fileDownload/index.ios.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ import CONST from '@src/CONST';
77
import {appendTimeToFileName, getFileName, getFileType, showGeneralErrorAlert, showPermissionErrorAlert, showSuccessAlert} from './FileUtils';
88
import type {FileDownload} from './types';
99

10+
const isUserCancelled = (err: unknown) => {
11+
let msg = '';
12+
if (typeof err === 'string') {
13+
msg = err.toLowerCase();
14+
} else if (err && typeof err === 'object') {
15+
const errorMessage = (err as {message?: unknown}).message;
16+
const errorError = (err as {error?: unknown}).error;
17+
if (typeof errorMessage === 'string') {
18+
msg = errorMessage.toLowerCase();
19+
} else if (typeof errorError === 'string') {
20+
msg = errorError.toLowerCase();
21+
}
22+
}
23+
return /cancel|did not share/.test(msg);
24+
};
25+
1026
/**
1127
* Downloads the file to Documents section in iOS
1228
*/
@@ -55,7 +71,11 @@ const postDownloadFile = (url: string, fileName?: string, formData?: FormData, o
5571
.then(() => RNFS.unlink(localPath));
5672
});
5773
})
58-
.catch(() => {
74+
.catch((error) => {
75+
// If the user cancels the iOS share/save dialog, we exit silently without showing an error
76+
if (isUserCancelled(error)) {
77+
return;
78+
}
5979
if (!onDownloadFailed) {
6080
showGeneralErrorAlert();
6181
}

src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import ConfirmModal from '@components/ConfirmModal';
88
import DecisionModal from '@components/DecisionModal';
99
import EmptyStateComponent from '@components/EmptyStateComponent';
1010
import HeaderWithBackButton from '@components/HeaderWithBackButton';
11-
import * as Expensicons from '@components/Icon/Expensicons';
1211
import LottieAnimations from '@components/LottieAnimations';
1312
import RenderHTML from '@components/RenderHTML';
1413
import ScreenWrapper from '@components/ScreenWrapper';
@@ -20,7 +19,7 @@ import type {ListItem} from '@components/SelectionListWithSections/types';
2019
import TableListItemSkeleton from '@components/Skeletons/TableRowSkeleton';
2120
import Text from '@components/Text';
2221
import useCleanupSelectedOptions from '@hooks/useCleanupSelectedOptions';
23-
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
22+
import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
2423
import useLocalize from '@hooks/useLocalize';
2524
import useMobileSelectionMode from '@hooks/useMobileSelectionMode';
2625
import useNetwork from '@hooks/useNetwork';
@@ -130,6 +129,7 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
130129
const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, {canBeMissing: false});
131130
const isMobileSelectionModeEnabled = useMobileSelectionMode();
132131
const illustrations = useMemoizedLazyIllustrations(['PerDiem'] as const);
132+
const expensifyIcons = useMemoizedLazyExpensifyIcons(['Gear', 'Table', 'Download', 'Trashcan'] as const);
133133

134134
const [customUnit, allRatesArray, allSubRates] = useMemo(() => {
135135
const customUnits = getPerDiemCustomUnit(policy);
@@ -275,14 +275,14 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
275275
const menuItems = [];
276276
if (policy?.areCategoriesEnabled && hasEnabledOptions(policyCategories ?? {})) {
277277
menuItems.push({
278-
icon: Expensicons.Gear,
278+
icon: expensifyIcons.Gear,
279279
text: translate('common.settings'),
280280
onSelected: openSettings,
281281
value: CONST.POLICY.SECONDARY_ACTIONS.SETTINGS,
282282
});
283283
}
284284
menuItems.push({
285-
icon: Expensicons.Table,
285+
icon: expensifyIcons.Table,
286286
text: translate('spreadsheet.importSpreadsheet'),
287287
onSelected: () => {
288288
if (isOffline) {
@@ -295,30 +295,43 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) {
295295
});
296296
if (hasVisibleSubRates) {
297297
menuItems.push({
298-
icon: Expensicons.Download,
298+
icon: expensifyIcons.Download,
299299
text: translate('spreadsheet.downloadCSV'),
300300
onSelected: () => {
301301
if (isOffline) {
302302
close(() => setIsOfflineModalVisible(true));
303303
return;
304304
}
305-
downloadPerDiemCSV(policyID, () => {
306-
setIsDownloadFailureModalVisible(true);
307-
});
305+
close(() =>
306+
downloadPerDiemCSV(policyID, () => {
307+
setIsDownloadFailureModalVisible(true);
308+
}),
309+
);
308310
},
309311
value: CONST.POLICY.SECONDARY_ACTIONS.DOWNLOAD_CSV,
310312
});
311313
}
312314

313315
return menuItems;
314-
}, [policy?.areCategoriesEnabled, policyCategories, translate, hasVisibleSubRates, openSettings, isOffline, policyID]);
316+
}, [
317+
policy?.areCategoriesEnabled,
318+
policyCategories,
319+
translate,
320+
hasVisibleSubRates,
321+
openSettings,
322+
isOffline,
323+
policyID,
324+
expensifyIcons.Gear,
325+
expensifyIcons.Table,
326+
expensifyIcons.Download,
327+
]);
315328

316329
const getHeaderButtons = () => {
317330
const options: Array<DropdownOption<DeepValueOf<typeof CONST.POLICY.BULK_ACTION_TYPES>>> = [];
318331

319332
if (shouldUseNarrowLayout ? canSelectMultiple : selectedPerDiem.length > 0) {
320333
options.push({
321-
icon: Expensicons.Trashcan,
334+
icon: expensifyIcons.Trashcan,
322335
text: translate('workspace.perDiem.deleteRates', {count: selectedPerDiem.length}),
323336
value: CONST.POLICY.BULK_ACTION_TYPES.DELETE,
324337
onSelected: () => setDeletePerDiemConfirmModalVisible(true),

src/pages/workspace/tags/ImportTagsOptionsPage.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import useOnyx from '@hooks/useOnyx';
1515
import usePolicy from '@hooks/usePolicy';
1616
import useResponsiveLayout from '@hooks/useResponsiveLayout';
1717
import useThemeStyles from '@hooks/useThemeStyles';
18+
import {close} from '@libs/actions/Modal';
1819
import {cleanPolicyTags, downloadMultiLevelTagsCSV, downloadTagsCSV, setImportedSpreadsheetIsImportingMultiLevelTags} from '@libs/actions/Policy/Tag';
1920
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
2021
import Navigation from '@libs/Navigation/Navigation';
@@ -111,13 +112,17 @@ function ImportTagsOptionsPage({route}: ImportTagsOptionsPageProps) {
111112
downloadMultiLevelTagsCSV(
112113
policyID,
113114
() => {
114-
setIsDownloadFailureModalVisible(true);
115+
close(() => {
116+
setIsDownloadFailureModalVisible(true);
117+
});
115118
},
116119
hasDependentTags,
117120
);
118121
} else {
119122
downloadTagsCSV(policyID, () => {
120-
setIsDownloadFailureModalVisible(true);
123+
close(() => {
124+
setIsDownloadFailureModalVisible(true);
125+
});
121126
});
122127
}
123128
}}
@@ -139,13 +144,17 @@ function ImportTagsOptionsPage({route}: ImportTagsOptionsPageProps) {
139144
downloadMultiLevelTagsCSV(
140145
policyID,
141146
() => {
142-
setIsDownloadFailureModalVisible(true);
147+
close(() => {
148+
setIsDownloadFailureModalVisible(true);
149+
});
143150
},
144151
hasDependentTags,
145152
);
146153
} else {
147154
downloadTagsCSV(policyID, () => {
148-
setIsDownloadFailureModalVisible(true);
155+
close(() => {
156+
setIsDownloadFailureModalVisible(true);
157+
});
149158
});
150159
}
151160
}}

0 commit comments

Comments
 (0)