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 && }