Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ describe('Smart Transactions', function () {
await sendPage.selectTokenFee('USDC');
await driver.delay(1000);
await sendPage.clickConfirmButton();
await sendPage.clickViewActivity();

const activityList = new ActivityListPage(driver);
await activityList.checkNoFailedTransactions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const CreateNamedSnapAccount: React.FC<CreateNamedSnapAccountProps> = ({
onActionComplete={rejectAction}
onCreateAccount={onCreateAccount}
getNextAvailableAccountName={getNextAccountName}
redirectToOverview={false}
/>
</Box>
);
Expand Down
6 changes: 6 additions & 0 deletions ui/ducks/swaps/swaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@ export const getSwapsQuotePrefetchingRefreshTime = (state) =>
export const getBackgroundSwapRouteState = (state) =>
state.metamask.swapsState.routeState;

export const selectShowAwaitingSwapScreen = (state) =>
state.metamask.swapsState.routeState === 'awaiting';

export const getCustomSwapsGas = (state) =>
state.metamask.swapsState.customMaxGas;

Expand All @@ -371,6 +374,9 @@ export const getFetchParams = (state) => state.metamask.swapsState.fetchParams;

export const getQuotes = (state) => state.metamask.swapsState.quotes;

export const selectHasSwapsQuotes = (state) =>
Boolean(Object.values(state.metamask.swapsState.quotes || {}).length);

export const getQuotesLastFetched = (state) =>
state.metamask.swapsState.quotesLastFetched;

Expand Down
94 changes: 2 additions & 92 deletions ui/pages/home/home.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ import {
RESTORE_VAULT_ROUTE,
CONNECTED_ROUTE,
CONNECTED_ACCOUNTS_ROUTE,
AWAITING_SWAP_ROUTE,
PREPARE_SWAP_ROUTE,
CROSS_CHAIN_SWAP_ROUTE,
ONBOARDING_REVIEW_SRP_ROUTE,
} from '../../helpers/constants/routes';
import ZENDESK_URLS from '../../helpers/constants/zendesk-url';
Expand All @@ -66,7 +63,6 @@ import {
} from '../../../shared/lib/ui-utils';
import { AccountOverview } from '../../components/multichain';
import { setEditedNetwork } from '../../store/actions';
import { getConfirmationRoute } from '../confirmations/hooks/useConfirmationNavigation';
import PasswordOutdatedModal from '../../components/app/password-outdated-modal';
import ShieldEntryModal from '../../components/app/shield-entry-modal';
import RewardsOnboardingModal from '../../components/app/rewards/onboarding/OnboardingModal';
Expand Down Expand Up @@ -116,27 +112,19 @@ export default class Home extends PureComponent {
showMultiRpcModal: PropTypes.bool.isRequired,
showUpdateModal: PropTypes.bool.isRequired,
newNetworkAddedConfigurationId: PropTypes.string,
isNotification: PropTypes.bool.isRequired,
isSidepanel: PropTypes.bool.isRequired,
// This prop is used in the `shouldCloseNotificationPopup` function
// eslint-disable-next-line react/no-unused-prop-types
totalUnapprovedCount: PropTypes.number.isRequired,
defaultHomeActiveTabName: PropTypes.string,
participateInMetaMetrics: PropTypes.bool.isRequired,
onTabClick: PropTypes.func.isRequired,
haveSwapsQuotes: PropTypes.bool.isRequired,
showAwaitingSwapScreen: PropTypes.bool.isRequired,
haveBridgeQuotes: PropTypes.bool.isRequired,
setDataCollectionForMarketing: PropTypes.func.isRequired,
dataCollectionForMarketing: PropTypes.bool,
swapsFetchParams: PropTypes.object,
location: PropTypes.object,
shouldShowWeb3ShimUsageNotification: PropTypes.bool.isRequired,
setWeb3ShimUsageAlertDismissed: PropTypes.func.isRequired,
originOfCurrentTab: PropTypes.string,
disableWeb3ShimUsageAlert: PropTypes.func.isRequired,
pendingApprovals: PropTypes.arrayOf(PropTypes.object).isRequired,
hasApprovalFlows: PropTypes.bool.isRequired,
infuraBlocked: PropTypes.bool.isRequired,
setRecoveryPhraseReminderHasBeenShown: PropTypes.func.isRequired,
setRecoveryPhraseReminderLastShown: PropTypes.func.isRequired,
Expand All @@ -160,7 +148,6 @@ export default class Home extends PureComponent {
clearNewNetworkAdded: PropTypes.func,
clearEditedNetwork: PropTypes.func,
setActiveNetwork: PropTypes.func,
hasAllowedPopupRedirectApprovals: PropTypes.bool.isRequired,
useExternalServices: PropTypes.bool,
setBasicFunctionalityModalOpen: PropTypes.func,
fetchBuyableChains: PropTypes.func.isRequired,
Expand All @@ -171,7 +158,6 @@ export default class Home extends PureComponent {
showShieldEntryModal: PropTypes.bool,
isSocialLoginFlow: PropTypes.bool,
lookupSelectedNetworks: PropTypes.func.isRequired,
navState: PropTypes.object,
evaluateCohortEligibility: PropTypes.func,
pendingShieldCohort: PropTypes.string,
setPendingShieldCohort: PropTypes.func,
Expand All @@ -183,80 +169,15 @@ export default class Home extends PureComponent {
state = {
canShowBlockageNotification: true,
notificationClosing: false,
redirecting: false,
};

constructor(props) {
super(props);

const {
attemptCloseNotificationPopup,
haveSwapsQuotes,
haveBridgeQuotes,
isNotification,
pendingApprovals,
showAwaitingSwapScreen,
swapsFetchParams,
location,
navState,
} = this.props;
// Read stayOnHomePage from both v5 location.state and v5-compat navState
const stayOnHomePage =
Boolean(location?.state?.stayOnHomePage) ||
Boolean(navState?.stayOnHomePage);

const { attemptCloseNotificationPopup } = this.props;
if (shouldCloseNotificationPopup(props)) {
this.state.notificationClosing = true;
attemptCloseNotificationPopup();
} else if (
pendingApprovals.length ||
(!isNotification &&
!stayOnHomePage &&
(showAwaitingSwapScreen ||
haveSwapsQuotes ||
swapsFetchParams ||
haveBridgeQuotes))
) {
this.state.redirecting = true;
}
}

checkStatusAndNavigate() {
const {
navigate,
isNotification,
haveSwapsQuotes,
haveBridgeQuotes,
showAwaitingSwapScreen,
swapsFetchParams,
location,
pendingApprovals,
hasApprovalFlows,
navState,
} = this.props;
// Read stayOnHomePage from both v5 location.state and v5-compat navState
const stayOnHomePage =
Boolean(location?.state?.stayOnHomePage) ||
Boolean(navState?.stayOnHomePage);

const canRedirect = !isNotification && !stayOnHomePage;
if (canRedirect && showAwaitingSwapScreen) {
navigate(AWAITING_SWAP_ROUTE);
} else if (canRedirect && (haveSwapsQuotes || swapsFetchParams)) {
navigate(PREPARE_SWAP_ROUTE);
} else if (canRedirect && haveBridgeQuotes) {
navigate(CROSS_CHAIN_SWAP_ROUTE + PREPARE_SWAP_ROUTE);
} else if (pendingApprovals.length || hasApprovalFlows) {
const url = getConfirmationRoute(
pendingApprovals?.[0]?.id,
pendingApprovals,
hasApprovalFlows,
'', // queryString
);

if (url) {
navigate(url, { replace: true });
}
}
}

Expand All @@ -277,8 +198,6 @@ export default class Home extends PureComponent {
}

componentDidMount() {
this.checkStatusAndNavigate();

this.props.fetchBuyableChains();

// Check for redirect after default page
Expand All @@ -304,12 +223,9 @@ export default class Home extends PureComponent {
componentDidUpdate(_prevProps, prevState) {
const {
attemptCloseNotificationPopup,
isNotification,
hasAllowedPopupRedirectApprovals,
newNetworkAddedConfigurationId,
setActiveNetwork,
clearNewNetworkAdded,
isSidepanel,
pendingShieldCohort,
evaluateCohortEligibility,
setPendingShieldCohort,
Expand All @@ -331,12 +247,6 @@ export default class Home extends PureComponent {

if (notificationClosing && !prevState.notificationClosing) {
attemptCloseNotificationPopup();
} else if (
isNotification ||
hasAllowedPopupRedirectApprovals ||
isSidepanel
) {
this.checkStatusAndNavigate();
}

// Check for pending Shield cohort evaluation if user is signed in
Expand Down Expand Up @@ -873,7 +783,7 @@ export default class Home extends PureComponent {

if (forgottenPassword) {
return <Navigate to={RESTORE_VAULT_ROUTE} replace />;
} else if (this.state.notificationClosing || this.state.redirecting) {
} else if (this.state.notificationClosing) {
return null;
}

Expand Down
119 changes: 119 additions & 0 deletions ui/pages/routes/confirmation-handler.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { useCallback, useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router-dom-v5-compat';
import { useSelector } from 'react-redux';

import {
AWAITING_SWAP_ROUTE,
PREPARE_SWAP_ROUTE,
CROSS_CHAIN_SWAP_ROUTE,
DEFAULT_ROUTE,
} from '../../helpers/constants/routes';
import { getConfirmationRoute } from '../confirmations/hooks/useConfirmationNavigation';
// eslint-disable-next-line import/no-restricted-paths
import { getEnvironmentType } from '../../../app/scripts/lib/util';
import {
ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_NOTIFICATION,
SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES,
} from '../../../shared/constants/app';
import {
selectHasApprovalFlows,
selectHasBridgeQuotes,
selectPendingApprovalsForNavigation,
} from '../../selectors';
import {
getFetchParams,
selectHasSwapsQuotes,
selectShowAwaitingSwapScreen,
} from '../../ducks/swaps/swaps';
import { useNavState } from '../../contexts/navigation-state';

const SNAP_APPROVAL_TYPES = [
'wallet_installSnapResult',
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.confirmAccountCreation,
SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.confirmAccountRemoval,
SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.showNameSnapAccount,
SNAP_MANAGE_ACCOUNTS_CONFIRMATION_TYPES.showSnapAccountRedirect,
///: END:ONLY_INCLUDE_IF
];

export const ConfirmationHandler = () => {
const navigate = useNavigate();
const location = useLocation();
const { pathname } = location;
const navState = useNavState();

const envType = getEnvironmentType();
const isNotification = envType === ENVIRONMENT_TYPE_NOTIFICATION;
const isFullscreen = envType === ENVIRONMENT_TYPE_FULLSCREEN;

const showAwaitingSwapScreen = useSelector(selectShowAwaitingSwapScreen);
const hasSwapsQuotes = useSelector(selectHasSwapsQuotes);
const hasBridgeQuotes = useSelector(selectHasBridgeQuotes);
const swapsFetchParams = useSelector(getFetchParams);
const pendingApprovals = useSelector(selectPendingApprovalsForNavigation);
const hasApprovalFlows = useSelector(selectHasApprovalFlows);

// Read stayOnHomePage from both v5 location.state and v5-compat navState
const stayOnHomePage =
Boolean(location.state?.stayOnHomePage) ||
Boolean(navState?.stayOnHomePage);

const canRedirect = !isNotification && !stayOnHomePage;

// Ported from home.component - checkStatusAndNavigate()
const checkStatusAndNavigate = useCallback(() => {
if (canRedirect && showAwaitingSwapScreen) {
navigate(AWAITING_SWAP_ROUTE);
} else if (canRedirect && (hasSwapsQuotes || swapsFetchParams)) {
navigate(PREPARE_SWAP_ROUTE);
} else if (canRedirect && hasBridgeQuotes) {
navigate(CROSS_CHAIN_SWAP_ROUTE + PREPARE_SWAP_ROUTE);
} else if (pendingApprovals.length || hasApprovalFlows) {
const url = getConfirmationRoute(
pendingApprovals?.[0]?.id,
pendingApprovals,
hasApprovalFlows,
'',
);

if (url) {
navigate(url, { replace: true });
}
}
}, [
canRedirect,
hasApprovalFlows,
hasBridgeQuotes,
hasSwapsQuotes,
navigate,
pendingApprovals,
showAwaitingSwapScreen,
swapsFetchParams,
]);

const hasAllowedPopupRedirectApprovals = pendingApprovals.some((approval) =>
SNAP_APPROVAL_TYPES.includes(approval.type),
);

useEffect(() => {
// Only run when on home/default page (for now)
if (pathname !== DEFAULT_ROUTE) {
return;
}

if (isFullscreen && !hasAllowedPopupRedirectApprovals) {
return;
}

checkStatusAndNavigate();
}, [
checkStatusAndNavigate,
hasAllowedPopupRedirectApprovals,
isFullscreen,
pathname,
]);

return null;
};
Loading
Loading