diff --git a/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx b/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx index 25a14c10eb67..1b2d51d2fd25 100644 --- a/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx +++ b/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.tsx @@ -2,6 +2,7 @@ import React from 'react'; import AttachmentView from '@components/Attachments/AttachmentView'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; import {ShowContextMenuContext, showContextMenuForReport} from '@components/ShowContextMenuContext'; +import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -28,6 +29,7 @@ function BaseAnchorForAttachmentsOnly({style, source = '', displayName = '', onP const sourceID = (source.match(CONST.REGEX.ATTACHMENT_ID) ?? [])[1]; const [download] = useOnyx(`${ONYXKEYS.COLLECTION.DOWNLOAD}${sourceID}`, {canBeMissing: true}); + const {translate} = useLocalize(); const {isOffline} = useNetwork(); const styles = useThemeStyles(); @@ -44,7 +46,7 @@ function BaseAnchorForAttachmentsOnly({style, source = '', displayName = '', onP return; } setDownload(sourceID, true); - fileDownload(sourceURLWithAuth, displayName, '', isMobileSafari()).then(() => setDownload(sourceID, false)); + fileDownload(translate, sourceURLWithAuth, displayName, '', isMobileSafari()).then(() => setDownload(sourceID, false)); }} onPressIn={onPressIn} onPressOut={onPressOut} diff --git a/src/components/AttachmentPicker/index.native.tsx b/src/components/AttachmentPicker/index.native.tsx index e34ca3e38920..397b0a8fa61b 100644 --- a/src/components/AttachmentPicker/index.native.tsx +++ b/src/components/AttachmentPicker/index.native.tsx @@ -164,7 +164,7 @@ function AttachmentPicker({ if (response.errorCode) { switch (response.errorCode) { case 'permission': - showCameraPermissionsAlert(); + showCameraPermissionsAlert(translate); return resolve(); default: showGeneralAlert(); @@ -242,7 +242,7 @@ function AttachmentPicker({ } }); }), - [fileLimit, showGeneralAlert, type], + [fileLimit, showGeneralAlert, translate, type], ); /** * Launch the DocumentPicker. Results are in the same format as ImagePicker diff --git a/src/components/DotIndicatorMessage.tsx b/src/components/DotIndicatorMessage.tsx index 639cf00238e1..b8abb709c699 100644 --- a/src/components/DotIndicatorMessage.tsx +++ b/src/components/DotIndicatorMessage.tsx @@ -74,7 +74,7 @@ function DotIndicatorMessage({messages = {}, style, type, textStyles, dismissErr if (href.endsWith('retry')) { handleRetryPress(receiptError, dismissError, setShouldShowErrorModal); } else if (href.endsWith('download')) { - fileDownload(receiptError.source, receiptError.filename).finally(() => dismissError()); + fileDownload(translate, receiptError.source, receiptError.filename).finally(() => dismissError()); } }; diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index cd57d85bdf20..542db103c23a 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -782,9 +782,13 @@ function MoneyReportHeader({ setOfflineModalVisible(true); return; } - exportReportToCSV({reportID: moneyRequestReport.reportID, transactionIDList: transactionIDs}, () => { - setDownloadErrorModalVisible(true); - }); + exportReportToCSV( + {reportID: moneyRequestReport.reportID, transactionIDList: transactionIDs}, + () => { + setDownloadErrorModalVisible(true); + }, + translate, + ); }, }, [CONST.REPORT.EXPORT_OPTIONS.EXPORT_TO_INTEGRATION]: { @@ -1423,9 +1427,9 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload || !canTriggerAutomaticPDFDownload.current) { return; } - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? ''); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate); canTriggerAutomaticPDFDownload.current = false; - }, [hasFinishedPDFDownload, reportPDFFilename, moneyRequestReport?.reportName]); + }, [hasFinishedPDFDownload, reportPDFFilename, moneyRequestReport?.reportName, translate]); const shouldShowBackButton = shouldDisplayBackButton || shouldUseNarrowLayout; @@ -1734,7 +1738,7 @@ function MoneyReportHeader({ if (!hasFinishedPDFDownload) { setIsPDFModalVisible(false); } else { - downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? ''); + downloadReportPDF(reportPDFFilename, moneyRequestReport?.reportName ?? '', translate); } }} text={hasFinishedPDFDownload ? translate('common.download') : translate('common.cancel')} diff --git a/src/components/QRShare/QRShareWithDownload/index.native.tsx b/src/components/QRShare/QRShareWithDownload/index.native.tsx index 72d78611b0c1..76c81769e44c 100644 --- a/src/components/QRShare/QRShareWithDownload/index.native.tsx +++ b/src/components/QRShare/QRShareWithDownload/index.native.tsx @@ -17,7 +17,7 @@ function QRShareWithDownload({ref, ...props}: QRShareWithDownloadProps) { ref, () => ({ download: () => - qrCodeScreenshotRef.current?.capture?.().then((uri) => fileDownload(uri, getQrCodeFileName(props.title ?? 'QRCode'), translate('fileDownload.success.qrMessage'))), + qrCodeScreenshotRef.current?.capture?.().then((uri) => fileDownload(translate, uri, getQrCodeFileName(props.title ?? 'QRCode'), translate('fileDownload.success.qrMessage'))), }), [props.title, translate], ); diff --git a/src/components/QRShare/QRShareWithDownload/index.tsx b/src/components/QRShare/QRShareWithDownload/index.tsx index de17910289cc..ae21d08c6bb0 100644 --- a/src/components/QRShare/QRShareWithDownload/index.tsx +++ b/src/components/QRShare/QRShareWithDownload/index.tsx @@ -1,6 +1,7 @@ import React, {useImperativeHandle, useRef} from 'react'; import getQrCodeFileName from '@components/QRShare/getQrCodeDownloadFileName'; import type {QRShareHandle} from '@components/QRShare/types'; +import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import fileDownload from '@libs/fileDownload'; import QRShare from '..'; @@ -9,6 +10,7 @@ import type {QRShareWithDownloadProps} from './types'; function QRShareWithDownload({ref, ...props}: QRShareWithDownloadProps) { const {isOffline} = useNetwork(); const qrShareRef = useRef(null); + const {translate} = useLocalize(); useImperativeHandle( ref, @@ -22,10 +24,10 @@ function QRShareWithDownload({ref, ...props}: QRShareWithDownloadProps) { return; } - svg.toDataURL((dataURL) => resolve(fileDownload(dataURL, getQrCodeFileName(props.title ?? 'QRCode')))); + svg.toDataURL((dataURL) => resolve(fileDownload(translate, dataURL, getQrCodeFileName(props.title ?? 'QRCode')))); }), }), - [props.title], + [props.title, translate], ); return ( diff --git a/src/components/VideoPlayerContexts/VideoPopoverMenuContext.tsx b/src/components/VideoPlayerContexts/VideoPopoverMenuContext.tsx index 94f1e552440a..9963dec08d5f 100644 --- a/src/components/VideoPlayerContexts/VideoPopoverMenuContext.tsx +++ b/src/components/VideoPlayerContexts/VideoPopoverMenuContext.tsx @@ -35,8 +35,8 @@ function VideoPopoverMenuContextProvider({children}: ChildrenProps) { if (typeof source === 'number' || !source) { return; } - fileDownload(addEncryptedAuthTokenToURL(source)); - }, [source]); + fileDownload(translate, addEncryptedAuthTokenToURL(source)); + }, [source, translate]); const menuItems = useMemo(() => { const items: PopoverMenuItem[] = []; diff --git a/src/hooks/useFilesValidation.tsx b/src/hooks/useFilesValidation.tsx index 91cdb9069809..9aa4e0395031 100644 --- a/src/hooks/useFilesValidation.tsx +++ b/src/hooks/useFilesValidation.tsx @@ -387,7 +387,7 @@ function useFilesValidation(onFilesValidated: (files: FileObject[], dataTransfer if (!fileError) { return ''; } - const prompt = getFileValidationErrorText(fileError, {fileType: invalidFileExtension}, isValidatingReceipts === true).reason; + const prompt = getFileValidationErrorText(translate, fileError, {fileType: invalidFileExtension}, isValidatingReceipts === true).reason; if (fileError === CONST.FILE_VALIDATION_ERRORS.WRONG_FILE_TYPE_MULTIPLE || fileError === CONST.FILE_VALIDATION_ERRORS.WRONG_FILE_TYPE) { return ( @@ -401,7 +401,7 @@ function useFilesValidation(onFilesValidated: (files: FileObject[], dataTransfer const ErrorModal = ( { - onExportFailed?.(); - }); + exportReportToCSV( + {reportID: report.reportID, transactionIDList: selectedTransactionIDs}, + () => { + onExportFailed?.(); + }, + translate, + ); clearSelectedTransactions(true); }, }, diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 12012ea4fee7..d7fa6df61d2a 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -2,6 +2,7 @@ import lodashCloneDeep from 'lodash/cloneDeep'; import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {PartialDeep} from 'type-fest'; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import type PolicyData from '@hooks/usePolicyData/types'; import * as API from '@libs/API'; import type { @@ -1235,7 +1236,7 @@ function setPolicyCustomUnitDefaultCategory(policyID: string, customUnitID: stri API.write(WRITE_COMMANDS.SET_CUSTOM_UNIT_DEFAULT_CATEGORY, params, {optimisticData, successData, failureData}); } -function downloadCategoriesCSV(policyID: string, onDownloadFailed: () => void) { +function downloadCategoriesCSV(policyID: string, onDownloadFailed: () => void, translate: LocalizedTranslate) { const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_CATEGORIES_CSV, { policyID, }); @@ -1247,7 +1248,7 @@ function downloadCategoriesCSV(policyID: string, onDownloadFailed: () => void) { formData.append(key, String(value)); } - fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_CATEGORIES_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); + fileDownload(translate, ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_CATEGORIES_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } function setWorkspaceCategoryDescriptionHint(policyID: string, categoryName: string, commentHint: string, policyCategories: PolicyCategories = {}) { diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts index f783083a6ee7..00d282ceb4fa 100644 --- a/src/libs/actions/Policy/Member.ts +++ b/src/libs/actions/Policy/Member.ts @@ -1,7 +1,7 @@ import type {OnyxCollection, OnyxCollectionInputValue, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; -import type {LocaleContextProps} from '@components/LocaleContextProvider'; +import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleContextProvider'; import * as API from '@libs/API'; import type { AddMembersToWorkspaceParams, @@ -1275,7 +1275,7 @@ function declineJoinRequest(reportID: string | undefined, reportAction: OnyxEntr API.write(WRITE_COMMANDS.DECLINE_JOIN_REQUEST, parameters, {optimisticData, failureData, successData}); } -function downloadMembersCSV(policyID: string, onDownloadFailed: () => void) { +function downloadMembersCSV(policyID: string, onDownloadFailed: () => void, translate: LocalizedTranslate) { const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_MEMBERS_CSV, { policyID, }); @@ -1287,7 +1287,7 @@ function downloadMembersCSV(policyID: string, onDownloadFailed: () => void) { formData.append(key, String(value)); } - fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_MEMBERS_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); + fileDownload(translate, ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_MEMBERS_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } function clearInviteDraft(policyID: string) { diff --git a/src/libs/actions/Policy/PerDiem.ts b/src/libs/actions/Policy/PerDiem.ts index 0f082dc07595..ddf64723b4b3 100644 --- a/src/libs/actions/Policy/PerDiem.ts +++ b/src/libs/actions/Policy/PerDiem.ts @@ -1,6 +1,7 @@ import lodashDeepClone from 'lodash/cloneDeep'; import type {NullishDeep} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import * as API from '@libs/API'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import {getCommandURL} from '@libs/ApiUtils'; @@ -173,7 +174,7 @@ function importPerDiemRates(policyID: string, customUnitID: string, rates: Rate[ API.write(WRITE_COMMANDS.IMPORT_PER_DIEM_RATES, parameters, onyxData); } -function downloadPerDiemCSV(policyID: string, onDownloadFailed: () => void) { +function downloadPerDiemCSV(policyID: string, onDownloadFailed: () => void, translate: LocalizedTranslate) { const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_PER_DIEM_CSV, { policyID, }); @@ -185,7 +186,7 @@ function downloadPerDiemCSV(policyID: string, onDownloadFailed: () => void) { formData.append(key, String(value)); } - fileDownload(getCommandURL({command: WRITE_COMMANDS.EXPORT_PER_DIEM_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); + fileDownload(translate, getCommandURL({command: WRITE_COMMANDS.EXPORT_PER_DIEM_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } function clearPolicyPerDiemRatesErrorFields(policyID: string, customUnitID: string, updatedErrorFields: ErrorFields) { diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index b8f06cf1c53a..fa0ccc141cdf 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -1,6 +1,7 @@ import lodashCloneDeep from 'lodash/cloneDeep'; import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import type PolicyData from '@hooks/usePolicyData/types'; import * as API from '@libs/API'; import type { @@ -1234,7 +1235,7 @@ function setPolicyTagApprover(policyID: string, tag: string, approver: string) { API.write(WRITE_COMMANDS.SET_POLICY_TAG_APPROVER, parameters, onyxData); } -function downloadTagsCSV(policyID: string, onDownloadFailed: () => void) { +function downloadTagsCSV(policyID: string, onDownloadFailed: () => void, translate: LocalizedTranslate) { const finalParameters = enhanceParameters(WRITE_COMMANDS.EXPORT_TAGS_CSV, { policyID, }); @@ -1245,10 +1246,10 @@ function downloadTagsCSV(policyID: string, onDownloadFailed: () => void) { formData.append(key, String(value)); } - fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_TAGS_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); + fileDownload(translate, ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_TAGS_CSV}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } -function downloadMultiLevelTagsCSV(policyID: string, onDownloadFailed: () => void, hasDependentTags: boolean) { +function downloadMultiLevelTagsCSV(policyID: string, onDownloadFailed: () => void, hasDependentTags: boolean, translate: LocalizedTranslate) { const command = hasDependentTags ? WRITE_COMMANDS.EXPORT_MULTI_LEVEL_DEPENDENT_TAGS_CSV : WRITE_COMMANDS.EXPORT_MULTI_LEVEL_INDEPENDENT_TAGS_CSV; const finalParameters = enhanceParameters(command, { @@ -1261,7 +1262,7 @@ function downloadMultiLevelTagsCSV(policyID: string, onDownloadFailed: () => voi formData.append(key, String(value)); } - fileDownload(ApiUtils.getCommandURL({command}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); + fileDownload(translate, ApiUtils.getCommandURL({command}), fileName, '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } function getPolicyTagsData(policyID: string | undefined) { diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 0be98707ea04..baa920755cbd 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -7,7 +7,7 @@ import type {NullishDeep, OnyxCollection, OnyxCollectionInputValue, OnyxEntry, O import Onyx from 'react-native-onyx'; import type {PartialDeep, ValueOf} from 'type-fest'; import type {Emoji} from '@assets/emojis/types'; -import type {LocaleContextProps} from '@components/LocaleContextProvider'; +import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleContextProvider'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL'; import * as API from '@libs/API'; @@ -4848,7 +4848,7 @@ function markAsManuallyExported(reportID: string, connectionName: ConnectionName API.write(WRITE_COMMANDS.MARK_AS_EXPORTED, params, {optimisticData, successData, failureData}); } -function exportReportToCSV({reportID, transactionIDList}: ExportReportCSVParams, onDownloadFailed: () => void) { +function exportReportToCSV({reportID, transactionIDList}: ExportReportCSVParams, onDownloadFailed: () => void, translate: LocalizedTranslate) { let reportIDParam = reportID; const allReportTransactions = getReportTransactions(reportID).filter((transaction) => transaction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE); const allTransactionIDs = allReportTransactions.map((transaction) => transaction.transactionID); @@ -4869,7 +4869,7 @@ function exportReportToCSV({reportID, transactionIDList}: ExportReportCSVParams, } } - fileDownload(ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_REPORT_TO_CSV}), 'Expensify.csv', '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); + fileDownload(translate, ApiUtils.getCommandURL({command: WRITE_COMMANDS.EXPORT_REPORT_TO_CSV}), 'Expensify.csv', '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } function exportReportToPDF({reportID}: ExportReportPDFParams) { @@ -4895,14 +4895,14 @@ function exportReportToPDF({reportID}: ExportReportPDFParams) { API.write(WRITE_COMMANDS.EXPORT_REPORT_TO_PDF, params, {optimisticData, failureData}); } -function downloadReportPDF(fileName: string, reportName: string) { +function downloadReportPDF(fileName: string, reportName: string, translate: LocalizedTranslate) { const baseURL = addTrailingForwardSlash(getOldDotURLFromEnvironment(environment)); const downloadFileName = `${reportName}.pdf`; setDownload(fileName, true); const pdfURL = `${baseURL}secure?secureType=pdfreport&filename=${encodeURIComponent(fileName)}&downloadName=${encodeURIComponent(downloadFileName)}&email=${encodeURIComponent( currentUserEmail ?? '', )}`; - fileDownload(addEncryptedAuthTokenToURL(pdfURL, true), downloadFileName, '', Browser.isMobileSafari()).then(() => setDownload(fileName, false)); + fileDownload(translate, addEncryptedAuthTokenToURL(pdfURL, true), downloadFileName, '', Browser.isMobileSafari()).then(() => setDownload(fileName, false)); } function setDeleteTransactionNavigateBackUrl(url: string) { diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index 5fcd61753af9..a46d3415cdd7 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -826,7 +826,7 @@ function rejectMoneyRequestsOnSearch( type Params = Record; -function exportSearchItemsToCSV({query, jsonQuery, reportIDList, transactionIDList}: ExportSearchItemsToCSVParams, onDownloadFailed: () => void) { +function exportSearchItemsToCSV({query, jsonQuery, reportIDList, transactionIDList}: ExportSearchItemsToCSVParams, onDownloadFailed: () => void, translate: LocalizedTranslate) { const reportIDSet = new Set(); const transactionIDSet = new Set(transactionIDList); for (const reportID of reportIDList) { @@ -868,7 +868,7 @@ function exportSearchItemsToCSV({query, jsonQuery, reportIDList, transactionIDLi } } - fileDownload(getCommandURL({command: WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV}), 'Expensify.csv', '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); + fileDownload(translate, getCommandURL({command: WRITE_COMMANDS.EXPORT_SEARCH_ITEMS_TO_CSV}), 'Expensify.csv', '', false, formData, CONST.NETWORK.METHOD.POST, onDownloadFailed); } function queueExportSearchItemsToCSV({query, jsonQuery, reportIDList, transactionIDList}: ExportSearchItemsToCSVParams) { diff --git a/src/libs/fileDownload/DownloadUtils.ts b/src/libs/fileDownload/DownloadUtils.ts index 41716c87a827..57edfd117b72 100644 --- a/src/libs/fileDownload/DownloadUtils.ts +++ b/src/libs/fileDownload/DownloadUtils.ts @@ -29,8 +29,17 @@ const createDownloadLink = (href: string, fileName: string) => { /** * The function downloads an attachment on web/desktop platforms. */ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -const fetchFileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false, formData = undefined, requestType = 'get', onDownloadFailed?: () => void) => { +const fetchFileDownload: FileDownload = ( + translate, + url, + fileName, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + successMessage = '', + shouldOpenExternalLink = false, + formData = undefined, + requestType = 'get', + onDownloadFailed?: () => void, +) => { const resolvedUrl = tryResolveUrlFromApiRoot(url); const isApiUrl = resolvedUrl.startsWith(ApiUtils.getApiRoot()); diff --git a/src/libs/fileDownload/FileUtils.ts b/src/libs/fileDownload/FileUtils.ts index 1acc9174f007..2e9aa6ba9e32 100644 --- a/src/libs/fileDownload/FileUtils.ts +++ b/src/libs/fileDownload/FileUtils.ts @@ -5,9 +5,9 @@ import type {ReactNativeBlobUtilReadStream} from 'react-native-blob-util'; import ReactNativeBlobUtil from 'react-native-blob-util'; import ImageSize from 'react-native-image-size'; import type {TupleToUnion, ValueOf} from 'type-fest'; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import DateUtils from '@libs/DateUtils'; import getPlatform from '@libs/getPlatform'; -import {translateLocal} from '@libs/Localize'; import Log from '@libs/Log'; import saveLastRoute from '@libs/saveLastRoute'; import CONST from '@src/CONST'; @@ -21,15 +21,15 @@ import type {ReadFileAsync, SplitExtensionFromFileName} from './types'; * Show alert on successful attachment download * @param successMessage */ -function showSuccessAlert(successMessage?: string) { +function showSuccessAlert(translate: LocalizedTranslate, successMessage?: string) { Alert.alert( - translateLocal('fileDownload.success.title'), - // successMessage can be an empty string and we want to default to `Localize.translateLocal('fileDownload.success.message')` + translate('fileDownload.success.title'), + // successMessage can be an empty string and we want to default to `Localize.translate('fileDownload.success.message')` // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - successMessage || translateLocal('fileDownload.success.message'), + successMessage || translate('fileDownload.success.message'), [ { - text: translateLocal('common.ok'), + text: translate('common.ok'), style: 'cancel', }, ], @@ -40,10 +40,10 @@ function showSuccessAlert(successMessage?: string) { /** * Show alert on attachment download error */ -function showGeneralErrorAlert() { - Alert.alert(translateLocal('fileDownload.generalError.title'), translateLocal('fileDownload.generalError.message'), [ +function showGeneralErrorAlert(translate: LocalizedTranslate) { + Alert.alert(translate('fileDownload.generalError.title'), translate('fileDownload.generalError.message'), [ { - text: translateLocal('common.cancel'), + text: translate('common.cancel'), style: 'cancel', }, ]); @@ -52,14 +52,14 @@ function showGeneralErrorAlert() { /** * Show alert on attachment download permissions error */ -function showPermissionErrorAlert() { - Alert.alert(translateLocal('fileDownload.permissionError.title'), translateLocal('fileDownload.permissionError.message'), [ +function showPermissionErrorAlert(translate: LocalizedTranslate) { + Alert.alert(translate('fileDownload.permissionError.title'), translate('fileDownload.permissionError.message'), [ { - text: translateLocal('common.cancel'), + text: translate('common.cancel'), style: 'cancel', }, { - text: translateLocal('common.settings'), + text: translate('common.settings'), onPress: () => { Linking.openSettings(); }, @@ -70,17 +70,17 @@ function showPermissionErrorAlert() { /** * Inform the users when they need to grant camera access and guide them to settings */ -function showCameraPermissionsAlert() { +function showCameraPermissionsAlert(translate: LocalizedTranslate) { Alert.alert( - translateLocal('attachmentPicker.cameraPermissionRequired'), - translateLocal('attachmentPicker.expensifyDoesNotHaveAccessToCamera'), + translate('attachmentPicker.cameraPermissionRequired'), + translate('attachmentPicker.expensifyDoesNotHaveAccessToCamera'), [ { - text: translateLocal('common.cancel'), + text: translate('common.cancel'), style: 'cancel', }, { - text: translateLocal('common.settings'), + text: translate('common.settings'), onPress: () => { Linking.openSettings(); // In the case of ios, the App reloads when we update camera permission from settings @@ -606,6 +606,7 @@ type TranslationAdditionalData = { }; const getFileValidationErrorText = ( + translate: LocalizedTranslate, validationError: ValueOf | null, additionalData: TranslationAdditionalData = {}, isValidatingReceipt = false, @@ -623,71 +624,71 @@ const getFileValidationErrorText = ( switch (validationError) { case CONST.FILE_VALIDATION_ERRORS.WRONG_FILE_TYPE: return { - title: translateLocal('attachmentPicker.wrongFileType'), - reason: translateLocal('attachmentPicker.notAllowedExtension'), + title: translate('attachmentPicker.wrongFileType'), + reason: translate('attachmentPicker.notAllowedExtension'), }; case CONST.FILE_VALIDATION_ERRORS.WRONG_FILE_TYPE_MULTIPLE: return { - title: translateLocal('attachmentPicker.someFilesCantBeUploaded'), - reason: translateLocal('attachmentPicker.unsupportedFileType', {fileType: additionalData.fileType ?? ''}), + title: translate('attachmentPicker.someFilesCantBeUploaded'), + reason: translate('attachmentPicker.unsupportedFileType', {fileType: additionalData.fileType ?? ''}), }; case CONST.FILE_VALIDATION_ERRORS.FILE_TOO_LARGE: return { - title: translateLocal('attachmentPicker.attachmentTooLarge'), + title: translate('attachmentPicker.attachmentTooLarge'), reason: isValidatingReceipt - ? translateLocal('attachmentPicker.sizeExceededWithLimit', { + ? translate('attachmentPicker.sizeExceededWithLimit', { maxUploadSizeInMB: additionalData.maxUploadSizeInMB ?? CONST.API_ATTACHMENT_VALIDATIONS.RECEIPT_MAX_SIZE / 1024 / 1024, }) - : translateLocal('attachmentPicker.sizeExceeded'), + : translate('attachmentPicker.sizeExceeded'), }; case CONST.FILE_VALIDATION_ERRORS.FILE_TOO_LARGE_MULTIPLE: return { - title: translateLocal('attachmentPicker.someFilesCantBeUploaded'), - reason: translateLocal('attachmentPicker.sizeLimitExceeded', { + title: translate('attachmentPicker.someFilesCantBeUploaded'), + reason: translate('attachmentPicker.sizeLimitExceeded', { maxUploadSizeInMB: additionalData.maxUploadSizeInMB ?? maxSize / 1024 / 1024, }), }; case CONST.FILE_VALIDATION_ERRORS.FILE_TOO_SMALL: return { - title: translateLocal('attachmentPicker.attachmentTooSmall'), - reason: translateLocal('attachmentPicker.sizeNotMet'), + title: translate('attachmentPicker.attachmentTooSmall'), + reason: translate('attachmentPicker.sizeNotMet'), }; case CONST.FILE_VALIDATION_ERRORS.FOLDER_NOT_ALLOWED: return { - title: translateLocal('attachmentPicker.attachmentError'), - reason: translateLocal('attachmentPicker.folderNotAllowedMessage'), + title: translate('attachmentPicker.attachmentError'), + reason: translate('attachmentPicker.folderNotAllowedMessage'), }; case CONST.FILE_VALIDATION_ERRORS.MAX_FILE_LIMIT_EXCEEDED: return { - title: translateLocal('attachmentPicker.someFilesCantBeUploaded'), - reason: translateLocal('attachmentPicker.maxFileLimitExceeded'), + title: translate('attachmentPicker.someFilesCantBeUploaded'), + reason: translate('attachmentPicker.maxFileLimitExceeded'), }; case CONST.FILE_VALIDATION_ERRORS.FILE_CORRUPTED: return { - title: translateLocal('attachmentPicker.attachmentError'), - reason: translateLocal('attachmentPicker.errorWhileSelectingCorruptedAttachment'), + title: translate('attachmentPicker.attachmentError'), + reason: translate('attachmentPicker.errorWhileSelectingCorruptedAttachment'), }; case CONST.FILE_VALIDATION_ERRORS.PROTECTED_FILE: return { - title: translateLocal('attachmentPicker.attachmentError'), - reason: translateLocal('attachmentPicker.protectedPDFNotSupported'), + title: translate('attachmentPicker.attachmentError'), + reason: translate('attachmentPicker.protectedPDFNotSupported'), }; default: return { - title: translateLocal('attachmentPicker.attachmentError'), - reason: translateLocal('attachmentPicker.errorWhileSelectingCorruptedAttachment'), + title: translate('attachmentPicker.attachmentError'), + reason: translate('attachmentPicker.errorWhileSelectingCorruptedAttachment'), }; } }; -const getConfirmModalPrompt = (attachmentInvalidReason: TranslationPaths | undefined) => { +const getConfirmModalPrompt = (translate: LocalizedTranslate, attachmentInvalidReason: TranslationPaths | undefined) => { if (!attachmentInvalidReason) { return ''; } if (attachmentInvalidReason === 'attachmentPicker.sizeExceededWithLimit') { - return translateLocal(attachmentInvalidReason, {maxUploadSizeInMB: CONST.API_ATTACHMENT_VALIDATIONS.RECEIPT_MAX_SIZE / (1024 * 1024)}); + return translate(attachmentInvalidReason, {maxUploadSizeInMB: CONST.API_ATTACHMENT_VALIDATIONS.RECEIPT_MAX_SIZE / (1024 * 1024)}); } - return translateLocal(attachmentInvalidReason); + return translate(attachmentInvalidReason); }; const MAX_CANVAS_SIZE = 4096; diff --git a/src/libs/fileDownload/index.android.ts b/src/libs/fileDownload/index.android.ts index b46c25b07298..6a476d0ed9d9 100644 --- a/src/libs/fileDownload/index.android.ts +++ b/src/libs/fileDownload/index.android.ts @@ -2,6 +2,7 @@ import {PermissionsAndroid, Platform} from 'react-native'; import type {FetchBlobResponse} from 'react-native-blob-util'; import RNFetchBlob from 'react-native-blob-util'; import RNFS from 'react-native-fs'; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import CONST from '@src/CONST'; import {appendTimeToFileName, getFileName, showGeneralErrorAlert, showPermissionErrorAlert, showSuccessAlert} from './FileUtils'; import type {FileDownload} from './types'; @@ -35,7 +36,7 @@ function hasAndroidPermission(): Promise { /** * Handling the download */ -function handleDownload(url: string, fileName?: string, successMessage?: string, shouldUnlink = true): Promise { +function handleDownload(translate: LocalizedTranslate, url: string, fileName?: string, successMessage?: string, shouldUnlink = true): Promise { return new Promise((resolve) => { const dirs = RNFetchBlob.fs.dirs; @@ -87,16 +88,16 @@ function handleDownload(url: string, fileName?: string, successMessage?: string, if (attachmentPath && shouldUnlink) { RNFetchBlob.fs.unlink(attachmentPath); } - showSuccessAlert(successMessage); + showSuccessAlert(translate, successMessage); }) .catch(() => { - showGeneralErrorAlert(); + showGeneralErrorAlert(translate); }) .finally(() => resolve()); }); } -const postDownloadFile = (url: string, fileName?: string, formData?: FormData, onDownloadFailed?: () => void): Promise => { +const postDownloadFile = (translate: LocalizedTranslate, url: string, fileName?: string, formData?: FormData, onDownloadFailed?: () => void): Promise => { const fetchOptions: RequestInit = { method: 'POST', body: formData, @@ -131,11 +132,11 @@ const postDownloadFile = (url: string, fileName?: string, formData?: FormData, o ) .then((downloadPath) => { RNFetchBlob.fs.unlink(downloadPath); - showSuccessAlert(); + showSuccessAlert(translate); }) .catch(() => { if (!onDownloadFailed) { - showGeneralErrorAlert(); + showGeneralErrorAlert(translate); } onDownloadFailed?.(); }); @@ -144,20 +145,20 @@ const postDownloadFile = (url: string, fileName?: string, formData?: FormData, o /** * Checks permission and downloads the file for Android */ -const fileDownload: FileDownload = (url, fileName, successMessage, _, formData, requestType, onDownloadFailed, shouldUnlink) => +const fileDownload: FileDownload = (translate, url, fileName, successMessage, _, formData, requestType, onDownloadFailed, shouldUnlink) => new Promise((resolve) => { hasAndroidPermission() .then((hasPermission) => { if (hasPermission) { if (requestType === CONST.NETWORK.METHOD.POST) { - return postDownloadFile(url, fileName, formData, onDownloadFailed); + return postDownloadFile(translate, url, fileName, formData, onDownloadFailed); } - return handleDownload(url, fileName, successMessage, shouldUnlink); + return handleDownload(translate, url, fileName, successMessage, shouldUnlink); } - showPermissionErrorAlert(); + showPermissionErrorAlert(translate); }) .catch(() => { - showPermissionErrorAlert(); + showPermissionErrorAlert(translate); }) .finally(() => resolve()); }); diff --git a/src/libs/fileDownload/index.desktop.ts b/src/libs/fileDownload/index.desktop.ts index accd4905e53c..3d55b7b66275 100644 --- a/src/libs/fileDownload/index.desktop.ts +++ b/src/libs/fileDownload/index.desktop.ts @@ -7,10 +7,10 @@ import type {FileDownload} from './types'; /** * The function downloads an attachment on desktop platforms. */ -const fileDownload: FileDownload = (url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed?: () => void) => { +const fileDownload: FileDownload = (translate, url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed?: () => void) => { if (requestType === CONST.NETWORK.METHOD.POST) { window.electron.send(ELECTRON_EVENTS.DOWNLOAD); - return fetchFileDownload(url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed); + return fetchFileDownload(translate, url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed); } const options: Options = { diff --git a/src/libs/fileDownload/index.ios.ts b/src/libs/fileDownload/index.ios.ts index 73392072d9fe..1157c175ac53 100644 --- a/src/libs/fileDownload/index.ios.ts +++ b/src/libs/fileDownload/index.ios.ts @@ -3,6 +3,7 @@ import type {PhotoIdentifier} from '@react-native-camera-roll/camera-roll'; import RNFetchBlob from 'react-native-blob-util'; import RNFS from 'react-native-fs'; import Share from 'react-native-share'; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import CONST from '@src/CONST'; import {appendTimeToFileName, getFileName, getFileType, showGeneralErrorAlert, showPermissionErrorAlert, showSuccessAlert} from './FileUtils'; import type {FileDownload} from './types'; @@ -44,7 +45,7 @@ function downloadFile(fileUrl: string, fileName: string) { }).fetch('GET', fileUrl); } -const postDownloadFile = (url: string, fileName?: string, formData?: FormData, onDownloadFailed?: () => void) => { +const postDownloadFile = (translate: LocalizedTranslate, url: string, fileName?: string, formData?: FormData, onDownloadFailed?: () => void) => { const fetchOptions: RequestInit = { method: 'POST', body: formData, @@ -77,7 +78,7 @@ const postDownloadFile = (url: string, fileName?: string, formData?: FormData, o return; } if (!onDownloadFailed) { - showGeneralErrorAlert(); + showGeneralErrorAlert(translate); } onDownloadFailed?.(); }); @@ -124,7 +125,7 @@ function downloadVideo(fileUrl: string, fileName: string): Promise +const fileDownload: FileDownload = (translate, fileUrl, fileName, successMessage, _, formData, requestType, onDownloadFailed) => new Promise((resolve) => { let fileDownloadPromise; const fileType = getFileType(fileUrl); @@ -140,7 +141,7 @@ const fileDownload: FileDownload = (fileUrl, fileName, successMessage, _, formDa break; default: if (requestType === CONST.NETWORK.METHOD.POST) { - fileDownloadPromise = postDownloadFile(fileUrl, fileName, formData, onDownloadFailed); + fileDownloadPromise = postDownloadFile(translate, fileUrl, fileName, formData, onDownloadFailed); break; } @@ -154,15 +155,15 @@ const fileDownload: FileDownload = (fileUrl, fileName, successMessage, _, formDa return; } - showSuccessAlert(successMessage); + showSuccessAlert(translate, successMessage); }) .catch((err: Error) => { // iOS shows permission popup only once. Subsequent request will only throw an error. // We catch the error and show a redirection link to the settings screen if (err.message === CONST.IOS_CAMERA_ROLL_ACCESS_ERROR) { - showPermissionErrorAlert(); + showPermissionErrorAlert(translate); } else { - showGeneralErrorAlert(); + showGeneralErrorAlert(translate); } }) .finally(() => resolve()); diff --git a/src/libs/fileDownload/index.ts b/src/libs/fileDownload/index.ts index fc1ea6f74d9b..1df7023fa625 100644 --- a/src/libs/fileDownload/index.ts +++ b/src/libs/fileDownload/index.ts @@ -4,7 +4,15 @@ import type {FileDownload} from './types'; /** * The function downloads an attachment on web/desktop platforms. */ -const fileDownload: FileDownload = (url, fileName, successMessage = '', shouldOpenExternalLink = false, formData = undefined, requestType = 'get', onDownloadFailed?: () => void) => - fetchFileDownload(url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed); +const fileDownload: FileDownload = ( + translate, + url, + fileName, + successMessage = '', + shouldOpenExternalLink = false, + formData = undefined, + requestType = 'get', + onDownloadFailed?: () => void, +) => fetchFileDownload(translate, url, fileName, successMessage, shouldOpenExternalLink, formData, requestType, onDownloadFailed); export default fileDownload; diff --git a/src/libs/fileDownload/types.ts b/src/libs/fileDownload/types.ts index d94e9245f0fc..e8efbe131f31 100644 --- a/src/libs/fileDownload/types.ts +++ b/src/libs/fileDownload/types.ts @@ -1,7 +1,9 @@ import type {Asset} from 'react-native-image-picker'; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; import type {RequestType} from '@src/types/onyx/Request'; type FileDownload = ( + translate: LocalizedTranslate, url: string, fileName?: string, successMessage?: string, diff --git a/src/libs/localFileDownload/index.android.ts b/src/libs/localFileDownload/index.android.ts index 6573006154d4..b8b7a653bcb8 100644 --- a/src/libs/localFileDownload/index.android.ts +++ b/src/libs/localFileDownload/index.android.ts @@ -8,7 +8,7 @@ import type LocalFileDownload from './types'; * and textContent, so we're able to copy it to the Android public download dir. * After the file is copied, it is removed from the internal dir. */ -const localFileDownload: LocalFileDownload = (fileName, textContent, successMessage) => { +const localFileDownload: LocalFileDownload = (fileName, textContent, translate, successMessage) => { localFileCreate(fileName, textContent).then(({path, newFileName}) => { RNFetchBlob.MediaCollection.copyToMediaStore( { @@ -20,10 +20,10 @@ const localFileDownload: LocalFileDownload = (fileName, textContent, successMess path, ) .then(() => { - FileUtils.showSuccessAlert(successMessage); + FileUtils.showSuccessAlert(translate, successMessage); }) .catch(() => { - FileUtils.showGeneralErrorAlert(); + FileUtils.showGeneralErrorAlert(translate); }) .finally(() => { RNFetchBlob.fs.unlink(path); diff --git a/src/libs/localFileDownload/types.ts b/src/libs/localFileDownload/types.ts index 68e013e60bb3..182da40a11ed 100644 --- a/src/libs/localFileDownload/types.ts +++ b/src/libs/localFileDownload/types.ts @@ -1,3 +1,5 @@ -type LocalFileDownload = (fileName: string, textContent: string, successMessage?: string) => void; +import type {LocalizedTranslate} from '@components/LocaleContextProvider'; + +type LocalFileDownload = (fileName: string, textContent: string, translate: LocalizedTranslate, successMessage?: string) => void; export default LocalFileDownload; diff --git a/src/pages/Search/SearchPage.tsx b/src/pages/Search/SearchPage.tsx index 19709ee3f08d..eed7363a004d 100644 --- a/src/pages/Search/SearchPage.tsx +++ b/src/pages/Search/SearchPage.tsx @@ -388,6 +388,7 @@ function SearchPage({route}: SearchPageProps) { () => { setIsDownloadErrorModalVisible(true); }, + translate, ); clearSelectedTransactions(undefined, true); }, diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index dd2d41e14d67..4b9fe4d0e3c0 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -980,7 +980,7 @@ const ContextMenuActions: ContextMenuAction[] = [ const isUploading = html.includes(CONST.ATTACHMENT_OPTIMISTIC_SOURCE_ATTRIBUTE); return isAttachment && !isUploading && !!reportAction?.reportActionID && !isMessageDeleted(reportAction) && !isOffline; }, - onPress: (closePopover, {reportAction}) => { + onPress: (closePopover, {reportAction, translate}) => { const html = getActionHtml(reportAction); const {originalFileName, sourceURL} = getAttachmentDetails(html); const sourceURLWithAuth = addEncryptedAuthTokenToURL(sourceURL ?? ''); @@ -988,7 +988,7 @@ const ContextMenuActions: ContextMenuAction[] = [ setDownload(sourceID, true); const anchorRegex = CONST.REGEX_LINK_IN_ANCHOR; const isAnchorTag = anchorRegex.test(html); - fileDownload(sourceURLWithAuth, originalFileName ?? '', '', isAnchorTag && isMobileSafari()).then(() => setDownload(sourceID, false)); + fileDownload(translate, sourceURLWithAuth, originalFileName ?? '', '', isAnchorTag && isMobileSafari()).then(() => setDownload(sourceID, false)); if (closePopover) { hideContextMenu(true, ReportActionComposeFocusManager.focus); } diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 48e14d92491e..2c5c2e94c495 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -189,7 +189,7 @@ function IOURequestStepScan({ setCameraPermissionStatus(status); if (status === RESULTS.BLOCKED) { - showCameraPermissionsAlert(); + showCameraPermissionsAlert(translate); } }) .catch(() => { diff --git a/src/pages/media/AttachmentModalScreen/routes/hooks/useDownloadAttachment.ts b/src/pages/media/AttachmentModalScreen/routes/hooks/useDownloadAttachment.ts index 2ce970df91c2..482454f0190a 100644 --- a/src/pages/media/AttachmentModalScreen/routes/hooks/useDownloadAttachment.ts +++ b/src/pages/media/AttachmentModalScreen/routes/hooks/useDownloadAttachment.ts @@ -1,5 +1,6 @@ import {useCallback} from 'react'; import {Keyboard} from 'react-native'; +import useLocalize from '@hooks/useLocalize'; import addEncryptedAuthTokenToURL from '@libs/addEncryptedAuthTokenToURL'; import fileDownload from '@libs/fileDownload'; import {getFileName} from '@libs/fileDownload/FileUtils'; @@ -13,6 +14,7 @@ type UseDownloadAttachmentProps = { }; function useDownloadAttachment({isAuthTokenRequired, type, draftTransactionID}: UseDownloadAttachmentProps = {}) { + const {translate} = useLocalize(); /** * Download the currently viewed attachment. */ @@ -26,14 +28,14 @@ function useDownloadAttachment({isAuthTokenRequired, type, draftTransactionID}: if (typeof sourceURL === 'string') { const fileName = type === CONST.ATTACHMENT_TYPE.SEARCH ? getFileName(`${sourceURL}`) : file?.name; const shouldUnlink = !draftTransactionID; - fileDownload(sourceURL, fileName ?? '', undefined, undefined, undefined, undefined, undefined, shouldUnlink); + fileDownload(translate, sourceURL, fileName ?? '', undefined, undefined, undefined, undefined, undefined, shouldUnlink); } // At ios, if the keyboard is open while opening the attachment, then after downloading // the attachment keyboard will show up. So, to fix it we need to dismiss the keyboard. Keyboard.dismiss(); }, - [isAuthTokenRequired, type, draftTransactionID], + [isAuthTokenRequired, type, draftTransactionID, translate], ); return downloadAttachment; diff --git a/src/pages/settings/AboutPage/ConsolePage.tsx b/src/pages/settings/AboutPage/ConsolePage.tsx index 5c6a5e1a454d..f4e7ba7023b1 100644 --- a/src/pages/settings/AboutPage/ConsolePage.tsx +++ b/src/pages/settings/AboutPage/ConsolePage.tsx @@ -119,7 +119,7 @@ function ConsolePage() { const saveLogs = () => { const logsWithParsedMessages = parseStringifiedMessages(filteredLogsList); - localFileDownload('logs', JSON.stringify(logsWithParsedMessages, null, 2)); + localFileDownload('logs', JSON.stringify(logsWithParsedMessages, null, 2), translate); }; const shareLogs = () => { diff --git a/src/pages/settings/Security/TwoFactorAuth/CopyCodesPage.tsx b/src/pages/settings/Security/TwoFactorAuth/CopyCodesPage.tsx index 5af06e4aeb0e..4b12737ed630 100644 --- a/src/pages/settings/Security/TwoFactorAuth/CopyCodesPage.tsx +++ b/src/pages/settings/Security/TwoFactorAuth/CopyCodesPage.tsx @@ -124,7 +124,7 @@ function CopyCodesPage({route}: TwoFactorAuthPageProps) { text={translate('common.download')} icon={icons.Download} onPress={() => { - localFileDownload('two-factor-auth-codes', account?.recoveryCodes ?? ''); + localFileDownload('two-factor-auth-codes', account?.recoveryCodes ?? '', translate); setError(''); setCodesAreCopied(); }} diff --git a/src/pages/wallet/WalletStatementPage.tsx b/src/pages/wallet/WalletStatementPage.tsx index e6208ebe7cf0..69e190816654 100644 --- a/src/pages/wallet/WalletStatementPage.tsx +++ b/src/pages/wallet/WalletStatementPage.tsx @@ -56,12 +56,12 @@ function WalletStatementPage({route}: WalletStatementPageProps) { const downloadFileName = `Expensify_Statement_${yearMonth}.pdf`; const fileName = walletStatement[yearMonth]; const pdfURL = `${baseURL}secure?secureType=pdfreport&filename=${fileName}&downloadName=${downloadFileName}`; - fileDownload(pdfURL, downloadFileName).finally(() => setIsDownloading(false)); + fileDownload(translate, pdfURL, downloadFileName).finally(() => setIsDownloading(false)); return; } generateStatementPDF(yearMonth); - }, [baseURL, isWalletStatementGenerating, walletStatement, yearMonth]); + }, [baseURL, isWalletStatementGenerating, translate, walletStatement, yearMonth]); // eslint-disable-next-line rulesdir/prefer-early-return useEffect(() => { diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx index 26a0da6ea93c..edf28578e448 100644 --- a/src/pages/workspace/WorkspaceMembersPage.tsx +++ b/src/pages/workspace/WorkspaceMembersPage.tsx @@ -661,9 +661,13 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers } close(() => { - downloadMembersCSV(policyID, () => { - setIsDownloadFailureModalVisible(true); - }); + downloadMembersCSV( + policyID, + () => { + setIsDownloadFailureModalVisible(true); + }, + translate, + ); }); }, value: CONST.POLICY.SECONDARY_ACTIONS.DOWNLOAD_CSV, diff --git a/src/pages/workspace/accounting/intacct/SageIntacctPrerequisitesPage.tsx b/src/pages/workspace/accounting/intacct/SageIntacctPrerequisitesPage.tsx index c850587a6582..fe7b063c3cf1 100644 --- a/src/pages/workspace/accounting/intacct/SageIntacctPrerequisitesPage.tsx +++ b/src/pages/workspace/accounting/intacct/SageIntacctPrerequisitesPage.tsx @@ -42,7 +42,7 @@ function SageIntacctPrerequisitesPage({route}: SageIntacctPrerequisitesPageProps iconRight: icons.NewWindow, shouldShowRightIcon: true, onPress: () => { - fileDownload(CONST.EXPENSIFY_PACKAGE_FOR_SAGE_INTACCT, CONST.EXPENSIFY_PACKAGE_FOR_SAGE_INTACCT_FILE_NAME, '', true); + fileDownload(translate, CONST.EXPENSIFY_PACKAGE_FOR_SAGE_INTACCT, CONST.EXPENSIFY_PACKAGE_FOR_SAGE_INTACCT_FILE_NAME, '', true); }, onSecondaryInteraction: (event: GestureResponderEvent | MouseEvent) => showContextMenu({ diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index 5aa1104670bd..65028ba66b54 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -343,9 +343,13 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { return; } close(() => { - downloadCategoriesCSV(policyId, () => { - setIsDownloadFailureModalVisible(true); - }); + downloadCategoriesCSV( + policyId, + () => { + setIsDownloadFailureModalVisible(true); + }, + translate, + ); }); }, value: CONST.POLICY.SECONDARY_ACTIONS.DOWNLOAD_CSV, diff --git a/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx b/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx index dbc5dbb508ce..496bb07cc6ee 100644 --- a/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx +++ b/src/pages/workspace/perDiem/WorkspacePerDiemPage.tsx @@ -303,9 +303,13 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) { return; } close(() => - downloadPerDiemCSV(policyID, () => { - setIsDownloadFailureModalVisible(true); - }), + downloadPerDiemCSV( + policyID, + () => { + setIsDownloadFailureModalVisible(true); + }, + translate, + ), ); }, value: CONST.POLICY.SECONDARY_ACTIONS.DOWNLOAD_CSV, diff --git a/src/pages/workspace/tags/ImportTagsOptionsPage.tsx b/src/pages/workspace/tags/ImportTagsOptionsPage.tsx index f7db88b337f5..324754ae1789 100644 --- a/src/pages/workspace/tags/ImportTagsOptionsPage.tsx +++ b/src/pages/workspace/tags/ImportTagsOptionsPage.tsx @@ -117,13 +117,18 @@ function ImportTagsOptionsPage({route}: ImportTagsOptionsPageProps) { }); }, hasDependentTags, + translate, ); } else { - downloadTagsCSV(policyID, () => { - close(() => { - setIsDownloadFailureModalVisible(true); - }); - }); + downloadTagsCSV( + policyID, + () => { + close(() => { + setIsDownloadFailureModalVisible(true); + }); + }, + translate, + ); } }} > @@ -149,13 +154,18 @@ function ImportTagsOptionsPage({route}: ImportTagsOptionsPageProps) { }); }, hasDependentTags, + translate, ); } else { - downloadTagsCSV(policyID, () => { - close(() => { - setIsDownloadFailureModalVisible(true); - }); - }); + downloadTagsCSV( + policyID, + () => { + close(() => { + setIsDownloadFailureModalVisible(true); + }); + }, + translate, + ); } }} > diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index 1ee498d84cd8..11e5b9d86f92 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -430,11 +430,16 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { setIsDownloadFailureModalVisible(true); }, hasDependentTags, + translate, ); } else { - downloadTagsCSV(policyID, () => { - setIsDownloadFailureModalVisible(true); - }); + downloadTagsCSV( + policyID, + () => { + setIsDownloadFailureModalVisible(true); + }, + translate, + ); } }); },