import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { Redirect, Route } from 'react-router-dom';
import AssetList from '../../components/app/asset-list';
import NftsTab from '../../components/app/nfts-tab';
import HomeNotification from '../../components/app/home-notification';
import MultipleNotifications from '../../components/app/multiple-notifications';
import TransactionList from '../../components/app/transaction-list';
import Popover from '../../components/ui/popover';
import Button from '../../components/ui/button';
import ConnectedSites from '../connected-sites';
import ConnectedAccounts from '../connected-accounts';
import { Tabs, Tab } from '../../components/ui/tabs';
import { EthOverview } from '../../components/app/wallet-overview';
import WhatsNewPopup from '../../components/app/whats-new-popup';
import TermsOfUsePopup from '../../components/app/terms-of-use-popup';
import ActionableMessage from '../../components/ui/actionable-message/actionable-message';
import {
FONT_WEIGHT,
DISPLAY,
TextColor,
TextVariant,
} from '../../helpers/constants/design-system';
import { SECOND } from '../../../shared/constants/time';
import {
ButtonIcon,
ButtonIconSize,
IconName,
Text,
Box,
} from '../../components/component-library';
import {
ASSET_ROUTE,
RESTORE_VAULT_ROUTE,
CONFIRM_TRANSACTION_ROUTE,
CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE,
CONFIRM_ADD_SUGGESTED_NFT_ROUTE,
CONNECT_ROUTE,
CONNECTED_ROUTE,
CONNECTED_ACCOUNTS_ROUTE,
AWAITING_SWAP_ROUTE,
BUILD_QUOTE_ROUTE,
VIEW_QUOTE_ROUTE,
CONFIRMATION_V_NEXT_ROUTE,
ADD_NFT_ROUTE,
} from '../../helpers/constants/routes';
import ZENDESK_URLS from '../../helpers/constants/zendesk-url';
function shouldCloseNotificationPopup({
isNotification,
totalUnapprovedCount,
hasApprovalFlows,
isSigningQRHardwareTransaction,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
waitForConfirmDeepLinkDialog,
institutionalConnectRequests,
///: END:ONLY_INCLUDE_IN
}) {
let shouldCLose =
isNotification &&
totalUnapprovedCount === 0 &&
!hasApprovalFlows &&
!isSigningQRHardwareTransaction;
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
shouldCLose &&=
// MMI User must be shown a deeplink
!waitForConfirmDeepLinkDialog &&
// MMI User is connecting to custodian or compliance
institutionalConnectRequests.length === 0;
///: END:ONLY_INCLUDE_IN
return shouldCLose;
}
export default class Home extends PureComponent {
static contextTypes = {
t: PropTypes.func,
trackEvent: PropTypes.func,
};
static propTypes = {
history: PropTypes.object,
forgottenPassword: PropTypes.bool,
hasTransactionPendingApprovals: PropTypes.bool.isRequired,
hasWatchTokenPendingApprovals: PropTypes.bool,
hasWatchNftPendingApprovals: PropTypes.bool,
isPopup: PropTypes.bool,
isNotification: PropTypes.bool.isRequired,
firstPermissionsRequestId: PropTypes.string,
// This prop is used in the `shouldCloseNotificationPopup` function
// eslint-disable-next-line react/no-unused-prop-types
totalUnapprovedCount: PropTypes.number.isRequired,
setConnectedStatusPopoverHasBeenShown: PropTypes.func,
connectedStatusPopoverHasBeenShown: PropTypes.bool,
defaultHomeActiveTabName: PropTypes.string,
firstTimeFlowType: PropTypes.string,
completedOnboarding: PropTypes.bool,
onTabClick: PropTypes.func.isRequired,
haveSwapsQuotes: PropTypes.bool.isRequired,
showAwaitingSwapScreen: PropTypes.bool.isRequired,
swapsFetchParams: PropTypes.object,
shouldShowWeb3ShimUsageNotification: PropTypes.bool.isRequired,
setWeb3ShimUsageAlertDismissed: PropTypes.func.isRequired,
originOfCurrentTab: PropTypes.string,
disableWeb3ShimUsageAlert: PropTypes.func.isRequired,
pendingConfirmations: PropTypes.arrayOf(PropTypes.object).isRequired,
hasApprovalFlows: PropTypes.bool.isRequired,
infuraBlocked: PropTypes.bool.isRequired,
showWhatsNewPopup: PropTypes.bool.isRequired,
hideWhatsNewPopup: PropTypes.func.isRequired,
showTermsOfUsePopup: PropTypes.bool.isRequired,
announcementsToShow: PropTypes.bool.isRequired,
///: BEGIN:ONLY_INCLUDE_IN(snaps)
errorsToShow: PropTypes.object.isRequired,
shouldShowErrors: PropTypes.bool.isRequired,
removeSnapError: PropTypes.func.isRequired,
///: END:ONLY_INCLUDE_IN
setTermsOfUseLastAgreed: PropTypes.func.isRequired,
showOutdatedBrowserWarning: PropTypes.bool.isRequired,
setOutdatedBrowserWarningLastShown: PropTypes.func.isRequired,
newNetworkAddedName: PropTypes.string,
// This prop is used in the `shouldCloseNotificationPopup` function
// eslint-disable-next-line react/no-unused-prop-types
isSigningQRHardwareTransaction: PropTypes.bool.isRequired,
newNftAddedMessage: PropTypes.string,
setNewNftAddedMessage: PropTypes.func.isRequired,
removeNftMessage: PropTypes.string,
setRemoveNftMessage: PropTypes.func.isRequired,
closeNotificationPopup: PropTypes.func.isRequired,
newTokensImported: PropTypes.string,
setNewTokensImported: PropTypes.func.isRequired,
newNetworkAddedConfigurationId: PropTypes.string,
clearNewNetworkAdded: PropTypes.func,
setActiveNetwork: PropTypes.func,
onboardedInThisUISession: PropTypes.bool,
};
state = {
canShowBlockageNotification: true,
notificationClosing: false,
redirecting: false,
};
constructor(props) {
super(props);
const {
closeNotificationPopup,
firstPermissionsRequestId,
haveSwapsQuotes,
isNotification,
showAwaitingSwapScreen,
hasWatchTokenPendingApprovals,
hasWatchNftPendingApprovals,
swapsFetchParams,
hasTransactionPendingApprovals,
} = this.props;
if (shouldCloseNotificationPopup(props)) {
this.state.notificationClosing = true;
closeNotificationPopup();
} else if (
firstPermissionsRequestId ||
hasTransactionPendingApprovals ||
hasWatchTokenPendingApprovals ||
hasWatchNftPendingApprovals ||
(!isNotification &&
(showAwaitingSwapScreen || haveSwapsQuotes || swapsFetchParams))
) {
this.state.redirecting = true;
}
}
checkStatusAndNavigate() {
const {
firstPermissionsRequestId,
history,
isNotification,
hasTransactionPendingApprovals,
hasWatchTokenPendingApprovals,
hasWatchNftPendingApprovals,
haveSwapsQuotes,
showAwaitingSwapScreen,
swapsFetchParams,
pendingConfirmations,
hasApprovalFlows,
} = this.props;
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
this.shouldCloseCurrentWindow();
///: END:ONLY_INCLUDE_IN
if (!isNotification && showAwaitingSwapScreen) {
history.push(AWAITING_SWAP_ROUTE);
} else if (!isNotification && haveSwapsQuotes) {
history.push(VIEW_QUOTE_ROUTE);
} else if (!isNotification && swapsFetchParams) {
history.push(BUILD_QUOTE_ROUTE);
} else if (firstPermissionsRequestId) {
history.push(`${CONNECT_ROUTE}/${firstPermissionsRequestId}`);
} else if (hasTransactionPendingApprovals) {
history.push(CONFIRM_TRANSACTION_ROUTE);
} else if (hasWatchTokenPendingApprovals) {
history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE);
} else if (hasWatchNftPendingApprovals) {
history.push(CONFIRM_ADD_SUGGESTED_NFT_ROUTE);
} else if (pendingConfirmations.length > 0 || hasApprovalFlows) {
history.push(CONFIRMATION_V_NEXT_ROUTE);
}
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
this.checkInstitutionalConnectRequest();
///: END:ONLY_INCLUDE_IN
}
componentDidMount() {
this.checkStatusAndNavigate();
}
static getDerivedStateFromProps(props) {
if (shouldCloseNotificationPopup(props)) {
return { notificationClosing: true };
}
return null;
}
componentDidUpdate(_prevProps, prevState) {
const { closeNotificationPopup, isNotification } = this.props;
const { notificationClosing } = this.state;
if (notificationClosing && !prevState.notificationClosing) {
closeNotificationPopup();
} else if (isNotification) {
this.checkStatusAndNavigate();
}
}
onAcceptTermsOfUse = () => {
const { setTermsOfUseLastAgreed } = this.props;
setTermsOfUseLastAgreed(new Date().getTime());
};
onOutdatedBrowserWarningClose = () => {
const { setOutdatedBrowserWarningLastShown } = this.props;
setOutdatedBrowserWarningLastShown(new Date().getTime());
};
renderNotifications() {
const { t } = this.context;
const {
shouldShowWeb3ShimUsageNotification,
setWeb3ShimUsageAlertDismissed,
originOfCurrentTab,
disableWeb3ShimUsageAlert,
///: BEGIN:ONLY_INCLUDE_IN(snaps)
removeSnapError,
errorsToShow,
shouldShowErrors,
///: END:ONLY_INCLUDE_IN
infuraBlocked,
showOutdatedBrowserWarning,
newNftAddedMessage,
setNewNftAddedMessage,
newNetworkAddedName,
removeNftMessage,
setRemoveNftMessage,
newTokensImported,
setNewTokensImported,
newNetworkAddedConfigurationId,
clearNewNetworkAdded,
setActiveNetwork,
} = this.props;
const onAutoHide = () => {
setNewNftAddedMessage('');
setRemoveNftMessage('');
};
const autoHideDelay = 5 * SECOND;
return (