From 4fa79fd5a73bb49cada0ef7b2c7d2232454ca758 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 14:01:38 +0200 Subject: [PATCH 01/31] Add error message --- src/components/StatePicker/StateSelectorModal.js | 2 +- src/languages/en.ts | 2 ++ src/languages/types.ts | 3 +++ src/libs/actions/IOU.js | 4 ++-- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/StatePicker/StateSelectorModal.js b/src/components/StatePicker/StateSelectorModal.js index 378dcc4ebc8b..30379c72c4a0 100644 --- a/src/components/StatePicker/StateSelectorModal.js +++ b/src/components/StatePicker/StateSelectorModal.js @@ -10,7 +10,7 @@ import useLocalize from '../../hooks/useLocalize'; import ScreenWrapper from '../ScreenWrapper'; import styles from '../../styles/styles'; import searchCountryOptions from '../../libs/searchCountryOptions'; -import StringUtils from '../../libs/StringUtils'; +import * as StringUtils from '../../libs/StringUtils'; const propTypes = { /** Whether the modal is visible */ diff --git a/src/languages/en.ts b/src/languages/en.ts index f69f9ea4bedd..edbac8d1dc61 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -74,6 +74,7 @@ import type { FormattedMaxLengthParams, RequestedAmountMessageParams, TagSelectionParams, + ReceiptCreateFailureMessageParams, TranslationBase, WalletProgramParams, } from './types'; @@ -567,6 +568,7 @@ export default { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', genericCreateFailureMessage: 'Unexpected error requesting money, please try again later', + receiptCreateFailureMessage: ({receiptUrl}: ReceiptCreateFailureMessageParams) => `The receipt didn't upload. Save the file or dismiss this error and lose it.`, genericDeleteFailureMessage: 'Unexpected error deleting the money request, please try again later', genericEditFailureMessage: 'Unexpected error editing the money request, please try again later', genericSmartscanFailureMessage: 'Transaction is missing fields', diff --git a/src/languages/types.ts b/src/languages/types.ts index 3ee504ccddd7..193f226899d6 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -198,6 +198,8 @@ type FormattedMaxLengthParams = {formattedMaxLength: string}; type TagSelectionParams = {tagName: string}; +type ReceiptCreateFailureMessageParams = {tagName: string}; + type WalletProgramParams = {walletProgram: string}; /* Translation Object types */ @@ -313,6 +315,7 @@ export type { RemovedTheRequestParams, FormattedMaxLengthParams, TagSelectionParams, + ReceiptCreateFailureMessageParams, SetTheDistanceParams, UpdatedTheDistanceParams, WalletProgramParams, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index d5676672dd33..de6fdccd7b4e 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -349,12 +349,12 @@ function buildOnyxDataForMoneyRequest( errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, [iouAction.reportActionID]: { - errors: ErrorUtils.getMicroSecondOnyxError(null), + errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxError(Localize.translateLocal('iou.error.receiptCreateFailureMessage', {receiptUrl: transaction.receipt.source})) : ErrorUtils.getMicroSecondOnyxError(null), }, } : { [iouAction.reportActionID]: { - errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxError(Localize.translateLocal('iou.error.receiptCreateFailureMessage', {receiptUrl: transaction.receipt.source})) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }), }, From 418f5d7246330c1db21db885e7c849eeb546f165 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 14:02:27 +0200 Subject: [PATCH 02/31] handle htmL --- src/components/DotIndicatorMessage.js | 5 ++++- src/libs/StringUtils.ts | 15 ++++++++++++++- .../PersonalDetails/CountrySelectionPage.js | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index b3528b43dc75..f5d2bbbd5b1e 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -8,6 +8,9 @@ import * as Expensicons from './Icon/Expensicons'; import themeColors from '../styles/themes/default'; import Text from './Text'; import * as Localize from '../libs/Localize'; +import {hasHTML} from "../libs/StringUtils"; +import RenderHTML from "./RenderHTML"; +import * as StringUtils from "../libs/StringUtils"; const propTypes = { /** @@ -66,7 +69,7 @@ function DotIndicatorMessage(props) { key={i} style={styles.offlineFeedback.text} > - {message} + {StringUtils.hasHTML(message) ? : message} ))} diff --git a/src/libs/StringUtils.ts b/src/libs/StringUtils.ts index 8ef23bb0751b..b7021010aa05 100644 --- a/src/libs/StringUtils.ts +++ b/src/libs/StringUtils.ts @@ -10,4 +10,17 @@ function sanitizeString(str: string): string { return _.deburr(str).toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''); } -export default {sanitizeString}; +/** + * Very simple function to identify if a string contains HTML elements. WARNING: Things like '' will return true + * @param str - The string to check. + * @returns True if it contains html elements + */ +function hasHTML(str: string): boolean { + const regex = new RegExp('/<\\/?[a-z][\\s\\S]*>/', 'i'); + return regex.test(str) +} + +export { + sanitizeString, + hasHTML, +}; diff --git a/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js b/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js index 741974776df1..ef19ba6aad9d 100644 --- a/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js +++ b/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js @@ -7,7 +7,7 @@ import ScreenWrapper from '../../../../components/ScreenWrapper'; import HeaderWithBackButton from '../../../../components/HeaderWithBackButton'; import SelectionList from '../../../../components/SelectionList'; import searchCountryOptions from '../../../../libs/searchCountryOptions'; -import StringUtils from '../../../../libs/StringUtils'; +import * as StringUtils from '../../../../libs/StringUtils'; import CONST from '../../../../CONST'; import useLocalize from '../../../../hooks/useLocalize'; From ccda700add1f128ac8c882507f532d8ea56058fa Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 14:12:11 +0200 Subject: [PATCH 03/31] fix regex --- src/libs/StringUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/StringUtils.ts b/src/libs/StringUtils.ts index b7021010aa05..ae0df0e563d3 100644 --- a/src/libs/StringUtils.ts +++ b/src/libs/StringUtils.ts @@ -16,7 +16,7 @@ function sanitizeString(str: string): string { * @returns True if it contains html elements */ function hasHTML(str: string): boolean { - const regex = new RegExp('/<\\/?[a-z][\\s\\S]*>/', 'i'); + const regex = new RegExp('', 'i'); return regex.test(str) } From ee3fbdb2f6903a8bf8b426a9cf340a8145829c83 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 14:12:48 +0200 Subject: [PATCH 04/31] style --- src/components/DotIndicatorMessage.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index f5d2bbbd5b1e..3ed660865cc9 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -8,9 +8,8 @@ import * as Expensicons from './Icon/Expensicons'; import themeColors from '../styles/themes/default'; import Text from './Text'; import * as Localize from '../libs/Localize'; -import {hasHTML} from "../libs/StringUtils"; -import RenderHTML from "./RenderHTML"; -import * as StringUtils from "../libs/StringUtils"; +import RenderHTML from './RenderHTML'; +import * as StringUtils from '../libs/StringUtils'; const propTypes = { /** From 6cb7230ef7cd786c2e716b0b68d97ff01699d574 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 17:00:23 +0200 Subject: [PATCH 05/31] use object for error --- src/CONST.ts | 1 + src/components/DotIndicatorMessage.js | 20 ++++++++++++++++++-- src/libs/actions/IOU.js | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index 55fd7faa5a6a..2651fb057a92 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1118,6 +1118,7 @@ const CONST = { DOCX: 'docx', SVG: 'svg', }, + RECEIPT_ERROR: 'receiptError', }, GROWL: { diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 3ed660865cc9..e74974846141 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -10,6 +10,7 @@ import Text from './Text'; import * as Localize from '../libs/Localize'; import RenderHTML from './RenderHTML'; import * as StringUtils from '../libs/StringUtils'; +import CONST from '../CONST'; const propTypes = { /** @@ -39,6 +40,13 @@ function DotIndicatorMessage(props) { return null; } + function isReceiptError (message) { + if (_.isString(message)) { + return false; + } + return _.get(message, 'error', '') === CONST.IOU.RECEIPT_ERROR; + } + // To ensure messages are presented in order we are sort of destroying the data we are given // and rebuilding as an array so we can render the messages in order. We don't really care about // the microtime timestamps anyways so isn't the end of the world that we sort of lose them here. @@ -64,13 +72,21 @@ function DotIndicatorMessage(props) { {_.map(sortedMessages, (message, i) => ( + isReceiptError(message) ? ( + + bla + + ) : ( - {StringUtils.hasHTML(message) ? : message} + {message} - ))} + )))} ); diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index de6fdccd7b4e..60b5b1f1fad6 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -354,7 +354,7 @@ function buildOnyxDataForMoneyRequest( } : { [iouAction.reportActionID]: { - errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxError(Localize.translateLocal('iou.error.receiptCreateFailureMessage', {receiptUrl: transaction.receipt.source})) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: transaction.receipt ? {[DateUtils.getMicroseconds()]: {error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}} : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }), }, From 874985736bd4b2343b0d0d667c2c03010bcc82a9 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 17:23:20 +0200 Subject: [PATCH 06/31] Use new approach --- src/components/DotIndicatorMessage.js | 38 ++++++++++++++++++++------- src/languages/en.ts | 4 ++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index e74974846141..4486d439a05f 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -1,16 +1,17 @@ import React from 'react'; import _ from 'underscore'; import PropTypes from 'prop-types'; -import {View} from 'react-native'; +import {Keyboard, View} from 'react-native'; import styles from '../styles/styles'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import themeColors from '../styles/themes/default'; import Text from './Text'; import * as Localize from '../libs/Localize'; -import RenderHTML from './RenderHTML'; -import * as StringUtils from '../libs/StringUtils'; import CONST from '../CONST'; +import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; +import addEncryptedAuthTokenToURL from "../libs/addEncryptedAuthTokenToURL"; +import fileDownload from '../libs/fileDownload'; const propTypes = { /** @@ -40,12 +41,19 @@ function DotIndicatorMessage(props) { return null; } - function isReceiptError (message) { + const isReceiptError = (message) => { if (_.isString(message)) { return false; } return _.get(message, 'error', '') === CONST.IOU.RECEIPT_ERROR; - } + }; + + /** + * Download the failed receipt. + */ + const downloadReceipt = (source, filename) => { + fileDownload(source, filename); + }; // To ensure messages are presented in order we are sort of destroying the data we are given // and rebuilding as an array so we can render the messages in order. We don't really care about @@ -73,12 +81,22 @@ function DotIndicatorMessage(props) { {_.map(sortedMessages, (message, i) => ( isReceiptError(message) ? ( - { + downloadReceipt(message.source, message.filename) + }} > - bla - + + {Localize.translateLocal('iou.error.receiptFailureMessage')} + {Localize.translateLocal('iou.error.saveFileMessage')} + {Localize.translateLocal('iou.error.loseFileMessage')} + + ) : ( `The receipt didn't upload. Save the file or dismiss this error and lose it.`, + receiptFailureMessage: 'The receipt didn\'t upload. ', + saveFileMessage: 'Save the file ', + loseFileMessage: 'or dismiss this error and lose it', genericDeleteFailureMessage: 'Unexpected error deleting the money request, please try again later', genericEditFailureMessage: 'Unexpected error editing the money request, please try again later', genericSmartscanFailureMessage: 'Transaction is missing fields', From 52f5e509b699ebaf1235e32f9f8988defe497738 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 17:59:10 +0200 Subject: [PATCH 07/31] use function --- src/components/DotIndicatorMessage.js | 1 - src/languages/en.ts | 1 - src/languages/types.ts | 3 --- src/libs/ErrorUtils.ts | 10 +++++++++- src/libs/actions/IOU.js | 4 ++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 4486d439a05f..afb59114cc6d 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -10,7 +10,6 @@ import Text from './Text'; import * as Localize from '../libs/Localize'; import CONST from '../CONST'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; -import addEncryptedAuthTokenToURL from "../libs/addEncryptedAuthTokenToURL"; import fileDownload from '../libs/fileDownload'; const propTypes = { diff --git a/src/languages/en.ts b/src/languages/en.ts index 9dfeddcc2f36..d4c5e300708d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -74,7 +74,6 @@ import type { FormattedMaxLengthParams, RequestedAmountMessageParams, TagSelectionParams, - ReceiptCreateFailureMessageParams, TranslationBase, WalletProgramParams, } from './types'; diff --git a/src/languages/types.ts b/src/languages/types.ts index 193f226899d6..3ee504ccddd7 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -198,8 +198,6 @@ type FormattedMaxLengthParams = {formattedMaxLength: string}; type TagSelectionParams = {tagName: string}; -type ReceiptCreateFailureMessageParams = {tagName: string}; - type WalletProgramParams = {walletProgram: string}; /* Translation Object types */ @@ -315,7 +313,6 @@ export type { RemovedTheRequestParams, FormattedMaxLengthParams, TagSelectionParams, - ReceiptCreateFailureMessageParams, SetTheDistanceParams, UpdatedTheDistanceParams, WalletProgramParams, diff --git a/src/libs/ErrorUtils.ts b/src/libs/ErrorUtils.ts index bf4fc0d810a4..4be126830500 100644 --- a/src/libs/ErrorUtils.ts +++ b/src/libs/ErrorUtils.ts @@ -42,6 +42,14 @@ function getMicroSecondOnyxError(error: string): Record { return {[DateUtils.getMicroseconds()]: error}; } +/** + * Method used to get an error object with microsecond as the key and am object as the value. + * @param error - error key or message to be saved + */ +function getMicroSecondOnyxErrorObject(error: Record): Record> { + return {[DateUtils.getMicroseconds()]: error}; +} + type OnyxDataWithErrors = { errors?: Errors; }; @@ -111,4 +119,4 @@ function addErrorMessage(errors: ErrorsList, inputID?: string, message?: string) } } -export {getAuthenticateErrorMessage, getMicroSecondOnyxError, getLatestErrorMessage, getLatestErrorField, getEarliestErrorField, addErrorMessage}; +export {getAuthenticateErrorMessage, getMicroSecondOnyxError, getMicroSecondOnyxErrorObject, getLatestErrorMessage, getLatestErrorField, getEarliestErrorField, addErrorMessage}; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 60b5b1f1fad6..a6e028b6e7ea 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -349,12 +349,12 @@ function buildOnyxDataForMoneyRequest( errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, [iouAction.reportActionID]: { - errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxError(Localize.translateLocal('iou.error.receiptCreateFailureMessage', {receiptUrl: transaction.receipt.source})) : ErrorUtils.getMicroSecondOnyxError(null), + errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) : ErrorUtils.getMicroSecondOnyxError(null), }, } : { [iouAction.reportActionID]: { - errors: transaction.receipt ? {[DateUtils.getMicroseconds()]: {error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}} : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }), }, From d97beb33efe4d1febd628b3a6baaa8c65666e19b Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 18:00:30 +0200 Subject: [PATCH 08/31] remove unneeded helper function --- src/components/StatePicker/StateSelectorModal.js | 2 +- src/libs/StringUtils.ts | 15 +-------------- .../PersonalDetails/CountrySelectionPage.js | 2 +- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/components/StatePicker/StateSelectorModal.js b/src/components/StatePicker/StateSelectorModal.js index 30379c72c4a0..378dcc4ebc8b 100644 --- a/src/components/StatePicker/StateSelectorModal.js +++ b/src/components/StatePicker/StateSelectorModal.js @@ -10,7 +10,7 @@ import useLocalize from '../../hooks/useLocalize'; import ScreenWrapper from '../ScreenWrapper'; import styles from '../../styles/styles'; import searchCountryOptions from '../../libs/searchCountryOptions'; -import * as StringUtils from '../../libs/StringUtils'; +import StringUtils from '../../libs/StringUtils'; const propTypes = { /** Whether the modal is visible */ diff --git a/src/libs/StringUtils.ts b/src/libs/StringUtils.ts index ae0df0e563d3..8ef23bb0751b 100644 --- a/src/libs/StringUtils.ts +++ b/src/libs/StringUtils.ts @@ -10,17 +10,4 @@ function sanitizeString(str: string): string { return _.deburr(str).toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''); } -/** - * Very simple function to identify if a string contains HTML elements. WARNING: Things like '' will return true - * @param str - The string to check. - * @returns True if it contains html elements - */ -function hasHTML(str: string): boolean { - const regex = new RegExp('', 'i'); - return regex.test(str) -} - -export { - sanitizeString, - hasHTML, -}; +export default {sanitizeString}; diff --git a/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js b/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js index ef19ba6aad9d..741974776df1 100644 --- a/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js +++ b/src/pages/settings/Profile/PersonalDetails/CountrySelectionPage.js @@ -7,7 +7,7 @@ import ScreenWrapper from '../../../../components/ScreenWrapper'; import HeaderWithBackButton from '../../../../components/HeaderWithBackButton'; import SelectionList from '../../../../components/SelectionList'; import searchCountryOptions from '../../../../libs/searchCountryOptions'; -import * as StringUtils from '../../../../libs/StringUtils'; +import StringUtils from '../../../../libs/StringUtils'; import CONST from '../../../../CONST'; import useLocalize from '../../../../hooks/useLocalize'; From ca1443a94469d02637aac37375c74e208973a8ac Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 17 Oct 2023 18:06:51 +0200 Subject: [PATCH 09/31] spanish --- src/languages/es.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/languages/es.ts b/src/languages/es.ts index 83e09b2a62c0..913056364970 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -561,6 +561,9 @@ export default { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', genericCreateFailureMessage: 'Error inesperado solicitando dinero, Por favor, inténtalo más tarde', + receiptFailureMessage: 'El recibo no se subió. ', + saveFileMessage: 'Guarda el archivo ', + loseFileMessage: 'o descarta este error y piérdelo', genericDeleteFailureMessage: 'Error inesperado eliminando la solicitud de dinero. Por favor, inténtalo más tarde', genericEditFailureMessage: 'Error inesperado al guardar la solicitud de dinero. Por favor, inténtalo más tarde', genericSmartscanFailureMessage: 'La transacción tiene campos vacíos', From 0c559d1a9affc62563acda575a22cb8e6a8185c4 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 18 Oct 2023 13:10:37 +0200 Subject: [PATCH 10/31] lint --- src/components/DotIndicatorMessage.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index afb59114cc6d..2b1e4ceac97f 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -1,7 +1,7 @@ import React from 'react'; import _ from 'underscore'; import PropTypes from 'prop-types'; -import {Keyboard, View} from 'react-native'; +import {View} from 'react-native'; import styles from '../styles/styles'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; @@ -49,6 +49,9 @@ function DotIndicatorMessage(props) { /** * Download the failed receipt. + * + * @param {String} source + * @param {String} filename */ const downloadReceipt = (source, filename) => { fileDownload(source, filename); From 08d8e8667d4e24e83ff50eed7ee0b1e42372ac79 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 18 Oct 2023 13:25:59 +0200 Subject: [PATCH 11/31] prettier --- src/components/DotIndicatorMessage.js | 19 ++++++++++--------- src/languages/en.ts | 2 +- src/libs/actions/IOU.js | 8 ++++++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 2b1e4ceac97f..2683e24e6e8e 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -81,12 +81,12 @@ function DotIndicatorMessage(props) { /> - {_.map(sortedMessages, (message, i) => ( + {_.map(sortedMessages, (message, i) => isReceiptError(message) ? ( { - downloadReceipt(message.source, message.filename) + downloadReceipt(message.source, message.filename); }} > ) : ( - - {message} - - )))} + + {message} + + ), + )} ); diff --git a/src/languages/en.ts b/src/languages/en.ts index d4c5e300708d..57d5eaf11e82 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -567,7 +567,7 @@ export default { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', genericCreateFailureMessage: 'Unexpected error requesting money, please try again later', - receiptFailureMessage: 'The receipt didn\'t upload. ', + receiptFailureMessage: "The receipt didn't upload. ", saveFileMessage: 'Save the file ', loseFileMessage: 'or dismiss this error and lose it', genericDeleteFailureMessage: 'Unexpected error deleting the money request, please try again later', diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a6e028b6e7ea..2d19366e657a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -349,12 +349,16 @@ function buildOnyxDataForMoneyRequest( errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, [iouAction.reportActionID]: { - errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) : ErrorUtils.getMicroSecondOnyxError(null), + errors: transaction.receipt + ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) + : ErrorUtils.getMicroSecondOnyxError(null), }, } : { [iouAction.reportActionID]: { - errors: transaction.receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: transaction.receipt + ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) + : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }), }, From 040c5edcb4326211493d100e88203699dd271be4 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 18 Oct 2023 16:48:05 +0200 Subject: [PATCH 12/31] allow multiple lines --- src/components/DotIndicatorMessage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 2683e24e6e8e..ef838fb0ed4a 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -92,7 +92,6 @@ function DotIndicatorMessage(props) { {Localize.translateLocal('iou.error.receiptFailureMessage')} {Localize.translateLocal('iou.error.saveFileMessage')} From 17a1c43ba0dab4f7d41e7256bb6b8942cf7e215f Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 19 Oct 2023 12:04:11 +0200 Subject: [PATCH 13/31] add split flow --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 2256b72e3851..c9bcf60e88ac 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1413,7 +1413,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, value: { [splitIOUReportAction.reportActionID]: { - errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }, }); @@ -1436,7 +1436,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co errors: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage'), }, [splitIOUReportAction.reportActionID]: { - errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }, }, From 1d95f4613ca3567efc635e1b0c3c308c8015cc1d Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 19 Oct 2023 12:36:17 +0200 Subject: [PATCH 14/31] use isEmpty --- src/libs/actions/IOU.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index c9bcf60e88ac..a223ce212d70 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -359,16 +359,16 @@ function buildOnyxDataForMoneyRequest( errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, [iouAction.reportActionID]: { - errors: transaction.receipt - ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) - : ErrorUtils.getMicroSecondOnyxError(null), + errors: _.isEmpty(transaction.receipt) + ? ErrorUtils.getMicroSecondOnyxError(null) + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), }, } : { [iouAction.reportActionID]: { - errors: transaction.receipt - ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}) - : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: !_.isEmpty(transaction.receipt) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), }, }), }, @@ -1413,7 +1413,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, value: { [splitIOUReportAction.reportActionID]: { - errors: receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: _.isEmpty(receipt) ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), }, }, }); @@ -1436,7 +1436,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co errors: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage'), }, [splitIOUReportAction.reportActionID]: { - errors: receipt ? ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}) : ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: _.isEmpty(receipt) ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), }, }, }, From 0d010f9ede36a4c616d160fbbe98d4f2f7e90463 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 19 Oct 2023 12:47:24 +0200 Subject: [PATCH 15/31] use empty for split --- src/libs/actions/IOU.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a223ce212d70..554e52f7383f 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1413,7 +1413,9 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, value: { [splitIOUReportAction.reportActionID]: { - errors: _.isEmpty(receipt) ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), + errors: _.isEmpty(receipt) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), }, }, }); @@ -1436,7 +1438,9 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co errors: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage'), }, [splitIOUReportAction.reportActionID]: { - errors: _.isEmpty(receipt) ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), + errors: _.isEmpty(receipt) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), }, }, }, From 42e4ba3fcf441b58dff9e254121af0787da03316 Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 30 Oct 2023 12:10:04 +0100 Subject: [PATCH 16/31] import update --- src/components/DotIndicatorMessage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index bfd572bc50b3..e02635f35973 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -9,9 +9,9 @@ import themeColors from '@styles/themes/default'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import Text from './Text'; -import CONST from '../CONST'; +import CONST from '@src/CONST'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; -import fileDownload from '../libs/fileDownload'; +import fileDownload from '@libs/fileDownload'; const propTypes = { /** From 8b0382b5805d11020cea62925a4cceace0521c6b Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 30 Oct 2023 12:18:51 +0100 Subject: [PATCH 17/31] reorder --- src/components/DotIndicatorMessage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index e02635f35973..fa8c7bd67c97 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -3,15 +3,15 @@ import React from 'react'; import {View} from 'react-native'; import _ from 'underscore'; import * as Localize from '@libs/Localize'; +import fileDownload from '@libs/fileDownload'; import stylePropTypes from '@styles/stylePropTypes'; import styles from '@styles/styles'; import themeColors from '@styles/themes/default'; +import CONST from '@src/CONST'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import Text from './Text'; -import CONST from '@src/CONST'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; -import fileDownload from '@libs/fileDownload'; const propTypes = { /** From f8ce4eb16ff1c6dee199ffc7c002ac62da6a12ed Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 30 Oct 2023 12:44:12 +0100 Subject: [PATCH 18/31] prettier --- src/components/DotIndicatorMessage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index fa8c7bd67c97..31b96899ef56 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -2,16 +2,16 @@ import PropTypes from 'prop-types'; import React from 'react'; import {View} from 'react-native'; import _ from 'underscore'; -import * as Localize from '@libs/Localize'; import fileDownload from '@libs/fileDownload'; +import * as Localize from '@libs/Localize'; import stylePropTypes from '@styles/stylePropTypes'; import styles from '@styles/styles'; import themeColors from '@styles/themes/default'; import CONST from '@src/CONST'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; -import Text from './Text'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; +import Text from './Text'; const propTypes = { /** From 3dc351255b70f5cce05e4a44000e6c79dd9767bc Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 3 Nov 2023 13:04:03 +0100 Subject: [PATCH 19/31] docs --- src/components/DotIndicatorMessage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 6610db1b4a61..3297f70fafc6 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -45,6 +45,7 @@ const defaultProps = { * Check if the error includes a receipt. * * @param {String} message + * @returns {Boolean} */ const isReceiptError = (message) => { if (_.isString(message)) { From b1e1d13dbd826a5e336c7e24e431d893e86e7e49 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 9 Nov 2023 17:16:36 +0100 Subject: [PATCH 20/31] Correctly display message --- src/libs/actions/IOU.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a6ab4c717915..7af9ca90cb9b 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -337,7 +337,9 @@ function buildOnyxDataForMoneyRequest( ...(isNewChatReport ? { [chatCreatedAction.reportActionID]: { - errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: _.isEmpty(transaction.receipt) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), }, [reportPreviewAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError(null), @@ -346,7 +348,9 @@ function buildOnyxDataForMoneyRequest( : { [reportPreviewAction.reportActionID]: { created: reportPreviewAction.created, - errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), + errors: _.isEmpty(transaction.receipt) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), }, }), }, @@ -358,17 +362,17 @@ function buildOnyxDataForMoneyRequest( ...(isNewIOUReport ? { [iouCreatedAction.reportActionID]: { - errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), - }, - [iouAction.reportActionID]: { errors: _.isEmpty(transaction.receipt) - ? ErrorUtils.getMicroSecondOnyxError(null) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), }, + [iouAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError(null), + }, } : { [iouAction.reportActionID]: { - errors: !_.isEmpty(transaction.receipt) + errors: _.isEmpty(transaction.receipt) ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), }, From a87aac4cd8c2e814d88bf2038d03f66accc7bd98 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 14 Nov 2023 13:41:41 +0100 Subject: [PATCH 21/31] Avoid warnings --- src/components/DotIndicatorMessage.js | 3 ++- src/components/MessagesRow.js | 2 +- src/libs/ErrorUtils.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index 3297f70fafc6..b698d5251320 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -22,7 +22,7 @@ const propTypes = { * timestamp: 'message', * } */ - messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))])), + messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string, PropTypes.object]), PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))])), // The type of message, 'error' shows a red dot, 'success' shows a green dot type: PropTypes.oneOf(['error', 'success']).isRequired, @@ -88,6 +88,7 @@ function DotIndicatorMessage(props) { {_.map(sortedMessages, (message, i) => isReceiptError(message) ? ( { fileDownload(message.source, message.filename); diff --git a/src/components/MessagesRow.js b/src/components/MessagesRow.js index e49fca97cef7..f27329ac88ce 100644 --- a/src/components/MessagesRow.js +++ b/src/components/MessagesRow.js @@ -15,7 +15,7 @@ import Tooltip from './Tooltip'; const propTypes = { /** The messages to display */ - messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))])), + messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string, PropTypes.object]), PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))])), /** The type of message, 'error' shows a red dot, 'success' shows a green dot */ type: PropTypes.oneOf(['error', 'success']).isRequired, diff --git a/src/libs/ErrorUtils.ts b/src/libs/ErrorUtils.ts index 2112037b9450..46bdd510f5c4 100644 --- a/src/libs/ErrorUtils.ts +++ b/src/libs/ErrorUtils.ts @@ -43,7 +43,7 @@ function getMicroSecondOnyxError(error: string): Record { } /** - * Method used to get an error object with microsecond as the key and am object as the value. + * Method used to get an error object with microsecond as the key and an object as the value. * @param error - error key or message to be saved */ function getMicroSecondOnyxErrorObject(error: Record): Record> { From b3080678a8106142c4158efb626020eb6e0e1a14 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 14 Nov 2023 13:53:54 +0100 Subject: [PATCH 22/31] prettier --- src/components/DotIndicatorMessage.js | 4 +++- src/components/MessagesRow.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/DotIndicatorMessage.js b/src/components/DotIndicatorMessage.js index b698d5251320..4844a6af269c 100644 --- a/src/components/DotIndicatorMessage.js +++ b/src/components/DotIndicatorMessage.js @@ -22,7 +22,9 @@ const propTypes = { * timestamp: 'message', * } */ - messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string, PropTypes.object]), PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))])), + messages: PropTypes.objectOf( + PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string, PropTypes.object]), PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))]), + ), // The type of message, 'error' shows a red dot, 'success' shows a green dot type: PropTypes.oneOf(['error', 'success']).isRequired, diff --git a/src/components/MessagesRow.js b/src/components/MessagesRow.js index f27329ac88ce..ffd14db39dbf 100644 --- a/src/components/MessagesRow.js +++ b/src/components/MessagesRow.js @@ -15,7 +15,9 @@ import Tooltip from './Tooltip'; const propTypes = { /** The messages to display */ - messages: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string, PropTypes.object]), PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))])), + messages: PropTypes.objectOf( + PropTypes.oneOfType([PropTypes.oneOfType([PropTypes.string, PropTypes.object]), PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object]))]), + ), /** The type of message, 'error' shows a red dot, 'success' shows a green dot */ type: PropTypes.oneOf(['error', 'success']).isRequired, From 9bf109ccfb18de211c2423ab95442adaabc655bc Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 16 Nov 2023 14:10:57 +0100 Subject: [PATCH 23/31] Allow temporary files download in-tab --- src/libs/fileDownload/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/fileDownload/index.js b/src/libs/fileDownload/index.js index d1fa968b665f..81f7aa1df9b6 100644 --- a/src/libs/fileDownload/index.js +++ b/src/libs/fileDownload/index.js @@ -11,7 +11,7 @@ import * as FileUtils from './FileUtils'; */ export default function fileDownload(url, fileName) { const resolvedUrl = tryResolveUrlFromApiRoot(url); - if (!resolvedUrl.startsWith(ApiUtils.getApiRoot())) { + if (!resolvedUrl.startsWith(ApiUtils.getApiRoot()) && !resolvedUrl.startsWith('blob')) { // Different origin URLs might pose a CORS issue during direct downloads. // Opening in a new tab avoids this limitation, letting the browser handle the download. Link.openExternalLink(url); From 24a1a76102989711e5030dd78c672b346333f64e Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 16 Nov 2023 14:14:40 +0100 Subject: [PATCH 24/31] add const --- src/CONST.ts | 1 + src/libs/fileDownload/index.js | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index ee930a6c60b8..a7fbd4b9bbae 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -961,6 +961,7 @@ const CONST = { ATTACHMENT_SOURCE_ATTRIBUTE: 'data-expensify-source', ATTACHMENT_PREVIEW_ATTRIBUTE: 'src', ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE: 'data-name', + ATTACHMENT_TEMPORARY_URL_START: 'blob', ATTACHMENT_PICKER_TYPE: { FILE: 'file', diff --git a/src/libs/fileDownload/index.js b/src/libs/fileDownload/index.js index 81f7aa1df9b6..5aa04acddf38 100644 --- a/src/libs/fileDownload/index.js +++ b/src/libs/fileDownload/index.js @@ -1,5 +1,6 @@ import * as ApiUtils from '@libs/ApiUtils'; import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot'; +import CONST from '@src/CONST'; import * as Link from '@userActions/Link'; import * as FileUtils from './FileUtils'; @@ -11,7 +12,7 @@ import * as FileUtils from './FileUtils'; */ export default function fileDownload(url, fileName) { const resolvedUrl = tryResolveUrlFromApiRoot(url); - if (!resolvedUrl.startsWith(ApiUtils.getApiRoot()) && !resolvedUrl.startsWith('blob')) { + if (!resolvedUrl.startsWith(ApiUtils.getApiRoot()) && !resolvedUrl.startsWith(CONST.ATTACHMENT_TEMPORARY_URL_START)) { // Different origin URLs might pose a CORS issue during direct downloads. // Opening in a new tab avoids this limitation, letting the browser handle the download. Link.openExternalLink(url); From cc15c6d0210c53164569469336d6a64e34a504b6 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 16 Nov 2023 14:25:59 +0100 Subject: [PATCH 25/31] update const --- src/CONST.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index a7fbd4b9bbae..35cd75f0b288 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -961,7 +961,7 @@ const CONST = { ATTACHMENT_SOURCE_ATTRIBUTE: 'data-expensify-source', ATTACHMENT_PREVIEW_ATTRIBUTE: 'src', ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE: 'data-name', - ATTACHMENT_TEMPORARY_URL_START: 'blob', + ATTACHMENT_TEMPORARY_URL_START: 'blob:', ATTACHMENT_PICKER_TYPE: { FILE: 'file', From b3a6ca9b39796b8cbce953ab2faf2fcc7a86c48c Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 16 Nov 2023 14:35:34 +0100 Subject: [PATCH 26/31] prettier --- src/libs/fileDownload/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/fileDownload/index.js b/src/libs/fileDownload/index.js index 5aa04acddf38..70952df69a64 100644 --- a/src/libs/fileDownload/index.js +++ b/src/libs/fileDownload/index.js @@ -1,7 +1,7 @@ import * as ApiUtils from '@libs/ApiUtils'; import tryResolveUrlFromApiRoot from '@libs/tryResolveUrlFromApiRoot'; -import CONST from '@src/CONST'; import * as Link from '@userActions/Link'; +import CONST from '@src/CONST'; import * as FileUtils from './FileUtils'; /** From bb41f23def759cf6601c26d58ec36aa25d1edcbe Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 17 Nov 2023 11:51:57 +0100 Subject: [PATCH 27/31] delete ruby version change --- .ruby-version | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .ruby-version diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 818bd47abfc9..000000000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -3.0.6 From 57f1a8de007b90ac562a64430405d7f4d3fe6307 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 21 Nov 2023 16:34:42 +0100 Subject: [PATCH 28/31] add helper function --- src/libs/actions/IOU.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 31b75091d517..05a9660bd0a4 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -344,9 +344,7 @@ function buildOnyxDataForMoneyRequest( ...(isNewChatReport ? { [chatCreatedAction.reportActionID]: { - errors: _.isEmpty(transaction.receipt) - ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), + errors: getReceiptError(transaction), }, [reportPreviewAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError(null), @@ -355,9 +353,7 @@ function buildOnyxDataForMoneyRequest( : { [reportPreviewAction.reportActionID]: { created: reportPreviewAction.created, - errors: _.isEmpty(transaction.receipt) - ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), + errors: getReceiptError(transaction), }, }), }, @@ -369,9 +365,7 @@ function buildOnyxDataForMoneyRequest( ...(isNewIOUReport ? { [iouCreatedAction.reportActionID]: { - errors: _.isEmpty(transaction.receipt) - ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), + errors: getReceiptError(transaction), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError(null), @@ -379,9 +373,7 @@ function buildOnyxDataForMoneyRequest( } : { [iouAction.reportActionID]: { - errors: _.isEmpty(transaction.receipt) - ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}), + errors: getReceiptError(transaction), }, }), }, @@ -2985,6 +2977,18 @@ function getIOUReportID(iou, route) { return lodashGet(route, 'params.reportID') || lodashGet(iou, 'participants.0.reportID', ''); } +/** + * Helper function to get the receipt error for money requests, or the generic error if there's no receipt + * + * @param {Object} transaction + * @returns {Object} + */ +function getReceiptError(transaction) { + return _.isEmpty(transaction.receipt) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}); +} + export { createDistanceRequest, deleteMoneyRequest, From 4366cd88d131fc2157fdd5df0ca4fbcef41590a1 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 21 Nov 2023 17:08:28 +0100 Subject: [PATCH 29/31] move function --- src/libs/actions/IOU.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 05a9660bd0a4..e4c41e10c03f 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -141,6 +141,18 @@ function resetMoneyRequestInfo(id = '') { }); } +/** + * Helper function to get the receipt error for money requests, or the generic error if there's no receipt + * + * @param {Object} transaction + * @returns {Object} + */ +function getReceiptError(transaction) { + return _.isEmpty(transaction.receipt) + ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}); +} + function buildOnyxDataForMoneyRequest( chatReport, iouReport, @@ -2977,18 +2989,6 @@ function getIOUReportID(iou, route) { return lodashGet(route, 'params.reportID') || lodashGet(iou, 'participants.0.reportID', ''); } -/** - * Helper function to get the receipt error for money requests, or the generic error if there's no receipt - * - * @param {Object} transaction - * @returns {Object} - */ -function getReceiptError(transaction) { - return _.isEmpty(transaction.receipt) - ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}); -} - export { createDistanceRequest, deleteMoneyRequest, From 7021a01b0126dbfce71684c098222696cfc714a7 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 21 Nov 2023 17:20:08 +0100 Subject: [PATCH 30/31] use for everything --- src/libs/actions/IOU.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index e4c41e10c03f..2166e914b27a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -144,13 +144,13 @@ function resetMoneyRequestInfo(id = '') { /** * Helper function to get the receipt error for money requests, or the generic error if there's no receipt * - * @param {Object} transaction + * @param {Object} receipt * @returns {Object} */ -function getReceiptError(transaction) { - return _.isEmpty(transaction.receipt) +function getReceiptError(receipt) { + return _.isEmpty(receipt) ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: transaction.receipt.source, filename: transaction.filename}); + : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: receipt.source, filename: receipt.filename}); } function buildOnyxDataForMoneyRequest( @@ -356,7 +356,7 @@ function buildOnyxDataForMoneyRequest( ...(isNewChatReport ? { [chatCreatedAction.reportActionID]: { - errors: getReceiptError(transaction), + errors: getReceiptError(transaction.receipt), }, [reportPreviewAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError(null), @@ -365,7 +365,7 @@ function buildOnyxDataForMoneyRequest( : { [reportPreviewAction.reportActionID]: { created: reportPreviewAction.created, - errors: getReceiptError(transaction), + errors: getReceiptError(transaction.receipt), }, }), }, @@ -377,7 +377,7 @@ function buildOnyxDataForMoneyRequest( ...(isNewIOUReport ? { [iouCreatedAction.reportActionID]: { - errors: getReceiptError(transaction), + errors: getReceiptError(transaction.receipt), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError(null), @@ -385,7 +385,7 @@ function buildOnyxDataForMoneyRequest( } : { [iouAction.reportActionID]: { - errors: getReceiptError(transaction), + errors: getReceiptError(transaction.receipt), }, }), }, @@ -1445,9 +1445,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${splitChatReport.reportID}`, value: { [splitIOUReportAction.reportActionID]: { - errors: _.isEmpty(receipt) - ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), + errors: getReceiptError(receipt), }, }, }); @@ -1470,9 +1468,7 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co errors: ErrorUtils.getMicroSecondOnyxError('report.genericCreateReportFailureMessage'), }, [splitIOUReportAction.reportActionID]: { - errors: _.isEmpty(receipt) - ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage') - : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source, filename}), + errors: getReceiptError(receipt), }, }, }, From d52631c4ae00f9203cd2fb3b6c859c10d312ac88 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 22 Nov 2023 12:11:38 +0100 Subject: [PATCH 31/31] update message --- src/languages/en.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index b0011cdba9d4..76e503fcb2ae 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -592,7 +592,7 @@ export default { other: 'Unexpected error, please try again later', genericCreateFailureMessage: 'Unexpected error requesting money, please try again later', receiptFailureMessage: "The receipt didn't upload. ", - saveFileMessage: 'Save the file ', + saveFileMessage: 'Download the file ', loseFileMessage: 'or dismiss this error and lose it', genericDeleteFailureMessage: 'Unexpected error deleting the money request, please try again later', genericEditFailureMessage: 'Unexpected error editing the money request, please try again later',