1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Make permission approval redirect flow consistent (#8755)

* make redirect flow consistent

* remove cancel redirect

* extract redirect component into own file
This commit is contained in:
Erik Marks 2020-06-12 09:38:20 -07:00 committed by GitHub
commit 1323233cfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 303 additions and 362 deletions

View File

@ -73,12 +73,6 @@
"showIncomingTransactionsDescription": {
"message": "Select this to use Etherscan to show incoming transactions in the transactions list"
},
"cancelling": {
"message": "Cancelling..."
},
"cancelledConnectionWithMetaMask": {
"message": "Cancelled Connection With MetaMask"
},
"chartOnlyAvailableEth": {
"message": "Chart only available on Ethereum networks."
},
@ -88,9 +82,6 @@
"connectWithMetaMask": {
"message": "Connect With MetaMask"
},
"connectingWithMetaMask": {
"message": "Connecting With MetaMask..."
},
"connectTo": {
"message": "Connect to $1",
"description": "$1 is the name/origin of a site/dapp that the user can connect to metamask"

View File

@ -5,18 +5,12 @@
"showIncomingTransactionsDescription": {
"message": "Usa Etherscan per visualizzare le transazioni in ingresso nella lista delle transazioni"
},
"cancelledConnectionWithMetaMask": {
"message": "Transazioni Annullate con MetaMask"
},
"chartOnlyAvailableEth": {
"message": "Grafico disponibile solo per le reti Ethereum."
},
"connectedSites": {
"message": "Siti connessi"
},
"connectingWithMetaMask": {
"message": "Connettendo con MetaMask..."
},
"connectTo": {
"message": "Collegati a $1",
"description": "$1 is the name/origin of a site/dapp that the user can connect to metamask"

View File

@ -46,15 +46,6 @@
padding-left: 24px;
padding-right: 24px;
&--redirect {
margin-top: 140px;
width: 100%;
display: flex;
align-items: center;
padding-top: 8px;
height: 144px;
}
a, a:hover {
color: $dodger-blue;
}
@ -94,10 +85,6 @@
@extend %content-text;
line-height: 20px;
color: #6A737D;
&--redirect {
text-align: center;
}
}
&__permissions-container {
@ -147,105 +134,3 @@
font-weight: bold;
}
}
.permission-result {
@extend %header--24;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
text-align: center;
color: $Black-100;
&__icons {
display: flex;
}
&__center-icon {
display: flex;
position: relative;
justify-content: center;
align-items: center;
font-size: 12px;
}
h1 {
font-size: 14px;
line-height: 18px;
padding: 8px 0 0;
}
h2 {
font-size: 12px;
line-height: 17px;
color: #6A737D;
padding: 0;
}
&__check {
width: 40px;
height: 40px;
background: white url("/images/permissions-check.svg") no-repeat;
position: absolute;
}
&__reject {
position: absolute;
background: white;
display: flex;
justify-content: center;
align-items: center;
i {
color: #D73A49;
transform: scale(3);
}
}
&__identicon, .icon-with-fallback__identicon {
width: 32px;
height: 32px;
&--default {
background-color: #777A87;
color: white;
width: 64px;
height: 64px;
border-radius: 32px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
}
&__identicon-container, .icon-with-fallback__identicon-container {
height: auto;
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 64px;
width: 64px;
}
&__identicon-border, .icon-with-fallback__identicon-border {
height: 64px;
width: 64px;
border-radius: 50%;
border: 1px solid white;
background: #FFFFFF;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25);
}
&__identicon-border {
display: flex;
justify-content: center;
align-items: center;
}
.icon-with-fallback__identicon-border {
position: absolute;
}
}

View File

@ -1,9 +1,7 @@
import PropTypes from 'prop-types'
import React, { PureComponent } from 'react'
import IconWithFallBack from '../../../ui/icon-with-fallback'
import PermissionsConnectHeader from '../../permissions-connect-header'
import Tooltip from '../../../ui/tooltip-v2'
import classnames from 'classnames'
export default class PermissionPageContainerContent extends PureComponent {
@ -13,13 +11,9 @@ export default class PermissionPageContainerContent extends PureComponent {
onPermissionToggle: PropTypes.func.isRequired,
selectedIdentities: PropTypes.array,
allIdentitiesSelected: PropTypes.bool,
redirect: PropTypes.bool,
permissionRejected: PropTypes.bool,
}
static defaultProps = {
redirect: null,
permissionRejected: null,
selectedIdentities: [],
allIdentitiesSelected: false,
}
@ -28,39 +22,6 @@ export default class PermissionPageContainerContent extends PureComponent {
t: PropTypes.func,
}
renderBrokenLine () {
return (
<svg width="131" height="2" viewBox="0 0 131 2" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 1H134" stroke="#CDD1E4" strokeLinejoin="round" strokeDasharray="8 7" />
</svg>
)
}
renderRedirect () {
const { t } = this.context
const { permissionRejected, domainMetadata } = this.props
return (
<div className="permission-result">
{ permissionRejected ? t('cancelling') : t('connecting') }
<div className="permission-result__icons">
<IconWithFallBack icon={domainMetadata.icon} name={domainMetadata.name} />
<div className="permission-result__center-icon">
{ permissionRejected
? <span className="permission-result__reject" ><i className="fa fa-times-circle" /></span>
: <span className="permission-result__check" />
}
{ this.renderBrokenLine() }
</div>
<div className="permission-result__identicon-container">
<div className="permission-result__identicon-border">
<img src="/images/logo/metamask-fox.svg" />
</div>
</div>
</div>
</div>
)
}
renderRequestedPermissions () {
const {
selectedPermissions, onPermissionToggle,
@ -134,14 +95,10 @@ export default class PermissionPageContainerContent extends PureComponent {
}
getTitle () {
const { domainMetadata, redirect, permissionRejected, selectedIdentities, allIdentitiesSelected } = this.props
const { domainMetadata, selectedIdentities, allIdentitiesSelected } = this.props
const { t } = this.context
if (redirect && permissionRejected) {
return t('cancelledConnectionWithMetaMask')
} else if (redirect) {
return t('connectingWithMetaMask')
} else if (domainMetadata.extensionId) {
if (domainMetadata.extensionId) {
return t('externalExtension', [domainMetadata.extensionId])
} else if (allIdentitiesSelected) {
return t(
@ -166,36 +123,27 @@ export default class PermissionPageContainerContent extends PureComponent {
}
render () {
const { domainMetadata, redirect } = this.props
const { domainMetadata } = this.props
const { t } = this.context
const title = this.getTitle()
return (
<div
className={classnames('permission-approval-container__content', {
'permission-approval-container__content--redirect': redirect,
})}
>
{ !redirect
? (
<div className="permission-approval-container__content-container">
<PermissionsConnectHeader
icon={domainMetadata.icon}
iconName={domainMetadata.origin}
headerTitle={title}
headerText={ domainMetadata.extensionId
? t('allowExternalExtensionTo', [domainMetadata.extensionId])
: t('allowThisSiteTo')
}
/>
<section className="permission-approval-container__permissions-container">
{ this.renderRequestedPermissions() }
</section>
</div>
)
: this.renderRedirect()
}
<div className="permission-approval-container__content">
<div className="permission-approval-container__content-container">
<PermissionsConnectHeader
icon={domainMetadata.icon}
iconName={domainMetadata.origin}
headerTitle={title}
headerText={ domainMetadata.extensionId
? t('allowExternalExtensionTo', [domainMetadata.extensionId])
: t('allowThisSiteTo')
}
/>
<section className="permission-approval-container__permissions-container">
{ this.renderRequestedPermissions() }
</section>
</div>
</div>
)
}

View File

@ -13,15 +13,11 @@ export default class PermissionPageContainer extends Component {
selectedIdentities: PropTypes.array,
allIdentitiesSelected: PropTypes.bool,
request: PropTypes.object,
redirect: PropTypes.bool,
permissionRejected: PropTypes.bool,
requestMetadata: PropTypes.object,
targetDomainMetadata: PropTypes.object.isRequired,
}
static defaultProps = {
redirect: null,
permissionRejected: null,
request: {},
requestMetadata: {},
selectedIdentities: [],
@ -116,8 +112,6 @@ export default class PermissionPageContainer extends Component {
requestMetadata,
targetDomainMetadata,
selectedIdentities,
redirect,
permissionRejected,
allIdentitiesSelected,
} = this.props
@ -129,27 +123,20 @@ export default class PermissionPageContainer extends Component {
selectedPermissions={this.state.selectedPermissions}
onPermissionToggle={this.onPermissionToggle}
selectedIdentities={selectedIdentities}
redirect={redirect}
permissionRejected={permissionRejected}
allIdentitiesSelected={allIdentitiesSelected}
/>
{ !redirect
? (
<div className="permission-approval-container__footers">
<PermissionsConnectFooter />
<PageContainerFooter
cancelButtonType="default"
onCancel={() => this.onCancel()}
cancelText={this.context.t('cancel')}
onSubmit={() => this.onSubmit()}
submitText={this.context.t('connect')}
submitButtonType="confirm"
buttonSizeLarge={false}
/>
</div>
)
: null
}
<div className="permission-approval-container__footers">
<PermissionsConnectFooter />
<PageContainerFooter
cancelButtonType="default"
onCancel={() => this.onCancel()}
cancelText={this.context.t('cancel')}
onSubmit={() => this.onSubmit()}
submitText={this.context.t('connect')}
submitButtonType="confirm"
buttonSizeLarge={false}
/>
</div>
</div>
)
}

View File

@ -5,13 +5,14 @@ import IconWithFallBack from '../../ui/icon-with-fallback'
export default class PermissionsConnectHeader extends Component {
static propTypes = {
icon: PropTypes.string,
iconName: PropTypes.string.isRequired,
iconName: PropTypes.string,
headerTitle: PropTypes.node,
headerText: PropTypes.string,
}
static defaultProps = {
icon: null,
iconName: '',
headerTitle: '',
headerText: '',
}

View File

@ -198,23 +198,23 @@ export default class ChooseAccount extends Component {
: t('connectAccountOrCreate')
}
/>
{ this.renderAccountsListHeader() }
{ this.renderAccountsList() }
{this.renderAccountsListHeader()}
{this.renderAccountsList()}
<div className="permissions-connect-choose-account__footer-container">
<PermissionsConnectFooter />
<div className="permissions-connect-choose-account__bottom-buttons">
<Button
onClick={ () => cancelPermissionsRequest(permissionsRequestId) }
onClick={() => cancelPermissionsRequest(permissionsRequestId)}
type="default"
>
{ t('cancel') }
{t('cancel')}
</Button>
<Button
onClick={ () => selectAccounts(selectedAccounts) }
onClick={() => selectAccounts(selectedAccounts)}
type="primary"
disabled={ selectedAccounts.size === 0 }
disabled={selectedAccounts.size === 0}
>
{ t('next') }
{t('next')}
</Button>
</div>
</div>

View File

@ -1,4 +1,5 @@
@import 'choose-account/index';
@import 'redirect/index';
.permissions-connect {
width: 100%;

View File

@ -1,16 +1,14 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import { Switch, Route } from 'react-router-dom'
import ChooseAccount from './choose-account'
import { getEnvironmentType } from '../../../../app/scripts/lib/util'
import {
ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_NOTIFICATION,
} from '../../../../app/scripts/lib/enums'
import {
DEFAULT_ROUTE,
} from '../../helpers/constants/routes'
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../app/scripts/lib/enums'
import { DEFAULT_ROUTE } from '../../helpers/constants/routes'
import PermissionPageContainer from '../../components/app/permission-page-container'
import ChooseAccount from './choose-account'
import PermissionsRedirect from './redirect'
const APPROVE_TIMEOUT = 1200
export default class PermissionConnect extends Component {
static propTypes = {
@ -27,14 +25,12 @@ export default class PermissionConnect extends Component {
addressLastConnectedMap: PropTypes.object.isRequired,
lastConnectedInfo: PropTypes.object.isRequired,
permissionsRequestId: PropTypes.string,
hasPendingPermissionsRequests: PropTypes.bool.isRequired,
history: PropTypes.object.isRequired,
connectPath: PropTypes.string.isRequired,
confirmPermissionPath: PropTypes.string.isRequired,
page: PropTypes.string.isRequired,
targetDomainMetadata: PropTypes.object,
location: PropTypes.shape({
pathname: PropTypes.string,
}).isRequired,
}
static defaultProps = {
@ -53,74 +49,27 @@ export default class PermissionConnect extends Component {
selectedAccountAddresses: this.props.accounts.length === 1
? new Set([this.props.accounts[0].address])
: new Set(),
permissionAccepted: null,
permissionsApproved: null,
origin: this.props.origin,
targetDomainMetadata: this.props.targetDomainMetadata || {},
}
beforeUnload = () => {
const { permissionsRequestId, rejectPermissionsRequest } = this.props
const { permissionAccepted } = this.state
const { permissionsApproved } = this.state
if (permissionAccepted === null && permissionsRequestId) {
if (permissionsApproved === null && permissionsRequestId) {
rejectPermissionsRequest(permissionsRequestId)
}
}
removeBeforeUnload = () => {
const environmentType = getEnvironmentType()
if (
environmentType === ENVIRONMENT_TYPE_FULLSCREEN ||
environmentType === ENVIRONMENT_TYPE_NOTIFICATION
) {
if (environmentType === ENVIRONMENT_TYPE_NOTIFICATION) {
window.removeEventListener('beforeunload', this.beforeUnload)
}
}
componentDidUpdate (prevProps) {
const { permissionsRequest, lastConnectedInfo } = this.props
const { redirecting, origin } = this.state
if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) {
const accountsLastApprovedTime = lastConnectedInfo[origin]?.lastApproved || 0
const initialAccountsLastApprovedTime = prevProps.lastConnectedInfo[origin]?.lastApproved || 0
if (accountsLastApprovedTime > initialAccountsLastApprovedTime) {
this.redirectFlow(true)
} else {
this.redirectFlow(false)
}
}
}
selectAccounts = (addresses) => {
this.setState({
selectedAccountAddresses: addresses,
}, () => this.props.history.push(this.props.confirmPermissionPath))
}
redirectFlow (accepted) {
const { history, location, confirmPermissionPath } = this.props
this.setState({
redirecting: true,
permissionAccepted: accepted,
})
this.removeBeforeUnload()
if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) {
setTimeout(async () => {
global.platform.closeCurrentWindow()
}, 1500)
} else if (location.pathname === confirmPermissionPath) {
setTimeout(async () => {
history.push(DEFAULT_ROUTE)
}, 1500)
} else {
history.push(DEFAULT_ROUTE)
}
}
componentDidMount () {
const {
getCurrentWindowTab,
@ -136,26 +85,78 @@ export default class PermissionConnect extends Component {
}
const environmentType = getEnvironmentType()
if (
environmentType === ENVIRONMENT_TYPE_FULLSCREEN ||
environmentType === ENVIRONMENT_TYPE_NOTIFICATION
) {
if (environmentType === ENVIRONMENT_TYPE_NOTIFICATION) {
window.addEventListener('beforeunload', this.beforeUnload)
}
}
static getDerivedStateFromProps (props, state) {
const { permissionsRequest, targetDomainMetadata } = props
const { targetDomainMetadata: savedMetadata } = state
if (
permissionsRequest &&
savedMetadata.name !== targetDomainMetadata?.name
) {
return { targetDomainMetadata }
}
return null
}
componentDidUpdate (prevProps) {
const { permissionsRequest, lastConnectedInfo } = this.props
const { redirecting, origin } = this.state
if (!permissionsRequest && prevProps.permissionsRequest && !redirecting) {
const accountsLastApprovedTime = lastConnectedInfo[origin]?.lastApproved || 0
const initialAccountsLastApprovedTime = prevProps.lastConnectedInfo[origin]?.lastApproved || 0
const approved = accountsLastApprovedTime > initialAccountsLastApprovedTime
this.redirect(approved)
}
}
selectAccounts = (addresses) => {
this.setState({
selectedAccountAddresses: addresses,
}, () => this.props.history.push(this.props.confirmPermissionPath))
}
redirect (approved) {
this.setState({
redirecting: true,
permissionsApproved: approved,
})
this.removeBeforeUnload()
if (approved) {
setTimeout(this._doRedirect.bind(this), APPROVE_TIMEOUT)
} else {
this._doRedirect()
}
}
_doRedirect () {
const { history, hasPendingPermissionsRequests } = this.props
if (
!hasPendingPermissionsRequests &&
getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION
) {
global.platform.closeCurrentWindow()
} else {
history.push(DEFAULT_ROUTE)
}
}
cancelPermissionsRequest = async (requestId) => {
const { history, rejectPermissionsRequest } = this.props
const { rejectPermissionsRequest } = this.props
if (requestId) {
await rejectPermissionsRequest(requestId)
if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) {
window.close()
} else {
history.push(DEFAULT_ROUTE)
}
this.redirect(false)
}
}
@ -193,7 +194,6 @@ export default class PermissionConnect extends Component {
render () {
const {
approvePermissionsRequest,
rejectPermissionsRequest,
accounts,
showNewAccountModal,
newAccountNumber,
@ -203,63 +203,68 @@ export default class PermissionConnect extends Component {
permissionsRequestId,
connectPath,
confirmPermissionPath,
targetDomainMetadata,
} = this.props
const {
selectedAccountAddresses,
permissionAccepted,
permissionsApproved,
origin,
redirecting,
targetDomainMetadata,
} = this.state
return (
<div className="permissions-connect">
{ this.renderTopBar() }
<Switch>
<Route
path={connectPath}
exact
render={() => (
<ChooseAccount
accounts={accounts}
nativeCurrency={nativeCurrency}
selectAccounts={(addresses) => this.selectAccounts(addresses)}
selectNewAccountViaModal={(handleAccountClick) => {
showNewAccountModal({
onCreateNewAccount: (address) => handleAccountClick(address),
newAccountNumber,
})
}}
addressLastConnectedMap={addressLastConnectedMap}
cancelPermissionsRequest={(requestId) => this.cancelPermissionsRequest(requestId)}
permissionsRequestId={permissionsRequestId}
selectedAccountAddresses={selectedAccountAddresses}
targetDomainMetadata={targetDomainMetadata}
{
redirecting && permissionsApproved
? (
<PermissionsRedirect
domainMetadata={targetDomainMetadata}
/>
)}
/>
<Route
path={confirmPermissionPath}
exact
render={() => (
<PermissionPageContainer
request={permissionsRequest || {}}
approvePermissionsRequest={(request, accounts) => {
approvePermissionsRequest(request, accounts)
this.redirectFlow(true)
}}
rejectPermissionsRequest={(requestId) => {
rejectPermissionsRequest(requestId)
this.redirectFlow(false)
}}
selectedIdentities={accounts.filter((account) => selectedAccountAddresses.has(account.address))}
redirect={redirecting}
permissionRejected={ permissionAccepted === false }
cachedOrigin={origin}
/>
)}
/>
</Switch>
)
: (
<Switch>
<Route
path={connectPath}
exact
render={() => (
<ChooseAccount
accounts={accounts}
nativeCurrency={nativeCurrency}
selectAccounts={(addresses) => this.selectAccounts(addresses)}
selectNewAccountViaModal={(handleAccountClick) => {
showNewAccountModal({
onCreateNewAccount: (address) => handleAccountClick(address),
newAccountNumber,
})
}}
addressLastConnectedMap={addressLastConnectedMap}
cancelPermissionsRequest={(requestId) => this.cancelPermissionsRequest(requestId)}
permissionsRequestId={permissionsRequestId}
selectedAccountAddresses={selectedAccountAddresses}
targetDomainMetadata={targetDomainMetadata}
/>
)}
/>
<Route
path={confirmPermissionPath}
exact
render={() => (
<PermissionPageContainer
request={permissionsRequest || {}}
approvePermissionsRequest={(request, accounts) => {
approvePermissionsRequest(request, accounts)
this.redirect(true)
}}
rejectPermissionsRequest={(requestId) => this.cancelPermissionsRequest(requestId)}
selectedIdentities={accounts.filter((account) => selectedAccountAddresses.has(account.address))}
cachedOrigin={origin}
/>
)}
/>
</Switch>
)
}
</div>
)
}

View File

@ -32,6 +32,10 @@ const mapStateToProps = (state, ownProps) => {
const permissionsRequest = permissionsRequests
.find((permissionsRequest) => permissionsRequest.metadata.id === permissionsRequestId)
const hasPendingPermissionsRequests = permissionsRequest
? permissionsRequests.length > 1
: permissionsRequests.length > 0
const { metadata = {} } = permissionsRequest || {}
const { origin } = metadata
const nativeCurrency = getNativeCurrency(state)
@ -62,6 +66,7 @@ const mapStateToProps = (state, ownProps) => {
return {
permissionsRequest,
permissionsRequestId,
hasPendingPermissionsRequests,
accounts: accountsWithLabels,
origin,
newAccountNumber: accountsWithLabels.length + 1,

View File

@ -0,0 +1 @@
export { default } from './permissions-redirect.component'

View File

@ -0,0 +1,82 @@
.permissions-redirect {
display: flex;
height: 100%;
justify-content: center;
&__result {
@extend %header--24;
position: absolute;
top: 30%;
flex-direction: column;
justify-content: space-between;
align-items: center;
text-align: center;
color: $Black-100;
}
&__icons {
display: flex;
}
&__center-icon {
display: flex;
position: relative;
justify-content: center;
align-items: center;
font-size: 12px;
}
&__check {
width: 40px;
height: 40px;
background: white url("/images/permissions-check.svg") no-repeat;
position: absolute;
}
&__identicon, .icon-with-fallback__identicon {
width: 32px;
height: 32px;
&--default {
background-color: #777A87;
color: white;
width: 64px;
height: 64px;
border-radius: 32px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
}
&__identicon-container, .icon-with-fallback__identicon-container {
height: auto;
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 64px;
width: 64px;
}
&__identicon-border, .icon-with-fallback__identicon-border {
height: 64px;
width: 64px;
border-radius: 50%;
border: 1px solid white;
background: #FFFFFF;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25);
}
&__identicon-border {
display: flex;
justify-content: center;
align-items: center;
}
.icon-with-fallback__identicon-border {
position: absolute;
}
}

View File

@ -0,0 +1,41 @@
import React, { useContext } from 'react'
import PropTypes from 'prop-types'
import IconWithFallBack from '../../../components/ui/icon-with-fallback'
import { I18nContext } from '../../../contexts/i18n'
export default function PermissionsRedirect ({ domainMetadata }) {
const t = useContext(I18nContext)
return (
<div className="permissions-redirect">
<div className="permissions-redirect__result">
{ t('connecting') }
<div className="permissions-redirect__icons">
<IconWithFallBack icon={domainMetadata.icon} name={domainMetadata.name} />
<div className="permissions-redirect__center-icon">
<span className="permissions-redirect__check" />
{ renderBrokenLine() }
</div>
<div className="permissions-redirect__identicon-container">
<div className="permissions-redirect__identicon-border">
<img src="/images/logo/metamask-fox.svg" />
</div>
</div>
</div>
</div>
</div>
)
function renderBrokenLine () {
return (
<svg width="131" height="2" viewBox="0 0 131 2" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 1H134" stroke="#CDD1E4" strokeLinejoin="round" strokeDasharray="8 7" />
</svg>
)
}
}
PermissionsRedirect.propTypes = {
domainMetadata: PropTypes.object.isRequired,
}

View File

@ -173,17 +173,15 @@ export default class Routes extends Component {
return true
}
if (windowType === ENVIRONMENT_TYPE_POPUP) {
return this.onConfirmPage() || hasPermissionsRequests
if (windowType === ENVIRONMENT_TYPE_POPUP && this.onConfirmPage()) {
return true
}
const isHandlingPermissionsRequest = Boolean(matchPath(location.pathname, {
path: CONNECT_ROUTE, exact: false,
}))
})) || hasPermissionsRequests
if (hasPermissionsRequests || isHandlingPermissionsRequest) {
return true
}
return isHandlingPermissionsRequest
}
render () {

View File

@ -2056,9 +2056,11 @@ export function rejectPermissionsRequest (requestId) {
background.rejectPermissionsRequest(requestId, (err) => {
if (err) {
dispatch(displayWarning(err.message))
reject()
return reject(err)
}
resolve()
return forceUpdateMetamaskState(dispatch)
.then(resolve)
.catch(reject)
})
})
}