1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-01 00:28:06 +01:00
metamask-extension/ui/app/pages/home/home.component.js
2020-11-02 17:41:28 -06:00

324 lines
9.8 KiB
JavaScript

import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { Redirect, Route } from 'react-router-dom'
import { formatDate } from '../../helpers/utils/util'
import AssetList from '../../components/app/asset-list'
import HomeNotification from '../../components/app/home-notification'
import MultipleNotifications from '../../components/app/multiple-notifications'
import TransactionList from '../../components/app/transaction-list'
import MenuBar from '../../components/app/menu-bar'
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 SwapsIntroPopup from '../swaps/intro-popup'
import {
ASSET_ROUTE,
RESTORE_VAULT_ROUTE,
CONFIRM_TRANSACTION_ROUTE,
CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE,
INITIALIZE_BACKUP_SEED_PHRASE_ROUTE,
CONNECT_ROUTE,
CONNECTED_ROUTE,
CONNECTED_ACCOUNTS_ROUTE,
AWAITING_SWAP_ROUTE,
BUILD_QUOTE_ROUTE,
VIEW_QUOTE_ROUTE,
} from '../../helpers/constants/routes'
const LEARN_MORE_URL =
'https://metamask.zendesk.com/hc/en-us/articles/360045129011-Intro-to-MetaMask-v8-extension'
export default class Home extends PureComponent {
static contextTypes = {
t: PropTypes.func,
}
static propTypes = {
history: PropTypes.object,
forgottenPassword: PropTypes.bool,
suggestedTokens: PropTypes.object,
unconfirmedTransactionsCount: PropTypes.number,
shouldShowSeedPhraseReminder: PropTypes.bool,
isPopup: PropTypes.bool,
isNotification: PropTypes.bool.isRequired,
threeBoxSynced: PropTypes.bool,
setupThreeBox: PropTypes.func,
turnThreeBoxSyncingOn: PropTypes.func,
showRestorePrompt: PropTypes.bool,
selectedAddress: PropTypes.string,
restoreFromThreeBox: PropTypes.func,
setShowRestorePromptToFalse: PropTypes.func,
threeBoxLastUpdated: PropTypes.number,
firstPermissionsRequestId: PropTypes.string,
totalUnapprovedCount: PropTypes.number.isRequired,
setConnectedStatusPopoverHasBeenShown: PropTypes.func,
connectedStatusPopoverHasBeenShown: PropTypes.bool,
defaultHomeActiveTabName: PropTypes.string,
onTabClick: PropTypes.func.isRequired,
setSwapsWelcomeMessageHasBeenShown: PropTypes.func.isRequired,
swapsWelcomeMessageHasBeenShown: PropTypes.bool.isRequired,
haveSwapsQuotes: PropTypes.bool.isRequired,
showAwaitingSwapScreen: PropTypes.bool.isRequired,
swapsFetchParams: PropTypes.object,
swapsEnabled: PropTypes.bool,
isMainnet: PropTypes.bool,
}
state = {
mounted: false,
}
componentDidMount() {
const {
firstPermissionsRequestId,
history,
isNotification,
suggestedTokens = {},
totalUnapprovedCount,
unconfirmedTransactionsCount,
haveSwapsQuotes,
showAwaitingSwapScreen,
swapsFetchParams,
} = this.props
this.setState({ mounted: true })
if (isNotification && totalUnapprovedCount === 0) {
global.platform.closeCurrentWindow()
} else 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 (unconfirmedTransactionsCount > 0) {
history.push(CONFIRM_TRANSACTION_ROUTE)
} else if (Object.keys(suggestedTokens).length > 0) {
history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE)
}
}
static getDerivedStateFromProps(
{
firstPermissionsRequestId,
isNotification,
suggestedTokens,
totalUnapprovedCount,
unconfirmedTransactionsCount,
haveSwapsQuotes,
showAwaitingSwapScreen,
swapsFetchParams,
},
{ mounted },
) {
if (!mounted) {
if (isNotification && totalUnapprovedCount === 0) {
return { closing: true }
} else if (
firstPermissionsRequestId ||
unconfirmedTransactionsCount > 0 ||
Object.keys(suggestedTokens).length > 0 ||
(!isNotification &&
(showAwaitingSwapScreen || haveSwapsQuotes || swapsFetchParams))
) {
return { redirecting: true }
}
}
return null
}
componentDidUpdate(_, prevState) {
const {
setupThreeBox,
showRestorePrompt,
threeBoxLastUpdated,
threeBoxSynced,
} = this.props
if (!prevState.closing && this.state.closing) {
global.platform.closeCurrentWindow()
}
if (threeBoxSynced && showRestorePrompt && threeBoxLastUpdated === null) {
setupThreeBox()
}
}
renderNotifications() {
const { t } = this.context
const {
history,
shouldShowSeedPhraseReminder,
isPopup,
selectedAddress,
restoreFromThreeBox,
turnThreeBoxSyncingOn,
setShowRestorePromptToFalse,
showRestorePrompt,
threeBoxLastUpdated,
} = this.props
return (
<MultipleNotifications>
{shouldShowSeedPhraseReminder ? (
<HomeNotification
descriptionText={t('backupApprovalNotice')}
acceptText={t('backupNow')}
onAccept={() => {
if (isPopup) {
global.platform.openExtensionInBrowser(
INITIALIZE_BACKUP_SEED_PHRASE_ROUTE,
)
} else {
history.push(INITIALIZE_BACKUP_SEED_PHRASE_ROUTE)
}
}}
infoText={t('backupApprovalInfo')}
key="home-backupApprovalNotice"
/>
) : null}
{threeBoxLastUpdated && showRestorePrompt ? (
<HomeNotification
descriptionText={t('restoreWalletPreferences', [
formatDate(threeBoxLastUpdated, 'M/d/y'),
])}
acceptText={t('restore')}
ignoreText={t('noThanks')}
infoText={t('dataBackupFoundInfo')}
onAccept={() => {
restoreFromThreeBox(selectedAddress).then(() => {
turnThreeBoxSyncingOn()
})
}}
onIgnore={() => {
setShowRestorePromptToFalse()
}}
key="home-privacyModeDefault"
/>
) : null}
</MultipleNotifications>
)
}
renderPopover = () => {
const { setConnectedStatusPopoverHasBeenShown } = this.props
const { t } = this.context
return (
<Popover
title={t('whatsThis')}
onClose={setConnectedStatusPopoverHasBeenShown}
className="home__connected-status-popover"
showArrow
CustomBackground={({ onClose }) => {
return (
<div
className="home__connected-status-popover-bg-container"
onClick={onClose}
>
<div className="home__connected-status-popover-bg" />
</div>
)
}}
footer={
<>
<a href={LEARN_MORE_URL} target="_blank" rel="noopener noreferrer">
{t('learnMore')}
</a>
<Button
type="primary"
onClick={setConnectedStatusPopoverHasBeenShown}
>
{t('dismiss')}
</Button>
</>
}
>
<main className="home__connect-status-text">
<div>{t('metaMaskConnectStatusParagraphOne')}</div>
<div>{t('metaMaskConnectStatusParagraphTwo')}</div>
<div>{t('metaMaskConnectStatusParagraphThree')}</div>
</main>
</Popover>
)
}
render() {
const { t } = this.context
const {
defaultHomeActiveTabName,
onTabClick,
forgottenPassword,
history,
connectedStatusPopoverHasBeenShown,
isPopup,
swapsWelcomeMessageHasBeenShown,
setSwapsWelcomeMessageHasBeenShown,
swapsEnabled,
isMainnet,
} = this.props
if (forgottenPassword) {
return <Redirect to={{ pathname: RESTORE_VAULT_ROUTE }} />
} else if (this.state.closing || this.state.redirecting) {
return null
}
return (
<div className="main-container">
<Route path={CONNECTED_ROUTE} component={ConnectedSites} exact />
<Route
path={CONNECTED_ACCOUNTS_ROUTE}
component={ConnectedAccounts}
exact
/>
<div className="home__container">
{!swapsWelcomeMessageHasBeenShown && swapsEnabled && isMainnet ? (
<SwapsIntroPopup onClose={setSwapsWelcomeMessageHasBeenShown} />
) : null}
{isPopup && !connectedStatusPopoverHasBeenShown
? this.renderPopover()
: null}
<div className="home__main-view">
<MenuBar />
<div className="home__balance-wrapper">
<EthOverview />
</div>
<Tabs
defaultActiveTabName={defaultHomeActiveTabName}
onTabClick={onTabClick}
tabsClassName="home__tabs"
>
<Tab
activeClassName="home__tab--active"
className="home__tab"
data-testid="home__asset-tab"
name={t('assets')}
>
<AssetList
onClickAsset={(asset) =>
history.push(`${ASSET_ROUTE}/${asset}`)
}
/>
</Tab>
<Tab
activeClassName="home__tab--active"
className="home__tab"
data-testid="home__activity-tab"
name={t('activity')}
>
<TransactionList />
</Tab>
</Tabs>
</div>
{this.renderNotifications()}
</div>
</div>
)
}
}