diff --git a/src/components/WalletStatementModal/index.js b/src/components/WalletStatementModal/index.js index 31783da04e89..655ef2421e29 100644 --- a/src/components/WalletStatementModal/index.js +++ b/src/components/WalletStatementModal/index.js @@ -2,12 +2,15 @@ import React from 'react'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; import {View} from 'react-native'; +import _ from 'underscore'; import compose from '../../libs/compose'; import withLocalize from '../withLocalize'; import ONYXKEYS from '../../ONYXKEYS'; import {walletStatementPropTypes, walletStatementDefaultProps} from './WalletStatementModalPropTypes'; import styles from '../../styles/styles'; import FullScreenLoadingIndicator from '../FullscreenLoadingIndicator'; +import ROUTES from '../../ROUTES'; +import Navigation from '../../libs/Navigation/Navigation'; class WalletStatementModal extends React.Component { constructor(props) { @@ -18,6 +21,22 @@ class WalletStatementModal extends React.Component { }; } + /** + * Handles in-app navigation for iframe links + * + * @param {MessageEvent} e + */ + navigate(e) { + if (!e.data || e.data.type !== 'STATEMENT_NAVIGATE' || !e.data.url) { + return; + } + const iouRoutes = [ROUTES.IOU_REQUEST, ROUTES.IOU_SEND, ROUTES.IOU_BILL]; + const navigateToIOURoute = _.find(iouRoutes, iouRoute => e.data.url.includes(iouRoute)); + if (navigateToIOURoute) { + Navigation.navigate(navigateToIOURoute); + } + } + render() { const authToken = lodashGet(this.props, 'session.authToken', null); return ( @@ -33,7 +52,13 @@ class WalletStatementModal extends React.Component { width="100%" seamless="seamless" frameBorder="0" - onLoad={() => this.setState({isLoading: false})} + onLoad={() => { + this.setState({isLoading: false}); + + // We listen to a message sent from the iframe to the parent component when a link is clicked. + // This lets us handle navigation in the app, outside of the iframe. + window.onmessage = e => this.navigate(e); + }} /> diff --git a/src/components/WalletStatementModal/index.native.js b/src/components/WalletStatementModal/index.native.js index 42784e4b2671..01feae5fa021 100644 --- a/src/components/WalletStatementModal/index.native.js +++ b/src/components/WalletStatementModal/index.native.js @@ -2,29 +2,60 @@ import React from 'react'; import {WebView} from 'react-native-webview'; import lodashGet from 'lodash/get'; import {withOnyx} from 'react-native-onyx'; +import _ from 'underscore'; import withLocalize from '../withLocalize'; import ONYXKEYS from '../../ONYXKEYS'; import compose from '../../libs/compose'; import {walletStatementPropTypes, walletStatementDefaultProps} from './WalletStatementModalPropTypes'; import FullScreenLoadingIndicator from '../FullscreenLoadingIndicator'; +import Navigation from '../../libs/Navigation/Navigation'; +import ROUTES from '../../ROUTES'; -const WalletStatementModal = (props) => { - const authToken = lodashGet(props, 'session.authToken', null); - return ( - } - /> - ); -}; +class WalletStatementModal extends React.Component { + constructor(props) { + super(props); + + this.authToken = lodashGet(props, 'session.authToken', null); + this.navigate = this.navigate.bind(this); + } + + /** + * Handles in-app navigation for webview links + * + * @param {Object} params + * @param {String} params.url + */ + navigate({url}) { + if (!this.webview || !url) { + return; + } + const iouRoutes = [ROUTES.IOU_REQUEST, ROUTES.IOU_SEND, ROUTES.IOU_BILL]; + const navigateToIOURoute = _.find(iouRoutes, iouRoute => url.includes(iouRoute)); + if (navigateToIOURoute) { + this.webview.stopLoading(); + Navigation.navigate(navigateToIOURoute); + } + } + + render() { + return ( + this.webview = node} + originWhitelist={['https://*']} + source={{ + uri: this.props.statementPageURL, + headers: { + Cookie: `authToken=${this.authToken}`, + }, + }} + incognito // 'incognito' prop required for Android, issue here https://github.com/react-native-webview/react-native-webview/issues/1352 + startInLoadingState + renderLoading={() => } + onNavigationStateChange={this.navigate} + /> + ); + } +} WalletStatementModal.propTypes = walletStatementPropTypes; WalletStatementModal.defaultProps = walletStatementDefaultProps;