diff --git a/src/components/Avatar.js b/src/components/Avatar.js index 7aebb1d8fe68..81f35737ab6b 100644 --- a/src/components/Avatar.js +++ b/src/components/Avatar.js @@ -1,4 +1,4 @@ -import React, {useEffect, useRef, useState} from 'react'; +import React, {useState} from 'react'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import _ from 'underscore'; @@ -9,10 +9,9 @@ import CONST from '../CONST'; import * as StyleUtils from '../styles/StyleUtils'; import * as Expensicons from './Icon/Expensicons'; import Image from './Image'; -import {withNetwork} from './OnyxProvider'; -import networkPropTypes from './networkPropTypes'; import styles from '../styles/styles'; import * as ReportUtils from '../libs/ReportUtils'; +import useOnNetworkReconnect from './hooks/useOnNetworkReconnect'; const propTypes = { /** Source for the avatar. Can be a URL or an icon. */ @@ -44,9 +43,6 @@ const propTypes = { /** Owner of the avatar, typically a login email or workspace name */ name: PropTypes.string, - - /** Props to detect online status */ - network: networkPropTypes.isRequired, }; const defaultProps = { @@ -62,23 +58,8 @@ const defaultProps = { function Avatar(props) { const [imageError, setImageError] = useState(false); - const prevNetworkStatusRef = useRef(props.network.isOffline); - - useEffect(() => { - const isReconnecting = prevNetworkStatusRef.current && !props.network.isOffline; - if (!imageError || !isReconnecting) { - return; - } - setImageError(false); - - // We have not added the imageError as the dependency because effect is concerned with `imageError` only when the network state changes from offline -> online - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [props.network.isOffline]); - useEffect(() => { - // Used to store previous network state to compare on next render - prevNetworkStatusRef.current = props.network.isOffline; - }); + useOnNetworkReconnect(() => setImageError(false)); if (!props.source) { return null; @@ -128,4 +109,4 @@ function Avatar(props) { } Avatar.defaultProps = defaultProps; Avatar.propTypes = propTypes; -export default withNetwork()(Avatar); +export default Avatar; diff --git a/src/components/OnyxProvider.js b/src/components/OnyxProvider.js index 9ddea6ad0738..4bb2f69941e1 100644 --- a/src/components/OnyxProvider.js +++ b/src/components/OnyxProvider.js @@ -6,7 +6,7 @@ import ComposeProviders from './ComposeProviders'; // Set up any providers for individual keys. This should only be used in cases where many components will subscribe to // the same key (e.g. FlatList renderItem components) -const [withNetwork, NetworkProvider] = createOnyxContext(ONYXKEYS.NETWORK, {}); +const [withNetwork, NetworkProvider, NetworkContext] = createOnyxContext(ONYXKEYS.NETWORK, {}); const [withPersonalDetails, PersonalDetailsProvider] = createOnyxContext(ONYXKEYS.PERSONAL_DETAILS); const [withCurrentDate, CurrentDateProvider] = createOnyxContext(ONYXKEYS.CURRENT_DATE); const [withReportActionsDrafts, ReportActionsDraftsProvider] = createOnyxContext(ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS); @@ -45,4 +45,5 @@ export { withCurrentDate, withBlockedFromConcierge, withBetas, + NetworkContext, }; diff --git a/src/components/createOnyxContext.js b/src/components/createOnyxContext.js index c8452eb9ee83..7c3fcbd7f709 100644 --- a/src/components/createOnyxContext.js +++ b/src/components/createOnyxContext.js @@ -51,5 +51,5 @@ export default (onyxKeyName, defaultValue) => { return Consumer; }; - return [withOnyxKey, ProviderWithOnyx]; + return [withOnyxKey, ProviderWithOnyx, Context]; }; diff --git a/src/components/hooks/useOnNetworkReconnect.js b/src/components/hooks/useOnNetworkReconnect.js new file mode 100644 index 000000000000..c186789c0727 --- /dev/null +++ b/src/components/hooks/useOnNetworkReconnect.js @@ -0,0 +1,27 @@ +import {useRef, useContext, useEffect} from 'react'; +import {NetworkContext} from '../OnyxProvider'; + +/** + * @param {Function} onNetworkReconnect + */ +export default function useOnNetworkReconnect(onNetworkReconnect) { + const callback = useRef(onNetworkReconnect); + callback.current = onNetworkReconnect; + + const {isOffline} = useContext(NetworkContext); + const prevOfflineStatusRef = useRef(isOffline); + useEffect(() => { + // If we were offline before and now we are not offline then we just reconnected + const didReconnect = prevOfflineStatusRef.current && !isOffline; + if (!didReconnect) { + return; + } + + callback.current(); + }, [isOffline]); + + useEffect(() => { + // Used to store previous prop values to compare on next render + prevOfflineStatusRef.current = isOffline; + }, [isOffline]); +} diff --git a/src/pages/iou/MoneyRequestModal.js b/src/pages/iou/MoneyRequestModal.js index fb727646a61b..479e93fa9e09 100644 --- a/src/pages/iou/MoneyRequestModal.js +++ b/src/pages/iou/MoneyRequestModal.js @@ -23,11 +23,10 @@ import ScreenWrapper from '../../components/ScreenWrapper'; import CONST from '../../CONST'; import * as PersonalDetails from '../../libs/actions/PersonalDetails'; import withCurrentUserPersonalDetails from '../../components/withCurrentUserPersonalDetails'; -import networkPropTypes from '../../components/networkPropTypes'; -import {withNetwork} from '../../components/OnyxProvider'; import reportPropTypes from '../reportPropTypes'; import * as ReportUtils from '../../libs/ReportUtils'; import * as ReportScrollManager from '../../libs/ReportScrollManager'; +import useOnNetworkReconnect from '../../components/hooks/useOnNetworkReconnect'; import * as DeviceCapabilities from '../../libs/DeviceCapabilities'; /** @@ -44,9 +43,6 @@ const propTypes = { // eslint-disable-next-line react/no-unused-prop-types report: reportPropTypes, - /** Information about the network */ - network: networkPropTypes.isRequired, - // Holds data related to request view state, rather than the underlying request data. iou: PropTypes.shape({ /** Whether or not transaction creation has started */ @@ -112,7 +108,6 @@ const MoneyRequestModal = (props) => { : [Steps.MoneyRequestAmount, Steps.MoneyRequestParticipants, Steps.MoneyRequestConfirm]), [reportParticipants.length]); const prevCreatingIOUTransactionStatusRef = useRef(lodashGet(props.iou, 'creatingIOUTransaction')); - const prevNetworkStatusRef = useRef(props.network.isOffline); const [previousStepIndex, setPreviousStepIndex] = useState(-1); const [currentStepIndex, setCurrentStepIndex] = useState(0); @@ -144,18 +139,11 @@ const MoneyRequestModal = (props) => { } }, [props.iou]); - useEffect(() => { - if (props.network.isOffline || !prevNetworkStatusRef.current) { - return; - } - - // User came back online, so let's refetch the currency details based on location - PersonalDetails.openMoneyRequestModalPage(); - }, [props.network.isOffline]); + // User came back online, so let's refetch the currency details based on location + useOnNetworkReconnect(PersonalDetails.openMoneyRequestModalPage); useEffect(() => { // Used to store previous prop values to compare on next render - prevNetworkStatusRef.current = props.network.isOffline; prevCreatingIOUTransactionStatusRef.current = lodashGet(props.iou, 'creatingIOUTransaction'); }); @@ -461,7 +449,6 @@ MoneyRequestModal.defaultProps = defaultProps; export default compose( withLocalize, - withNetwork(), withCurrentUserPersonalDetails, withOnyx({ report: {