Skip to content

Commit

Permalink
fix re renders of wallet view on every navigation action
Browse files Browse the repository at this point in the history
  • Loading branch information
tommasini committed Oct 24, 2024
1 parent 5482dbd commit aaef69b
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ import IPFSGatewaySettings from '../../Settings/IPFSGatewaySettings';
import IncomingTransactionsSettings from '../../Settings/IncomingTransactionsSettings';
import BatchAccountBalanceSettings from '../../Settings/BatchAccountBalanceSettings';
import { isNotificationsFeatureEnabled } from '../../../../util/notifications';
import useCheckNftAutoDetectionModal from '../../../hooks/useCheckNftAutoDetectionModal';
import useCheckMultiRpcModal from '../../../hooks/useCheckMultiRpcModal';

const Heading: React.FC<HeadingProps> = ({ children, first }) => {
const { colors } = useTheme();
Expand Down Expand Up @@ -136,13 +138,12 @@ const Settings: React.FC = () => {
loading: disableNotificationsLoading,
error: disableNotificationsError,
} = useDisableNotifications();
// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const browserHistory = useSelector((state: any) => state.browser.history);

// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const lockTime = useSelector((state: any) => state.settings.lockTime);
const browserHistory = useSelector(
(state: RootState) => state.browser.history,
);

const lockTime = useSelector((state: RootState) => state.settings.lockTime);
const useTransactionSimulations = useSelector(
selectUseTransactionSimulations,
);
Expand All @@ -152,11 +153,21 @@ const Settings: React.FC = () => {
);

const seedphraseBackedUp = useSelector(
// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(state: any) => state.user.seedphraseBackedUp,
(state: RootState) => state.user.seedphraseBackedUp,
);

/**
* Shows Nft auto detect modal if the user is on mainnet, never saw the modal and have nft detection off
*/
useCheckNftAutoDetectionModal();

/**
* Show multi rpc modal if there are networks duplicated and if never showed before
*/
useCheckMultiRpcModal();

const type = useSelector(selectProviderType);

const isMainnet = type === MAINNET;

const updateNavBar = useCallback(() => {
Expand Down
80 changes: 17 additions & 63 deletions app/components/Views/Wallet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
AppStateStatus,
} from 'react-native';
import type { Theme } from '@metamask/design-tokens';
import { connect, useDispatch, useSelector } from 'react-redux';
import { connect, useSelector } from 'react-redux';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import DefaultTabBar from 'react-native-scrollable-tab-view/DefaultTabBar';
import { baseStyles } from '../../../styles/common';
Expand Down Expand Up @@ -82,19 +82,10 @@ import { RootState } from '../../../reducers';
import usePrevious from '../../hooks/usePrevious';
import { selectSelectedInternalAccountChecksummedAddress } from '../../../selectors/accountsController';
import { selectAccountBalanceByChainId } from '../../../selectors/accountTrackerController';
import {
selectShowMultiRpcModal,
selectUseNftDetection,
} from '../../../selectors/preferencesController';
import {
setNftAutoDetectionModalOpen,
setMultiRpcMigrationModalOpen,
} from '../../../actions/security';
import {
hideNftFetchingLoadingIndicator as hideNftFetchingLoadingIndicatorAction,
showNftFetchingLoadingIndicator as showNftFetchingLoadingIndicatorAction,
} from '../../../reducers/collectibles';
import { getCurrentRoute } from '../../../reducers/navigation';
import { WalletViewSelectorsIDs } from '../../../../e2e/selectors/wallet/WalletView.selectors';
import {
getMetamaskNotificationsUnreadCount,
Expand All @@ -105,7 +96,8 @@ import {
import { ButtonVariants } from '../../../component-library/components/Buttons/Button';
import { useListNotifications } from '../../../util/notifications/hooks/useNotifications';
import { PortfolioBalance } from '../../UI/Tokens/TokenList/PortfolioBalance';
import { isObject } from 'lodash';
import useCheckNftAutoDetectionModal from '../../hooks/useCheckNftAutoDetectionModal';
import useCheckMultiRpcModal from '../../hooks/useCheckMultiRpcModal';

const createStyles = ({ colors, typography }: Theme) =>
StyleSheet.create({
Expand Down Expand Up @@ -163,7 +155,6 @@ const Wallet = ({
navigation,
storePrivacyPolicyShownDate,
shouldShowNewPrivacyToast,
currentRouteName,
storePrivacyPolicyClickedOrClosed,
showNftFetchingLoadingIndicator,
hideNftFetchingLoadingIndicator,
Expand All @@ -177,7 +168,7 @@ const Wallet = ({
const { trackEvent } = useMetrics();
const styles = createStyles(theme);
const { colors } = theme;
const dispatch = useDispatch();

const networkConfigurations = useSelector(selectNetworkConfigurations);

/**
Expand Down Expand Up @@ -292,9 +283,7 @@ const Wallet = ({
* Network onboarding state
*/
const networkOnboardingState = useSelector(
// TODO: Replace "any" with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(state: any) => state.networkOnboarded.networkOnboardedState,
(state: RootState) => state.networkOnboarded.networkOnboardedState,
);

const isNotificationEnabled = useSelector(
Expand All @@ -314,11 +303,15 @@ const Wallet = ({
const networkName = networkConfigurations?.[chainId]?.name ?? name;

const networkImageSource = useSelector(selectNetworkImageSource);
const useNftDetection = useSelector(selectUseNftDetection);
const showMultiRpcModal = useSelector(selectShowMultiRpcModal);
const isNFTAutoDetectionModalViewed = useSelector(
(state: RootState) => state.security.isNFTAutoDetectionModalViewed,
);
/**
* Shows Nft auto detect modal if the user is on mainnet, never saw the modal and have nft detection off
*/
useCheckNftAutoDetectionModal();

/**
* Show multi rpc modal if there are networks duplicated and if never showed before
*/
useCheckMultiRpcModal();

/**
* Callback to trigger when pressing the navigation title.
Expand All @@ -332,47 +325,10 @@ const Wallet = ({
});
}, [navigate, providerConfig.chainId, trackEvent]);

const isNetworkDuplicated = Object.values(networkConfigurations).some(
(networkConfiguration) =>
isObject(networkConfiguration) &&
Array.isArray(networkConfiguration.rpcEndpoints) &&
networkConfiguration.rpcEndpoints.length > 1,
);

const checkNftAutoDetectionModal = useCallback(() => {
const isOnMainnet = isMainNet(providerConfig.chainId);
if (!useNftDetection && isOnMainnet && !isNFTAutoDetectionModalViewed) {
navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, {
screen: Routes.MODAL.NFT_AUTO_DETECTION_MODAL,
});
dispatch(setNftAutoDetectionModalOpen(true));
}
}, [
dispatch,
isNFTAutoDetectionModalViewed,
navigation,
providerConfig.chainId,
useNftDetection,
]);

const checkMultiRpcModal = useCallback(() => {
if (showMultiRpcModal && isNetworkDuplicated) {
navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, {
screen: Routes.MODAL.MULTI_RPC_MIGRATION_MODAL,
});
dispatch(setMultiRpcMigrationModalOpen(true));
}
}, [dispatch, showMultiRpcModal, navigation, isNetworkDuplicated]);

/**
* Check to see if notifications are enabled
*/
useEffect(() => {
if (
currentRouteName === 'Wallet' ||
currentRouteName === 'SecuritySettings'
) {
checkNftAutoDetectionModal();
checkMultiRpcModal();
}

async function checkIfNotificationsAreEnabled() {
await NotificationsService.isDeviceNotificationEnabled();
}
Expand Down Expand Up @@ -432,7 +388,6 @@ const Wallet = ({
providerConfig.rpcUrl,
networkOnboardingState,
prevChainId,
checkNftAutoDetectionModal,
accountBalanceByChainId?.balance,
]);

Expand Down Expand Up @@ -679,7 +634,6 @@ const Wallet = ({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const mapStateToProps = (state: any) => ({
shouldShowNewPrivacyToast: shouldShowNewPrivacyToastSelector(state),
currentRouteName: getCurrentRoute(state),
});

// TODO: Replace "any" with type
Expand Down
1 change: 1 addition & 0 deletions app/components/hooks/useCheckMultiRpcModal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './useCheckMultiRpcModal';
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useCallback, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import { isObject } from '@metamask/utils';
import Routes from '../../../constants/navigation/Routes';
import { setMultiRpcMigrationModalOpen } from '../../../actions/security';
import { selectShowMultiRpcModal } from '../../../selectors/preferencesController';
import { selectNetworkConfigurations } from '../../../selectors/networkController';

const useCheckMultiRpcModal = () => {
const dispatch = useDispatch();
const navigation = useNavigation();
const networkConfigurations = useSelector(selectNetworkConfigurations);

const showMultiRpcModal = useSelector(selectShowMultiRpcModal);

const isNetworkDuplicated = Object.values(networkConfigurations).some(
(networkConfiguration) =>
isObject(networkConfiguration) &&
Array.isArray(networkConfiguration.rpcEndpoints) &&
networkConfiguration.rpcEndpoints.length > 1,
);

const checkMultiRpcModal = useCallback(() => {
if (showMultiRpcModal && isNetworkDuplicated) {
navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, {
screen: Routes.MODAL.MULTI_RPC_MIGRATION_MODAL,
});
dispatch(setMultiRpcMigrationModalOpen(true));
}
}, [dispatch, showMultiRpcModal, navigation, isNetworkDuplicated]);

useEffect(() => {
checkMultiRpcModal();
}, [checkMultiRpcModal]);
};

export default useCheckMultiRpcModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './useCheckNftAutoDetectionModal';
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useCallback, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigation } from '@react-navigation/native';

import { selectUseNftDetection } from '../../../selectors/preferencesController';
import { isMainNet } from '../../../util/networks';
import Routes from '../../../constants/navigation/Routes';
import { setNftAutoDetectionModalOpen } from '../../../actions/security';
import { RootState } from '../../../reducers';
import { selectProviderConfig } from '../../../selectors/networkController';

const useCheckNftAutoDetectionModal = () => {
const dispatch = useDispatch();
const navigation = useNavigation();
const useNftDetection = useSelector(selectUseNftDetection);
const providerConfig = useSelector(selectProviderConfig);
const isNFTAutoDetectionModalViewed = useSelector(
(state: RootState) => state.security.isNFTAutoDetectionModalViewed,
);

const checkNftAutoDetectionModal = useCallback(() => {
const isOnMainnet = isMainNet(providerConfig.chainId);
if (!useNftDetection && isOnMainnet && !isNFTAutoDetectionModalViewed) {
navigation.navigate(Routes.MODAL.ROOT_MODAL_FLOW, {
screen: Routes.MODAL.NFT_AUTO_DETECTION_MODAL,
});
dispatch(setNftAutoDetectionModalOpen(true));
}
}, [
dispatch,
isNFTAutoDetectionModalViewed,
navigation,
providerConfig.chainId,
useNftDetection,
]);

useEffect(() => {
checkNftAutoDetectionModal();
}, [checkNftAutoDetectionModal]);
};

export default useCheckNftAutoDetectionModal;

0 comments on commit aaef69b

Please sign in to comment.