diff --git a/src/CONST.js b/src/CONST.js index 0ecb1aedf48a..4ffeaba8f616 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -305,6 +305,7 @@ const CONST = { COLD: 'cold', REPORT_ACTION_ITEM_LAYOUT_DEBOUNCE_TIME: 1500, TOOLTIP_SENSE: 1000, + SPINNER_TIMEOUT: 15 * 1000, }, PRIORITY_MODE: { GSD: 'gsd', diff --git a/src/components/FullscreenLoadingIndicator.js b/src/components/FullscreenLoadingIndicator.js index 41a2ef2f8436..4bf55d7a3921 100644 --- a/src/components/FullscreenLoadingIndicator.js +++ b/src/components/FullscreenLoadingIndicator.js @@ -5,38 +5,68 @@ import {ActivityIndicator, StyleSheet, View} from 'react-native'; import styles from '../styles/styles'; import themeColors from '../styles/themes/default'; import stylePropTypes from '../styles/stylePropTypes'; +import Log from '../libs/Log'; +import CONST from '../CONST'; const propTypes = { - /** Controls whether the loader is mounted and displayed */ - visible: PropTypes.bool, + /** + * Context info printed in timing log. + * Providing this prop would capture logs for mounting/unmounting and staying visible for too long + */ + logDetail: PropTypes.shape({ + /** Name is used to distinct the loader in captured logs. */ + name: PropTypes.string.isRequired, + }), /** Additional style props */ style: stylePropTypes, }; const defaultProps = { - visible: true, style: [], + logDetail: null, }; -/** - * Loading indication component intended to cover the whole page, while the page prepares for initial render - * - * @param {Object} props - * @returns {JSX.Element} - */ -const FullScreenLoadingIndicator = (props) => { - if (!props.visible) { - return null; +class FullScreenLoadingIndicator extends React.Component { + componentDidMount() { + if (!this.props.logDetail) { + return; + } + + if (!this.props.logDetail.name) { + throw new Error('A name should be set to distinct logged messages. Please check the `logDetails` prop.'); + } + + Log.info('[LoadingIndicator] Became visible', false, this.props.logDetail); + + this.timeoutID = setTimeout( + () => Log.alert( + `${CONST.ERROR.ENSURE_BUGBOT} [LoadingIndicator] Visible after timeout`, + {timeout: CONST.TIMING.SPINNER_TIMEOUT, ...this.props.logDetail}, + false, + ), + CONST.TIMING.SPINNER_TIMEOUT, + ); } - const additionalStyles = _.isArray(props.style) ? props.style : [props.style]; - return ( - - - - ); -}; + componentWillUnmount() { + if (!this.timeoutID) { + return; + } + + clearTimeout(this.timeoutID); + Log.info('[LoadingIndicator] Disappeared', false, this.props.logDetail); + } + + render() { + const additionalStyles = _.isArray(this.props.style) ? this.props.style : [this.props.style]; + return ( + + + + ); + } +} FullScreenLoadingIndicator.propTypes = propTypes; FullScreenLoadingIndicator.defaultProps = defaultProps; diff --git a/src/components/WalletStatementModal/index.js b/src/components/WalletStatementModal/index.js index 655ef2421e29..60d57fc5c14b 100644 --- a/src/components/WalletStatementModal/index.js +++ b/src/components/WalletStatementModal/index.js @@ -41,9 +41,7 @@ class WalletStatementModal extends React.Component { const authToken = lodashGet(this.props, 'session.authToken', null); return ( <> - + {this.state.isLoading && }