From d741cff0ab353a0ab5ab12266ed0327936489a65 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 25 Jun 2021 16:13:07 -0600 Subject: [PATCH 1/2] add asyncOpenURL wrapper --- src/libs/actions/IOU.js | 14 +++++++------ src/libs/asyncOpenURL/index.desktop.js | 10 +++++++++ src/libs/asyncOpenURL/index.native.js | 10 +++++++++ src/libs/asyncOpenURL/index.website.js | 29 ++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/libs/asyncOpenURL/index.desktop.js create mode 100644 src/libs/asyncOpenURL/index.native.js create mode 100644 src/libs/asyncOpenURL/index.website.js diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 3422e54e76dd..56147e51de72 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1,5 +1,4 @@ import Onyx from 'react-native-onyx'; -import {Linking} from 'react-native'; import _ from 'underscore'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; @@ -7,6 +6,7 @@ import ROUTES from '../../ROUTES'; import * as API from '../API'; import {getSimplifiedIOUReport, fetchChatReportsByIDs, fetchIOUReportByIDAndUpdateChatReport} from './Report'; import Navigation from '../Navigation/Navigation'; +import asyncOpenURL from '../asyncOpenURL'; /** * @param {Object[]} requestParams @@ -196,7 +196,8 @@ function payIOUReport({ const payIOUPromise = paymentMethodType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY ? API.PayWithWallet({reportID}) : API.PayIOU({reportID, paymentMethodType}); - payIOUPromise + + asyncOpenURL(payIOUPromise .then((response) => { if (response.jsonCode !== 200) { throw new Error(response.message); @@ -213,16 +214,17 @@ function payIOUReport({ // Once we have successfully paid the IOU we will transfer the user to their platform of choice if they have // selected something other than a manual settlement or Expensify Wallet e.g. Venmo or PayPal.me if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.PAYPAL_ME) { - Linking.openURL(buildPayPalPaymentUrl(amount, submitterPayPalMeAddress, currency)); - } else if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.VENMO) { - Linking.openURL(buildVenmoPaymentURL(amount, submitterPhoneNumber)); + return buildPayPalPaymentUrl(amount, submitterPayPalMeAddress, currency); + } + if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.VENMO) { + return buildVenmoPaymentURL(amount, submitterPhoneNumber); } }) .catch((error) => { console.error(`Error Paying iouReport: ${error}`); Onyx.merge(ONYXKEYS.IOU, {error: true}); }) - .finally(() => Onyx.merge(ONYXKEYS.IOU, {loading: false})); + .finally(() => Onyx.merge(ONYXKEYS.IOU, {loading: false}))); } export { diff --git a/src/libs/asyncOpenURL/index.desktop.js b/src/libs/asyncOpenURL/index.desktop.js new file mode 100644 index 000000000000..a3a04ac76edd --- /dev/null +++ b/src/libs/asyncOpenURL/index.desktop.js @@ -0,0 +1,10 @@ +import {Linking} from 'react-native'; + +export default function asyncOpenURL(promise) { + promise.then((url) => { + if (!url) { + return; + } + Linking.openURL(url); + }); +} diff --git a/src/libs/asyncOpenURL/index.native.js b/src/libs/asyncOpenURL/index.native.js new file mode 100644 index 000000000000..a3a04ac76edd --- /dev/null +++ b/src/libs/asyncOpenURL/index.native.js @@ -0,0 +1,10 @@ +import {Linking} from 'react-native'; + +export default function asyncOpenURL(promise) { + promise.then((url) => { + if (!url) { + return; + } + Linking.openURL(url); + }); +} diff --git a/src/libs/asyncOpenURL/index.website.js b/src/libs/asyncOpenURL/index.website.js new file mode 100644 index 000000000000..43a4407876d8 --- /dev/null +++ b/src/libs/asyncOpenURL/index.website.js @@ -0,0 +1,29 @@ +import {Linking} from 'react-native'; + +/** + * Prevents Safari from blocking pop-up window when opened within async call. + * + * @param {Promise} promise + */ +export default function asyncOpenURL(promise) { + const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); + + if (!isSafari) { + promise.then((url) => { + if (!url) { + return; + } + Linking.openURL(url); + }); + } else { + const windowRef = window.open(); + promise + .then((url) => { + if (!url) { + return windowRef.close(); + } + windowRef.location = url; + }) + .catch(() => windowRef.close()); + } +} From 2b004194004006e6073b918283b4c51d9e12f397 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 28 Jun 2021 11:42:24 -0600 Subject: [PATCH 2/2] remove platform files and update input argument --- src/libs/actions/IOU.js | 22 ++++++++++++---------- src/libs/asyncOpenURL/index.desktop.js | 10 ---------- src/libs/asyncOpenURL/index.js | 11 +++++++++++ src/libs/asyncOpenURL/index.native.js | 10 ---------- src/libs/asyncOpenURL/index.website.js | 17 ++++++++--------- 5 files changed, 31 insertions(+), 39 deletions(-) delete mode 100644 src/libs/asyncOpenURL/index.desktop.js create mode 100644 src/libs/asyncOpenURL/index.js delete mode 100644 src/libs/asyncOpenURL/index.native.js diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 56147e51de72..9056210024bc 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -197,6 +197,16 @@ function payIOUReport({ ? API.PayWithWallet({reportID}) : API.PayIOU({reportID, paymentMethodType}); + // Build the url for the user's platform of choice if they have + // selected something other than a manual settlement or Expensify Wallet e.g. Venmo or PayPal.me + let url; + if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.PAYPAL_ME) { + url = buildPayPalPaymentUrl(amount, submitterPayPalMeAddress, currency); + } + if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.VENMO) { + url = buildVenmoPaymentURL(amount, submitterPhoneNumber); + } + asyncOpenURL(payIOUPromise .then((response) => { if (response.jsonCode !== 200) { @@ -210,21 +220,13 @@ function payIOUReport({ // iouReport being fetched here must be open, because only an open iouReoport can be paid. // Therefore, we should also sync the chatReport after fetching the iouReport. fetchIOUReportByIDAndUpdateChatReport(reportID, chatReportID); - - // Once we have successfully paid the IOU we will transfer the user to their platform of choice if they have - // selected something other than a manual settlement or Expensify Wallet e.g. Venmo or PayPal.me - if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.PAYPAL_ME) { - return buildPayPalPaymentUrl(amount, submitterPayPalMeAddress, currency); - } - if (paymentMethodType === CONST.IOU.PAYMENT_TYPE.VENMO) { - return buildVenmoPaymentURL(amount, submitterPhoneNumber); - } }) .catch((error) => { console.error(`Error Paying iouReport: ${error}`); Onyx.merge(ONYXKEYS.IOU, {error: true}); }) - .finally(() => Onyx.merge(ONYXKEYS.IOU, {loading: false}))); + .finally(() => Onyx.merge(ONYXKEYS.IOU, {loading: false})), + url); } export { diff --git a/src/libs/asyncOpenURL/index.desktop.js b/src/libs/asyncOpenURL/index.desktop.js deleted file mode 100644 index a3a04ac76edd..000000000000 --- a/src/libs/asyncOpenURL/index.desktop.js +++ /dev/null @@ -1,10 +0,0 @@ -import {Linking} from 'react-native'; - -export default function asyncOpenURL(promise) { - promise.then((url) => { - if (!url) { - return; - } - Linking.openURL(url); - }); -} diff --git a/src/libs/asyncOpenURL/index.js b/src/libs/asyncOpenURL/index.js new file mode 100644 index 000000000000..192a9c3cba07 --- /dev/null +++ b/src/libs/asyncOpenURL/index.js @@ -0,0 +1,11 @@ +import {Linking} from 'react-native'; + +export default function asyncOpenURL(promise, url) { + if (!url) { + return; + } + + promise.then(() => { + Linking.openURL(url); + }); +} diff --git a/src/libs/asyncOpenURL/index.native.js b/src/libs/asyncOpenURL/index.native.js deleted file mode 100644 index a3a04ac76edd..000000000000 --- a/src/libs/asyncOpenURL/index.native.js +++ /dev/null @@ -1,10 +0,0 @@ -import {Linking} from 'react-native'; - -export default function asyncOpenURL(promise) { - promise.then((url) => { - if (!url) { - return; - } - Linking.openURL(url); - }); -} diff --git a/src/libs/asyncOpenURL/index.website.js b/src/libs/asyncOpenURL/index.website.js index 43a4407876d8..2ea074c8c5a2 100644 --- a/src/libs/asyncOpenURL/index.website.js +++ b/src/libs/asyncOpenURL/index.website.js @@ -4,24 +4,23 @@ import {Linking} from 'react-native'; * Prevents Safari from blocking pop-up window when opened within async call. * * @param {Promise} promise + * @param {string} url */ -export default function asyncOpenURL(promise) { +export default function asyncOpenURL(promise, url) { + if (!url) { + return; + } + const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); if (!isSafari) { - promise.then((url) => { - if (!url) { - return; - } + promise.then(() => { Linking.openURL(url); }); } else { const windowRef = window.open(); promise - .then((url) => { - if (!url) { - return windowRef.close(); - } + .then(() => { windowRef.location = url; }) .catch(() => windowRef.close());