diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj index de0bf9bf28ff..8f47635f6751 100644 --- a/ios/NewExpensify.xcodeproj/project.pbxproj +++ b/ios/NewExpensify.xcodeproj/project.pbxproj @@ -531,11 +531,11 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion", "${PODS_XCFRAMEWORKS_BUILD_DIR}/Onfido/Onfido.framework/Onfido", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/Plaid/LinkKit.framework/LinkKit", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/LinkKit/LinkKit.framework/LinkKit", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( @@ -707,11 +707,11 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-NewExpensify/Pods-NewExpensify-frameworks.sh", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/double-conversion/double-conversion.framework/double-conversion", "${PODS_XCFRAMEWORKS_BUILD_DIR}/Onfido/Onfido.framework/Onfido", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/Plaid/LinkKit.framework/LinkKit", - "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/LinkKit/LinkKit.framework/LinkKit", + "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes/hermes.framework/hermes", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( diff --git a/ios/Podfile b/ios/Podfile index 6ddfb790f587..db2612713022 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -17,7 +17,6 @@ target 'NewExpensify' do :hermes_enabled => true ) - pod 'react-native-webview', :path => '../node_modules/react-native-webview' target 'NewExpensifyTests' do inherit! :complete diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 5fab81d28dc2..ef9a14d20a47 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -878,7 +878,7 @@ SPEC CHECKSUMS: Airship: 29d674abeac754f783fc46c7d383d6f046687341 boost: a7c83b31436843459a1961bfd74b96033dc77234 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 + DoubleConversion: cf9b38bf0b2d048436d9a82ad2abe1404f11e7de FBLazyVector: e5569e42a1c79ca00521846c223173a57aca1fe1 FBReactNativeSpec: fe08c1cd7e2e205718d77ad14b34957cce949b58 Firebase: 54cdc8bc9c9b3de54f43dab86e62f5a76b47034f @@ -900,7 +900,7 @@ SPEC CHECKSUMS: Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541 FlipperKit: d8d346844eca5d9120c17d441a2f38596e8ed2b9 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 - glog: 5337263514dd6f09803962437687240c5dc39aa4 + glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62 GoogleAppMeasurement: 6b6a08fd9c71f4dbc89e0e812acca81d797aa342 GoogleDataTransport: 629c20a4d363167143f30ea78320d5a7eb8bd940 GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1 @@ -977,6 +977,6 @@ SPEC CHECKSUMS: Yoga: e7dc4e71caba6472ff48ad7d234389b91dadc280 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 1199d07d3ccd1ea23300ad9e27bc9287716223bf +PODFILE CHECKSUM: 431123d7514c52fa4516724b89c20d02c87ad8c8 COCOAPODS: 1.10.1 diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index e701f99ab6a1..62fd83231d33 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -130,6 +130,9 @@ export default { // The user's credit cards CARD_LIST: 'cardList', + // Stores information about the user's saved statements + WALLET_STATEMENT: 'walletStatement', + // Stores information about the active reimbursement account being set up REIMBURSEMENT_ACCOUNT: 'reimbursementAccount', diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 657558bf6dfb..50c66c684551 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -15,12 +15,10 @@ import NetworkConnection from '../NetworkConnection'; import redirectToSignIn from './SignInRedirect'; import NameValuePair from './NameValuePair'; import Growl from '../Growl'; -import CONFIG from '../../CONFIG'; import * as Localize from '../Localize'; import * as CloseAccountActions from './CloseAccount'; import * as Link from './Link'; import getSkinToneEmojiFromIndex from '../../components/EmojiPicker/getSkinToneEmojiFromIndex'; -import fileDownload from '../fileDownload'; let sessionAuthToken = ''; let sessionEmail = ''; @@ -402,20 +400,21 @@ function joinScreenShare(accessToken, roomName) { /** * Downloads the statement PDF for the provided period * @param {String} period YYYYMM format + * @returns {Promise} */ -function downloadStatementPDF(period) { - API.GetStatementPDF({period}) +function generateStatementPDF(period) { + Onyx.merge(ONYXKEYS.WALLET_STATEMENT, {isGenerating: true}); + return API.GetStatementPDF({period}) .then((response) => { - if (response.jsonCode === 200 && response.filename) { - const downloadFileName = `Expensify_Statement_${response.period}.pdf`; - const pdfURL = `${CONFIG.EXPENSIFY.EXPENSIFY_URL}secure?secureType=pdfreport&filename=${response.filename}&downloadName=${downloadFileName}`; - - fileDownload(pdfURL, downloadFileName); - } else { - Growl.show(Localize.translateLocal('common.genericErrorMessage'), CONST.GROWL.ERROR, 3000); + if (response.jsonCode !== 200 || !response.filename) { + Log.info('[User] Failed to generate statement PDF', false, {response}); + return; } - }) - .catch(() => Growl.show(Localize.translateLocal('common.genericErrorMessage'), CONST.GROWL.ERROR, 3000)); + + Onyx.merge(ONYXKEYS.WALLET_STATEMENT, {[period]: response.filename}); + }).finally(() => { + Onyx.merge(ONYXKEYS.WALLET_STATEMENT, {isGenerating: false}); + }); } export { @@ -437,5 +436,5 @@ export { setFrequentlyUsedEmojis, joinScreenShare, clearScreenShareRequest, - downloadStatementPDF, + generateStatementPDF, }; diff --git a/src/pages/wallet/WalletStatementPage.js b/src/pages/wallet/WalletStatementPage.js index 544de898d428..d1056ec5c21a 100644 --- a/src/pages/wallet/WalletStatementPage.js +++ b/src/pages/wallet/WalletStatementPage.js @@ -13,6 +13,10 @@ import compose from '../../libs/compose'; import CONFIG from '../../CONFIG'; import WalletStatementModal from '../../components/WalletStatementModal'; import * as User from '../../libs/actions/User'; +import fileDownload from '../../libs/fileDownload'; +import Growl from '../../libs/Growl'; +import CONST from '../../CONST'; +import makeCancellablePromise from '../../libs/MakeCancellablePromise'; const propTypes = { /** The route object passed to this page from the navigator */ @@ -26,33 +30,96 @@ const propTypes = { }).isRequired, }).isRequired, + walletStatement: PropTypes.shape({ + /** Whether the PDF file available for download or not */ + isGenerating: PropTypes.bool, + }), + ...withLocalizePropTypes, }; -const WalletStatementPage = (props) => { - moment.locale(lodashGet(props, 'preferredLocale', 'en')); - const yearMonth = lodashGet(props.route.params, 'yearMonth', null); - const year = yearMonth.substring(0, 4) || moment().year(); - const month = yearMonth.substring(4) || moment().month(); - const monthName = moment(month, 'M').format('MMMM'); - const title = `${monthName} ${year} statement`; - const url = `${CONFIG.EXPENSIFY.EXPENSIFY_URL}statement.php?period=${yearMonth}`; - return ( - - Navigation.dismissModal(true)} - onDownloadButtonPress={() => User.downloadStatementPDF(yearMonth)} - /> - - - ); +const defaultProps = { + walletStatement: { + isGenerating: false, + }, }; +class WalletStatementPage extends React.Component { + constructor(props) { + super(props); + + this.state = { + isDownloading: false, + }; + this.processDownload = this.processDownload.bind(this); + this.yearMonth = lodashGet(this.props.route.params, 'yearMonth', null); + this.generatePDFPromise = null; + } + + componentDidMount() { + this.generatePDFPromise = makeCancellablePromise(User.generateStatementPDF(this.yearMonth)); + } + + componentWillUnmount() { + if (!this.generatePDFPromise) { + return; + } + + this.generatePDFPromise.cancel(); + this.generatePDFPromise = null; + } + + processDownload(yearMonth) { + if (this.state.isDownloading) { + return; + } + + this.setState({ + isDownloading: true, + }); + + if (!this.props.walletStatement[yearMonth] || this.props.walletStatement.isGenerating) { + Growl.show(this.props.translate('common.genericErrorMessage'), CONST.GROWL.ERROR, 5000); + this.setState({ + isDownloading: false, + }); + } else { + const fileName = `Expensify_Statement_${yearMonth}.pdf`; + const pdfURL = `${CONFIG.EXPENSIFY.EXPENSIFY_URL}secure?secureType=pdfreport&filename=${this.props.walletStatement[yearMonth]}&downloadName=${fileName}`; + fileDownload(pdfURL, fileName).then(() => { + this.setState({ + isDownloading: false, + }); + }); + } + } + + render() { + moment.locale(lodashGet(this.props, 'preferredLocale', 'en')); + const year = this.yearMonth.substring(0, 4) || moment().year(); + const month = this.yearMonth.substring(4) || moment().month(); + const monthName = moment(month, 'M').format('MMMM'); + const title = `${monthName} ${year} statement`; + const url = `${CONFIG.EXPENSIFY.EXPENSIFY_URL}statement.php?period=${this.yearMonth}`; + + return ( + + Navigation.dismissModal(true)} + onDownloadButtonPress={() => this.processDownload(this.yearMonth)} + /> + + + ); + } +} + WalletStatementPage.propTypes = propTypes; +WalletStatementPage.defaultProps = defaultProps; WalletStatementPage.displayName = 'WalletStatementPage'; export default compose( withLocalize, @@ -60,5 +127,8 @@ export default compose( preferredLocale: { key: ONYXKEYS.NVP_PREFERRED_LOCALE, }, + walletStatement: { + key: ONYXKEYS.WALLET_STATEMENT, + }, }), )(WalletStatementPage);