mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Consolidate connected account alerts (#8802)
* update connected accounts appearance * consolidate account alerts * UnconnectedAccountAlert: use ConnectedAccountsList * move switch account action out of menu in all views Co-authored-by: Mark Stacey <markjstacey@gmail.com>
This commit is contained in:
parent
3f8fa161ca
commit
4dfe4e7463
@ -28,11 +28,8 @@
|
|||||||
"connectedAccountsEmptyDescription": {
|
"connectedAccountsEmptyDescription": {
|
||||||
"message": "MetaMask is not connected this site. To connect to a Web3 site, find the connect button on their site."
|
"message": "MetaMask is not connected this site. To connect to a Web3 site, find the connect button on their site."
|
||||||
},
|
},
|
||||||
"primary": {
|
"currentAccountNotConnected": {
|
||||||
"message": "Primary"
|
"message": "Your current account is not connected"
|
||||||
},
|
|
||||||
"lastActive": {
|
|
||||||
"message": "Last active"
|
|
||||||
},
|
},
|
||||||
"switchToThisAccount": {
|
"switchToThisAccount": {
|
||||||
"message": "Switch to this account"
|
"message": "Switch to this account"
|
||||||
@ -139,6 +136,9 @@
|
|||||||
"accountSelectionRequired": {
|
"accountSelectionRequired": {
|
||||||
"message": "You need to select an account!"
|
"message": "You need to select an account!"
|
||||||
},
|
},
|
||||||
|
"active": {
|
||||||
|
"message": "Active"
|
||||||
|
},
|
||||||
"activity": {
|
"activity": {
|
||||||
"message": "Activity"
|
"message": "Activity"
|
||||||
},
|
},
|
||||||
@ -187,17 +187,11 @@
|
|||||||
"alertsSettingsDescription": {
|
"alertsSettingsDescription": {
|
||||||
"message": "Enable or disable each alert"
|
"message": "Enable or disable each alert"
|
||||||
},
|
},
|
||||||
"alertSettingsSwitchToConnected": {
|
|
||||||
"message": "Opening popup with an unconnected account selected"
|
|
||||||
},
|
|
||||||
"alertSettingsSwitchToConnectedDescription": {
|
|
||||||
"message": "This alert is shown when you open the popup with an unconnected account selected."
|
|
||||||
},
|
|
||||||
"alertSettingsUnconnectedAccount": {
|
"alertSettingsUnconnectedAccount": {
|
||||||
"message": "Switching to an unconnected account"
|
"message": "Browsing a website with an unconnected account selected"
|
||||||
},
|
},
|
||||||
"alertSettingsUnconnectedAccountDescription": {
|
"alertSettingsUnconnectedAccountDescription": {
|
||||||
"message": "This alert is shown in the popup when you switch from a connected account to an unconnected account."
|
"message": "This alert is shown in the popup when you are browsing a connected Web3 site, but the currently selected account is not connected."
|
||||||
},
|
},
|
||||||
"allowOriginSpendToken": {
|
"allowOriginSpendToken": {
|
||||||
"message": "Allow $1 to spend your $2?",
|
"message": "Allow $1 to spend your $2?",
|
||||||
@ -991,9 +985,6 @@
|
|||||||
"noAlreadyHaveSeed": {
|
"noAlreadyHaveSeed": {
|
||||||
"message": "No, I already have a seed phrase"
|
"message": "No, I already have a seed phrase"
|
||||||
},
|
},
|
||||||
"notConnected": {
|
|
||||||
"message": "Not connected"
|
|
||||||
},
|
|
||||||
"protectYourKeys": {
|
"protectYourKeys": {
|
||||||
"message": "Protect Your Keys!"
|
"message": "Protect Your Keys!"
|
||||||
},
|
},
|
||||||
@ -1478,16 +1469,6 @@
|
|||||||
"supportCenter": {
|
"supportCenter": {
|
||||||
"message": "Visit our Support Center"
|
"message": "Visit our Support Center"
|
||||||
},
|
},
|
||||||
"switchAccounts": {
|
|
||||||
"message": "Switch accounts"
|
|
||||||
},
|
|
||||||
"switchToConnectedAlertMultipleAccountsDescription": {
|
|
||||||
"message": "This account is not connected. Switch to a connected account?"
|
|
||||||
},
|
|
||||||
"switchToConnectedAlertSingleAccountDescription": {
|
|
||||||
"message": "This account is not connected. Switch to a connected account ($1)?",
|
|
||||||
"description": "$1 will be replaced by the name of the connected account"
|
|
||||||
},
|
|
||||||
"symbol": {
|
"symbol": {
|
||||||
"message": "Symbol"
|
"message": "Symbol"
|
||||||
},
|
},
|
||||||
@ -1635,10 +1616,7 @@
|
|||||||
"unapproved": {
|
"unapproved": {
|
||||||
"message": "Unapproved"
|
"message": "Unapproved"
|
||||||
},
|
},
|
||||||
"unconnectedAccountAlertDescription": {
|
"alertDisableTooltip": {
|
||||||
"message": "$1 is not connected to $2."
|
|
||||||
},
|
|
||||||
"unconnectedAccountAlertDisableTooltip": {
|
|
||||||
"message": "This can be changed in \"Settings > Alerts\""
|
"message": "This can be changed in \"Settings > Alerts\""
|
||||||
},
|
},
|
||||||
"units": {
|
"units": {
|
||||||
@ -1776,11 +1754,5 @@
|
|||||||
"encryptionPublicKeyNotice": {
|
"encryptionPublicKeyNotice": {
|
||||||
"message": "$1 would like your public encryption key. By consenting, this site will be able to compose encrypted messages to you.",
|
"message": "$1 would like your public encryption key. By consenting, this site will be able to compose encrypted messages to you.",
|
||||||
"description": "$1 is website or dapp name"
|
"description": "$1 is website or dapp name"
|
||||||
},
|
|
||||||
"thisSite": {
|
|
||||||
"message": "this site"
|
|
||||||
},
|
|
||||||
"thisAccount": {
|
|
||||||
"message": "This account"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import ObservableStore from 'obs-store'
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const ALERT_TYPES = {
|
export const ALERT_TYPES = {
|
||||||
switchToConnected: 'switchToConnected',
|
|
||||||
unconnectedAccount: 'unconnectedAccount',
|
unconnectedAccount: 'unconnectedAccount',
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +24,7 @@ const defaultState = {
|
|||||||
},
|
},
|
||||||
{}
|
{}
|
||||||
),
|
),
|
||||||
switchToConnectedAlertShown: {},
|
unconnectedAccountAlertShownOrigins: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +43,7 @@ export default class AlertController {
|
|||||||
defaultState,
|
defaultState,
|
||||||
initState,
|
initState,
|
||||||
{
|
{
|
||||||
switchToConnectedAlertShown: {},
|
unconnectedAccountAlertShownOrigins: {},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
this.store = new ObservableStore(state)
|
this.store = new ObservableStore(state)
|
||||||
@ -54,9 +53,9 @@ export default class AlertController {
|
|||||||
|
|
||||||
preferencesStore.subscribe(({ selectedAddress }) => {
|
preferencesStore.subscribe(({ selectedAddress }) => {
|
||||||
const currentState = this.store.getState()
|
const currentState = this.store.getState()
|
||||||
if (currentState.switchToConnectedAlertShown && this.selectedAddress !== selectedAddress) {
|
if (currentState.unconnectedAccountAlertShownOrigins && this.selectedAddress !== selectedAddress) {
|
||||||
this.selectedAddress = selectedAddress
|
this.selectedAddress = selectedAddress
|
||||||
this.store.updateState({ switchToConnectedAlertShown: {} })
|
this.store.updateState({ unconnectedAccountAlertShownOrigins: {} })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -72,10 +71,10 @@ export default class AlertController {
|
|||||||
* Sets the "switch to connected" alert as shown for the given origin
|
* Sets the "switch to connected" alert as shown for the given origin
|
||||||
* @param {string} origin - The origin the alert has been shown for
|
* @param {string} origin - The origin the alert has been shown for
|
||||||
*/
|
*/
|
||||||
setSwitchToConnectedAlertShown (origin) {
|
setUnconnectedAccountAlertShown (origin) {
|
||||||
let { switchToConnectedAlertShown } = this.store.getState()
|
let { unconnectedAccountAlertShownOrigins } = this.store.getState()
|
||||||
switchToConnectedAlertShown = { ...switchToConnectedAlertShown }
|
unconnectedAccountAlertShownOrigins = { ...unconnectedAccountAlertShownOrigins }
|
||||||
switchToConnectedAlertShown[origin] = true
|
unconnectedAccountAlertShownOrigins[origin] = true
|
||||||
this.store.updateState({ switchToConnectedAlertShown })
|
this.store.updateState({ unconnectedAccountAlertShownOrigins })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,7 +545,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
|
|
||||||
// alert controller
|
// alert controller
|
||||||
setAlertEnabledness: nodeify(alertController.setAlertEnabledness, alertController),
|
setAlertEnabledness: nodeify(alertController.setAlertEnabledness, alertController),
|
||||||
setSwitchToConnectedAlertShown: nodeify(this.alertController.setSwitchToConnectedAlertShown, this.alertController),
|
setUnconnectedAccountAlertShown: nodeify(this.alertController.setUnconnectedAccountAlertShown, this.alertController),
|
||||||
|
|
||||||
// 3Box
|
// 3Box
|
||||||
setThreeBoxSyncingPermission: nodeify(threeBoxController.setThreeBoxSyncingPermission, threeBoxController),
|
setThreeBoxSyncingPermission: nodeify(threeBoxController.setThreeBoxSyncingPermission, threeBoxController),
|
||||||
|
@ -522,9 +522,6 @@
|
|||||||
"priceAndTimeEstimatesLastRetrieved": 1541527901281,
|
"priceAndTimeEstimatesLastRetrieved": 1541527901281,
|
||||||
"errors": {}
|
"errors": {}
|
||||||
},
|
},
|
||||||
"switchToConnected": {
|
|
||||||
"state": "CLOSED"
|
|
||||||
},
|
|
||||||
"unconnectedAccount": {
|
"unconnectedAccount": {
|
||||||
"state": "CLOSED"
|
"state": "CLOSED"
|
||||||
},
|
},
|
||||||
|
@ -473,9 +473,6 @@
|
|||||||
"priceAndTimeEstimatesLastRetrieved": 1541527901281,
|
"priceAndTimeEstimatesLastRetrieved": 1541527901281,
|
||||||
"errors": {}
|
"errors": {}
|
||||||
},
|
},
|
||||||
"switchToConnected": {
|
|
||||||
"state": "CLOSED"
|
|
||||||
},
|
|
||||||
"unconnectedAccount": {
|
"unconnectedAccount": {
|
||||||
"state": "CLOSED"
|
"state": "CLOSED"
|
||||||
},
|
},
|
||||||
|
@ -1295,9 +1295,6 @@
|
|||||||
"errors": {}
|
"errors": {}
|
||||||
},
|
},
|
||||||
"confirmTransaction": {},
|
"confirmTransaction": {},
|
||||||
"switchToConnected": {
|
|
||||||
"state": "CLOSED"
|
|
||||||
},
|
|
||||||
"unconnectedAccount": {
|
"unconnectedAccount": {
|
||||||
"state": "CLOSED"
|
"state": "CLOSED"
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,15 @@ import React from 'react'
|
|||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
import UnconnectedAccountAlert from './unconnected-account-alert'
|
import UnconnectedAccountAlert from './unconnected-account-alert'
|
||||||
import SwitchToConnectedAlert from './switch-to-connected-alert'
|
|
||||||
import { alertIsOpen as unconnectedAccountAlertIsOpen } from '../../../ducks/alerts/unconnected-account'
|
import { alertIsOpen as unconnectedAccountAlertIsOpen } from '../../../ducks/alerts/unconnected-account'
|
||||||
import { alertIsOpen as switchToConnectedAlertIsOpen } from '../../../ducks/alerts/switch-to-connected'
|
|
||||||
|
|
||||||
const Alerts = () => {
|
const Alerts = () => {
|
||||||
const _unconnectedAccountAlertIsOpen = useSelector(unconnectedAccountAlertIsOpen)
|
const _unconnectedAccountAlertIsOpen = useSelector(unconnectedAccountAlertIsOpen)
|
||||||
const _switchToConnectedAlertIsOpen = useSelector(switchToConnectedAlertIsOpen)
|
|
||||||
|
|
||||||
if (_unconnectedAccountAlertIsOpen) {
|
if (_unconnectedAccountAlertIsOpen) {
|
||||||
return (
|
return (
|
||||||
<UnconnectedAccountAlert />
|
<UnconnectedAccountAlert />
|
||||||
)
|
)
|
||||||
} else if (_switchToConnectedAlertIsOpen) {
|
|
||||||
return (
|
|
||||||
<SwitchToConnectedAlert />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
@ -1,3 +1 @@
|
|||||||
@import './unconnected-account-alert/unconnected-account-alert';
|
@import './unconnected-account-alert/unconnected-account-alert';
|
||||||
|
|
||||||
@import './switch-to-connected-alert/switch-to-connected-alert';
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export { default } from './switch-to-connected-alert'
|
|
@ -1,121 +0,0 @@
|
|||||||
import React, { useState } from 'react'
|
|
||||||
import { useDispatch, useSelector } from 'react-redux'
|
|
||||||
|
|
||||||
import {
|
|
||||||
ALERT_STATE,
|
|
||||||
switchToAccount,
|
|
||||||
dismissAlert,
|
|
||||||
dismissAndDisableAlert,
|
|
||||||
getAlertState,
|
|
||||||
} from '../../../../ducks/alerts/switch-to-connected'
|
|
||||||
import { getPermittedIdentitiesForCurrentTab } from '../../../../selectors'
|
|
||||||
import Popover from '../../../ui/popover'
|
|
||||||
import Button from '../../../ui/button'
|
|
||||||
import Dropdown from '../../../ui/dropdown'
|
|
||||||
import Checkbox from '../../../ui/check-box'
|
|
||||||
import Tooltip from '../../../ui/tooltip-v2'
|
|
||||||
import { useI18nContext } from '../../../../hooks/useI18nContext'
|
|
||||||
|
|
||||||
const {
|
|
||||||
ERROR,
|
|
||||||
LOADING,
|
|
||||||
} = ALERT_STATE
|
|
||||||
|
|
||||||
const SwitchToUnconnectedAccountAlert = () => {
|
|
||||||
const t = useI18nContext()
|
|
||||||
const dispatch = useDispatch()
|
|
||||||
const alertState = useSelector(getAlertState)
|
|
||||||
const connectedAccounts = useSelector(getPermittedIdentitiesForCurrentTab)
|
|
||||||
const [accountToSwitchTo, setAccountToSwitchTo] = useState(connectedAccounts[0].address)
|
|
||||||
const [dontShowThisAgain, setDontShowThisAgain] = useState(false)
|
|
||||||
|
|
||||||
const onClose = async () => {
|
|
||||||
return dontShowThisAgain
|
|
||||||
? await dispatch(dismissAndDisableAlert())
|
|
||||||
: dispatch(dismissAlert())
|
|
||||||
}
|
|
||||||
|
|
||||||
const options = connectedAccounts.map((account) => {
|
|
||||||
return { name: account.name, value: account.address }
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Popover
|
|
||||||
contentClassName="switch-to-connected-alert__content"
|
|
||||||
footer={(
|
|
||||||
<>
|
|
||||||
{
|
|
||||||
alertState === ERROR
|
|
||||||
? (
|
|
||||||
<div className="switch-to-connected-alert__error">
|
|
||||||
{ t('failureMessage') }
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
<div className="switch-to-connected-alert__footer-buttons">
|
|
||||||
<Button
|
|
||||||
disabled={alertState === LOADING}
|
|
||||||
onClick={onClose}
|
|
||||||
type="secondary"
|
|
||||||
>
|
|
||||||
{ t('dismiss') }
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
disabled={alertState === LOADING || alertState === ERROR || dontShowThisAgain}
|
|
||||||
onClick={() => dispatch(switchToAccount(accountToSwitchTo))}
|
|
||||||
type="primary"
|
|
||||||
>
|
|
||||||
{ t('switchAccounts') }
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
footerClassName="switch-to-connected-alert__footer"
|
|
||||||
onClose={onClose}
|
|
||||||
subtitle={
|
|
||||||
connectedAccounts.length > 1
|
|
||||||
? t('switchToConnectedAlertMultipleAccountsDescription')
|
|
||||||
: t('switchToConnectedAlertSingleAccountDescription', [connectedAccounts[0].name])
|
|
||||||
}
|
|
||||||
title={t('notConnected')}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
connectedAccounts.length > 1
|
|
||||||
? (
|
|
||||||
<Dropdown
|
|
||||||
className="switch-to-connected-alert__dropdown"
|
|
||||||
title="Switch to account"
|
|
||||||
onChange={(address) => setAccountToSwitchTo(address)}
|
|
||||||
options={options}
|
|
||||||
selectedOption={accountToSwitchTo}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
<div className="switch-to-connected-alert__checkbox-wrapper">
|
|
||||||
<Checkbox
|
|
||||||
id="switchToConnected_dontShowThisAgain"
|
|
||||||
checked={dontShowThisAgain}
|
|
||||||
className="switch-to-connected-alert__checkbox"
|
|
||||||
onClick={() => setDontShowThisAgain((checked) => !checked)}
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
className="switch-to-connected-alert__checkbox-label"
|
|
||||||
htmlFor="switchToConnected_dontShowThisAgain"
|
|
||||||
>
|
|
||||||
{ t('dontShowThisAgain') }
|
|
||||||
<Tooltip
|
|
||||||
position="top"
|
|
||||||
title={t('unconnectedAccountAlertDisableTooltip')}
|
|
||||||
wrapperClassName="switch-to-connected-alert__checkbox-label-tooltip"
|
|
||||||
>
|
|
||||||
<i className="fa fa-info-circle" />
|
|
||||||
</Tooltip>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SwitchToUnconnectedAccountAlert
|
|
@ -1,66 +0,0 @@
|
|||||||
.switch-to-connected-alert {
|
|
||||||
&__footer {
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
:only-child {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__footer-buttons {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
|
|
||||||
button:first-child {
|
|
||||||
margin-right: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__error {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
padding: 16px;
|
|
||||||
font-size: 14px;
|
|
||||||
border: 1px solid #D73A49;
|
|
||||||
background: #F8EAE8;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__content {
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 24px 24px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__dropdown {
|
|
||||||
background-color: white;
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__checkbox-wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__checkbox {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__checkbox-label {
|
|
||||||
font-size: 14px;
|
|
||||||
margin-top: auto;
|
|
||||||
margin-bottom: auto;
|
|
||||||
color: $Grey-500;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__checkbox-label-tooltip {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,12 +7,20 @@ import {
|
|||||||
dismissAlert,
|
dismissAlert,
|
||||||
dismissAndDisableAlert,
|
dismissAndDisableAlert,
|
||||||
getAlertState,
|
getAlertState,
|
||||||
|
switchToAccount,
|
||||||
} from '../../../../ducks/alerts/unconnected-account'
|
} from '../../../../ducks/alerts/unconnected-account'
|
||||||
|
import {
|
||||||
|
getOriginOfCurrentTab,
|
||||||
|
getPermittedIdentitiesForCurrentTab,
|
||||||
|
getSelectedAddress,
|
||||||
|
getSelectedIdentity,
|
||||||
|
} from '../../../../selectors'
|
||||||
|
import { isExtensionUrl } from '../../../../helpers/utils/util'
|
||||||
import Popover from '../../../ui/popover'
|
import Popover from '../../../ui/popover'
|
||||||
import Button from '../../../ui/button'
|
import Button from '../../../ui/button'
|
||||||
import Checkbox from '../../../ui/check-box'
|
import Checkbox from '../../../ui/check-box'
|
||||||
import Tooltip from '../../../ui/tooltip-v2'
|
import Tooltip from '../../../ui/tooltip-v2'
|
||||||
import { getSelectedIdentity, getOriginOfCurrentTab } from '../../../../selectors'
|
import ConnectedAccountsList from '../../connected-accounts-list'
|
||||||
import { useI18nContext } from '../../../../hooks/useI18nContext'
|
import { useI18nContext } from '../../../../hooks/useI18nContext'
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -20,12 +28,14 @@ const {
|
|||||||
LOADING,
|
LOADING,
|
||||||
} = ALERT_STATE
|
} = ALERT_STATE
|
||||||
|
|
||||||
const SwitchToUnconnectedAccountAlert = () => {
|
const UnconnectedAccountAlert = () => {
|
||||||
const t = useI18nContext()
|
const t = useI18nContext()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const alertState = useSelector(getAlertState)
|
const alertState = useSelector(getAlertState)
|
||||||
|
const connectedAccounts = useSelector(getPermittedIdentitiesForCurrentTab)
|
||||||
const origin = useSelector(getOriginOfCurrentTab)
|
const origin = useSelector(getOriginOfCurrentTab)
|
||||||
const selectedIdentity = useSelector(getSelectedIdentity)
|
const selectedIdentity = useSelector(getSelectedIdentity)
|
||||||
|
const selectedAddress = useSelector(getSelectedAddress)
|
||||||
const [dontShowThisAgain, setDontShowThisAgain] = useState(false)
|
const [dontShowThisAgain, setDontShowThisAgain] = useState(false)
|
||||||
|
|
||||||
const onClose = async () => {
|
const onClose = async () => {
|
||||||
@ -34,16 +44,7 @@ const SwitchToUnconnectedAccountAlert = () => {
|
|||||||
: dispatch(dismissAlert())
|
: dispatch(dismissAlert())
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountName = selectedIdentity?.name || t('thisAccount')
|
const footer = (
|
||||||
const siteName = origin || t('thisSite')
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Popover
|
|
||||||
contentClassName="unconnected-account-alert__content"
|
|
||||||
title={t('notConnected')}
|
|
||||||
subtitle={t('unconnectedAccountAlertDescription', [ accountName, siteName ])}
|
|
||||||
onClose={onClose}
|
|
||||||
footer={(
|
|
||||||
<>
|
<>
|
||||||
{
|
{
|
||||||
alertState === ERROR
|
alertState === ERROR
|
||||||
@ -54,26 +55,8 @@ const SwitchToUnconnectedAccountAlert = () => {
|
|||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
<div className="unconnected-account-alert__footer-buttons">
|
<div className="unconnected-account-alert__footer-row">
|
||||||
<Button
|
<div className="unconnected-account-alert__checkbox-wrapper">
|
||||||
disabled={alertState === LOADING}
|
|
||||||
onClick={onClose}
|
|
||||||
type="secondary"
|
|
||||||
>
|
|
||||||
{ t('dismiss') }
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
disabled={alertState === LOADING || alertState === ERROR || dontShowThisAgain }
|
|
||||||
onClick={() => dispatch(connectAccount())}
|
|
||||||
type="primary"
|
|
||||||
>
|
|
||||||
{ t('connect') }
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
footerClassName="unconnected-account-alert__footer"
|
|
||||||
>
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id="unconnectedAccount_dontShowThisAgain"
|
id="unconnectedAccount_dontShowThisAgain"
|
||||||
checked={dontShowThisAgain}
|
checked={dontShowThisAgain}
|
||||||
@ -87,14 +70,44 @@ const SwitchToUnconnectedAccountAlert = () => {
|
|||||||
{ t('dontShowThisAgain') }
|
{ t('dontShowThisAgain') }
|
||||||
<Tooltip
|
<Tooltip
|
||||||
position="top"
|
position="top"
|
||||||
title={t('unconnectedAccountAlertDisableTooltip')}
|
title={t('alertDisableTooltip')}
|
||||||
wrapperClassName="unconnected-account-alert__checkbox-label-tooltip"
|
wrapperClassName="unconnected-account-alert__checkbox-label-tooltip"
|
||||||
>
|
>
|
||||||
<i className="fa fa-info-circle" />
|
<i className="fa fa-info-circle" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
disabled={alertState === LOADING}
|
||||||
|
onClick={onClose}
|
||||||
|
type="secondary"
|
||||||
|
className="unconnected-account-alert__dismiss-button"
|
||||||
|
>
|
||||||
|
{ t('dismiss') }
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
title={isExtensionUrl(origin) ? t('currentExtension') : new URL(origin).host}
|
||||||
|
subtitle={t('currentAccountNotConnected')}
|
||||||
|
onClose={onClose}
|
||||||
|
contentClassName="unconnected-account-alert__content"
|
||||||
|
footerClassName="unconnected-account-alert__footer"
|
||||||
|
footer={footer}
|
||||||
|
>
|
||||||
|
<ConnectedAccountsList
|
||||||
|
accountToConnect={selectedIdentity}
|
||||||
|
connectAccount={() => dispatch(connectAccount(selectedAddress))}
|
||||||
|
connectedAccounts={connectedAccounts}
|
||||||
|
selectedAddress={selectedAddress}
|
||||||
|
setSelectedAddress={(address) => dispatch(switchToAccount(address))}
|
||||||
|
shouldRenderListOptions={false}
|
||||||
|
/>
|
||||||
</Popover>
|
</Popover>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SwitchToUnconnectedAccountAlert
|
export default UnconnectedAccountAlert
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
.unconnected-account-alert {
|
.unconnected-account-alert {
|
||||||
|
&__content {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&__footer {
|
&__footer {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
:only-child {
|
> :only-child {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__footer-buttons {
|
&__footer-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
button:first-child {
|
|
||||||
margin-right: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
&__dismiss-button {
|
||||||
font-size: 14px;
|
background: #037DD6;
|
||||||
line-height: 20px;
|
color: white;
|
||||||
padding: 8px;
|
height: 40px;
|
||||||
}
|
width: 100px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__error {
|
&__error {
|
||||||
@ -31,21 +34,24 @@
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__content {
|
&__checkbox-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 0 24px 24px 24px;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__checkbox {
|
&__checkbox {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
|
padding-top: 1px; // better alignment with rest of content
|
||||||
}
|
}
|
||||||
|
|
||||||
&__checkbox-label {
|
&__checkbox-label {
|
||||||
font-size: 14px;
|
display: flex;
|
||||||
|
font-size: 12px;
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
margin-bottom: auto;
|
margin-bottom: auto;
|
||||||
color: $Grey-500;
|
color: $Grey-500;
|
||||||
display: flex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__checkbox-label-tooltip {
|
&__checkbox-label-tooltip {
|
||||||
|
@ -12,13 +12,15 @@ export default class ConnectedAccountsListItem extends PureComponent {
|
|||||||
address: PropTypes.string.isRequired,
|
address: PropTypes.string.isRequired,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
name: PropTypes.node.isRequired,
|
name: PropTypes.node.isRequired,
|
||||||
status: PropTypes.node.isRequired,
|
status: PropTypes.string,
|
||||||
|
action: PropTypes.node,
|
||||||
options: PropTypes.node,
|
options: PropTypes.node,
|
||||||
}
|
}
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
className: null,
|
className: null,
|
||||||
options: null,
|
options: null,
|
||||||
|
action: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -27,6 +29,7 @@ export default class ConnectedAccountsListItem extends PureComponent {
|
|||||||
className,
|
className,
|
||||||
name,
|
name,
|
||||||
status,
|
status,
|
||||||
|
action,
|
||||||
options,
|
options,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
@ -39,18 +42,20 @@ export default class ConnectedAccountsListItem extends PureComponent {
|
|||||||
diameter={32}
|
diameter={32}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p className="connected-accounts-list__account-name">
|
||||||
<strong className="connected-accounts-list__account-name">{name}</strong>
|
<strong>{name}</strong>
|
||||||
</p>
|
</p>
|
||||||
{
|
{
|
||||||
status
|
status
|
||||||
? (
|
? (
|
||||||
<p className="connected-accounts-list__account-status">
|
<p className="connected-accounts-list__account-status">
|
||||||
|
|
||||||
{status}
|
{status}
|
||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
{action}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{options}
|
{options}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export { default } from './connected-accounts-list-permissions.component'
|
|
@ -1,7 +1,5 @@
|
|||||||
import { DateTime } from 'luxon'
|
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import React, { PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
import ConnectedAccountsListPermissions from './connected-accounts-list-permissions'
|
|
||||||
import ConnectedAccountsListItem from './connected-accounts-list-item'
|
import ConnectedAccountsListItem from './connected-accounts-list-item'
|
||||||
import ConnectedAccountsListOptions from './connected-accounts-list-options'
|
import ConnectedAccountsListOptions from './connected-accounts-list-options'
|
||||||
import { MenuItem } from '../../ui/menu'
|
import { MenuItem } from '../../ui/menu'
|
||||||
@ -13,7 +11,6 @@ export default class ConnectedAccountsList extends PureComponent {
|
|||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
accountToConnect: null,
|
accountToConnect: null,
|
||||||
permissions: undefined,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -26,31 +23,35 @@ export default class ConnectedAccountsList extends PureComponent {
|
|||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
lastActive: PropTypes.number,
|
lastActive: PropTypes.number,
|
||||||
})).isRequired,
|
})).isRequired,
|
||||||
permissions: PropTypes.arrayOf(PropTypes.shape({
|
connectAccount: PropTypes.func.isRequired,
|
||||||
key: PropTypes.string.isRequired,
|
|
||||||
})),
|
|
||||||
selectedAddress: PropTypes.string.isRequired,
|
selectedAddress: PropTypes.string.isRequired,
|
||||||
addPermittedAccount: PropTypes.func.isRequired,
|
removePermittedAccount: PropTypes.func,
|
||||||
removePermittedAccount: PropTypes.func.isRequired,
|
|
||||||
setSelectedAddress: PropTypes.func.isRequired,
|
setSelectedAddress: PropTypes.func.isRequired,
|
||||||
|
shouldRenderListOptions: (props, propName, componentName) => {
|
||||||
|
if (typeof props[propName] !== 'boolean') {
|
||||||
|
return new Error(
|
||||||
|
`Warning: Failed prop type: '${propName}' of component '${componentName}' must be a boolean. Received: ${typeof props[propName]}`
|
||||||
|
)
|
||||||
|
} else if (props[propName] && !props['removePermittedAccount']) {
|
||||||
|
return new Error(
|
||||||
|
`Warning: Failed prop type: '${propName}' of component '${componentName}' requires prop 'removePermittedAccount'.`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
accountWithOptionsShown: null,
|
accountWithOptionsShown: null,
|
||||||
}
|
}
|
||||||
|
|
||||||
connectAccount = () => {
|
|
||||||
this.props.addPermittedAccount(this.props.accountToConnect?.address)
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectAccount = () => {
|
disconnectAccount = () => {
|
||||||
this.hideAccountOptions()
|
this.hideAccountOptions()
|
||||||
this.props.removePermittedAccount(this.state.accountWithOptionsShown)
|
this.props.removePermittedAccount(this.state.accountWithOptionsShown)
|
||||||
}
|
}
|
||||||
|
|
||||||
switchAccount = () => {
|
switchAccount = (address) => {
|
||||||
this.hideAccountOptions()
|
this.hideAccountOptions()
|
||||||
this.props.setSelectedAddress(this.state.accountWithOptionsShown)
|
this.props.setSelectedAddress(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
hideAccountOptions = () => {
|
hideAccountOptions = () => {
|
||||||
@ -62,7 +63,7 @@ export default class ConnectedAccountsList extends PureComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderUnconnectedAccount () {
|
renderUnconnectedAccount () {
|
||||||
const { accountToConnect } = this.props
|
const { accountToConnect, connectAccount } = this.props
|
||||||
const { t } = this.context
|
const { t } = this.context
|
||||||
|
|
||||||
if (!accountToConnect) {
|
if (!accountToConnect) {
|
||||||
@ -75,59 +76,29 @@ export default class ConnectedAccountsList extends PureComponent {
|
|||||||
className="connected-accounts-list__row--highlight"
|
className="connected-accounts-list__row--highlight"
|
||||||
address={address}
|
address={address}
|
||||||
name={`${name} (…${address.substr(-4, 4)})`}
|
name={`${name} (…${address.substr(-4, 4)})`}
|
||||||
status={(
|
status={t('statusNotConnected')}
|
||||||
<>
|
action={(
|
||||||
{t('statusNotConnected')}
|
<a
|
||||||
·
|
className="connected-accounts-list__account-status-link"
|
||||||
<a className="connected-accounts-list__account-status-link" onClick={this.connectAccount}>
|
onClick={() => connectAccount(accountToConnect.address)}
|
||||||
|
>
|
||||||
{t('connect')}
|
{t('connect')}
|
||||||
</a>
|
</a>
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
renderListItemOptions (address) {
|
||||||
const { connectedAccounts, permissions, selectedAddress } = this.props
|
|
||||||
const { accountWithOptionsShown } = this.state
|
const { accountWithOptionsShown } = this.state
|
||||||
const { t } = this.context
|
const { t } = this.context
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<main className="connected-accounts-list">
|
|
||||||
{this.renderUnconnectedAccount()}
|
|
||||||
{
|
|
||||||
connectedAccounts.map(({ address, name, lastActive }, index) => {
|
|
||||||
let status
|
|
||||||
if (index === 0) {
|
|
||||||
status = t('primary')
|
|
||||||
} else if (lastActive) {
|
|
||||||
status = `${t('lastActive')}: ${DateTime.fromMillis(lastActive).toISODate()}`
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ConnectedAccountsListItem
|
|
||||||
key={address}
|
|
||||||
address={address}
|
|
||||||
name={`${name} (…${address.substr(-4, 4)})`}
|
|
||||||
status={status}
|
|
||||||
options={(
|
|
||||||
<ConnectedAccountsListOptions
|
<ConnectedAccountsListOptions
|
||||||
onHideOptions={this.hideAccountOptions}
|
onHideOptions={this.hideAccountOptions}
|
||||||
onShowOptions={this.showAccountOptions.bind(null, address)}
|
onShowOptions={this.showAccountOptions.bind(null, address)}
|
||||||
show={accountWithOptionsShown === address}
|
show={accountWithOptionsShown === address}
|
||||||
>
|
>
|
||||||
{
|
|
||||||
address === selectedAddress ? null : (
|
|
||||||
<MenuItem
|
|
||||||
iconClassName="fas fa-random"
|
|
||||||
onClick={this.switchAccount}
|
|
||||||
>
|
|
||||||
{t('switchToThisAccount')}
|
|
||||||
</MenuItem>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
iconClassName="disconnect-icon"
|
iconClassName="disconnect-icon"
|
||||||
onClick={this.disconnectAccount}
|
onClick={this.disconnectAccount}
|
||||||
@ -135,13 +106,57 @@ export default class ConnectedAccountsList extends PureComponent {
|
|||||||
{t('disconnectThisAccount')}
|
{t('disconnectThisAccount')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</ConnectedAccountsListOptions>
|
</ConnectedAccountsListOptions>
|
||||||
)}
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderListItemAction (address) {
|
||||||
|
const { t } = this.context
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
className="connected-accounts-list__account-status-link"
|
||||||
|
onClick={() => this.switchAccount(address)}
|
||||||
|
>
|
||||||
|
{t('switchToThisAccount')}
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const {
|
||||||
|
connectedAccounts,
|
||||||
|
selectedAddress,
|
||||||
|
shouldRenderListOptions,
|
||||||
|
} = this.props
|
||||||
|
const { t } = this.context
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<main className="connected-accounts-list">
|
||||||
|
{this.renderUnconnectedAccount()}
|
||||||
|
{
|
||||||
|
connectedAccounts.map(({ address, name }, index) => {
|
||||||
|
return (
|
||||||
|
<ConnectedAccountsListItem
|
||||||
|
key={address}
|
||||||
|
address={address}
|
||||||
|
name={`${name} (…${address.substr(-4, 4)})`}
|
||||||
|
status={index === 0 ? t('active') : null}
|
||||||
|
options={
|
||||||
|
shouldRenderListOptions
|
||||||
|
? this.renderListItemOptions(address)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
action={
|
||||||
|
address !== selectedAddress
|
||||||
|
? this.renderListItemAction(address)
|
||||||
|
: null
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</main>
|
</main>
|
||||||
<ConnectedAccountsListPermissions permissions={permissions} />
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -8,28 +8,34 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__account-name {
|
&__account-name {
|
||||||
|
display: inline;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%account-status-typography {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 17px;
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
&__account-status {
|
&__account-status {
|
||||||
|
@extend %account-status-typography;
|
||||||
|
display: inline;
|
||||||
color: $Grey-500;
|
color: $Grey-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__account-status-link {
|
&__account-status-link {
|
||||||
|
@extend %account-status-typography;
|
||||||
|
display: block;
|
||||||
|
|
||||||
&, &:hover {
|
&, &:hover {
|
||||||
color: $curious-blue;
|
color: $curious-blue;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__account-status {
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 17px;
|
|
||||||
padding-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__row {
|
&__row {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -40,10 +46,6 @@
|
|||||||
|
|
||||||
border-top: 1px solid $geyser;
|
border-top: 1px solid $geyser;
|
||||||
|
|
||||||
&:last-of-type {
|
|
||||||
border-bottom: 1px solid $geyser;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--highlight {
|
&--highlight {
|
||||||
background-color: $warning-light-yellow;
|
background-color: $warning-light-yellow;
|
||||||
border: 1px solid $warning-yellow;
|
border: 1px solid $warning-yellow;
|
||||||
@ -70,72 +72,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.connected-accounts-permissions {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 24px;
|
|
||||||
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 17px;
|
|
||||||
color: $Grey-500;
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
p + p {
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
color: #24292E;
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 24px;
|
|
||||||
|
|
||||||
background: none;
|
|
||||||
padding: 0;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__list {
|
|
||||||
padding-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__list-item {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
i {
|
|
||||||
display: block;
|
|
||||||
padding-right: 8px;
|
|
||||||
font-size: 18px;
|
|
||||||
color: $Grey-800;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__list-container {
|
|
||||||
max-height: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
height: auto;
|
|
||||||
transition: max-height 0.8s cubic-bezier(0.4, 0.0, 0.2, 1);
|
|
||||||
|
|
||||||
&--expanded {
|
|
||||||
// arbitrarily set hard coded value for effect to work
|
|
||||||
max-height: 100px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tippy-tooltip.none-theme {
|
.tippy-tooltip.none-theme {
|
||||||
background: none;
|
background: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -2,7 +2,7 @@ import classnames from 'classnames'
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import React, { PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
|
|
||||||
export default class ConnectedAccountsListPermissions extends PureComponent {
|
export default class ConnectedAccountsPermissions extends PureComponent {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
t: PropTypes.func.isRequired,
|
t: PropTypes.func.isRequired,
|
||||||
}
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export { default } from './connected-accounts-permissions.component'
|
@ -0,0 +1,64 @@
|
|||||||
|
.connected-accounts-permissions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 17px;
|
||||||
|
color: $Grey-500;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
p + p {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: #24292E;
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list-item {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
i {
|
||||||
|
display: block;
|
||||||
|
padding-right: 8px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: $Grey-800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list-container {
|
||||||
|
max-height: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
height: auto;
|
||||||
|
transition: max-height 0.8s cubic-bezier(0.4, 0.0, 0.2, 1);
|
||||||
|
|
||||||
|
&--expanded {
|
||||||
|
// arbitrarily set hard coded value for effect to work
|
||||||
|
max-height: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -88,6 +88,8 @@
|
|||||||
|
|
||||||
@import 'connected-accounts-list/index';
|
@import 'connected-accounts-list/index';
|
||||||
|
|
||||||
|
@import 'connected-accounts-permissions/index';
|
||||||
|
|
||||||
@import '../ui/icon-with-fallback/index';
|
@import '../ui/icon-with-fallback/index';
|
||||||
|
|
||||||
@import '../ui/icon/index';
|
@import '../ui/icon/index';
|
||||||
|
@ -107,7 +107,7 @@
|
|||||||
border-top: 1px solid #D2D8DD;
|
border-top: 1px solid #D2D8DD;
|
||||||
padding: 16px 24px 24px;
|
padding: 16px 24px 24px;
|
||||||
|
|
||||||
& :only-child {
|
> :only-child {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export { default as switchToConnected } from './switch-to-connected'
|
|
||||||
export { default as unconnectedAccount } from './unconnected-account'
|
export { default as unconnectedAccount } from './unconnected-account'
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
import { createSlice } from '@reduxjs/toolkit'
|
|
||||||
import { captureException } from '@sentry/browser'
|
|
||||||
|
|
||||||
import { ALERT_TYPES } from '../../../../app/scripts/controllers/alert'
|
|
||||||
import * as actionConstants from '../../store/actionConstants'
|
|
||||||
import { setAlertEnabledness, setSelectedAddress } from '../../store/actions'
|
|
||||||
|
|
||||||
// Constants
|
|
||||||
|
|
||||||
export const ALERT_STATE = {
|
|
||||||
CLOSED: 'CLOSED',
|
|
||||||
ERROR: 'ERROR',
|
|
||||||
LOADING: 'LOADING',
|
|
||||||
OPEN: 'OPEN',
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = ALERT_TYPES.switchToConnected
|
|
||||||
|
|
||||||
const initialState = {
|
|
||||||
state: ALERT_STATE.CLOSED,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slice (reducer plus auto-generated actions and action creators)
|
|
||||||
|
|
||||||
const slice = createSlice({
|
|
||||||
name,
|
|
||||||
initialState,
|
|
||||||
reducers: {
|
|
||||||
disableAlertFailed: (state) => {
|
|
||||||
state.state = ALERT_STATE.ERROR
|
|
||||||
},
|
|
||||||
disableAlertRequested: (state) => {
|
|
||||||
state.state = ALERT_STATE.LOADING
|
|
||||||
},
|
|
||||||
disableAlertSucceeded: (state) => {
|
|
||||||
state.state = ALERT_STATE.CLOSED
|
|
||||||
},
|
|
||||||
dismissAlert: (state) => {
|
|
||||||
state.state = ALERT_STATE.CLOSED
|
|
||||||
},
|
|
||||||
switchAccountFailed: (state) => {
|
|
||||||
state.state = ALERT_STATE.ERROR
|
|
||||||
},
|
|
||||||
switchAccountRequested: (state) => {
|
|
||||||
state.state = ALERT_STATE.LOADING
|
|
||||||
},
|
|
||||||
switchAccountSucceeded: (state) => {
|
|
||||||
state.state = ALERT_STATE.CLOSED
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extraReducers: {
|
|
||||||
[actionConstants.SELECTED_ADDRESS_CHANGED]: (state) => {
|
|
||||||
// close the alert if the account is switched while it's open
|
|
||||||
if (state.state === ALERT_STATE.OPEN) {
|
|
||||||
state.state = ALERT_STATE.CLOSED
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const { actions, reducer } = slice
|
|
||||||
|
|
||||||
export default reducer
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
export const getAlertState = (state) => state[name].state
|
|
||||||
|
|
||||||
export const alertIsOpen = (state) => state[name].state !== ALERT_STATE.CLOSED
|
|
||||||
|
|
||||||
// Actions / action-creators
|
|
||||||
|
|
||||||
const {
|
|
||||||
disableAlertFailed,
|
|
||||||
disableAlertRequested,
|
|
||||||
disableAlertSucceeded,
|
|
||||||
dismissAlert,
|
|
||||||
switchAccountFailed,
|
|
||||||
switchAccountRequested,
|
|
||||||
switchAccountSucceeded,
|
|
||||||
} = actions
|
|
||||||
|
|
||||||
export { dismissAlert }
|
|
||||||
|
|
||||||
export const dismissAndDisableAlert = () => {
|
|
||||||
return async (dispatch) => {
|
|
||||||
try {
|
|
||||||
await dispatch(disableAlertRequested())
|
|
||||||
await dispatch(setAlertEnabledness(name, false))
|
|
||||||
await dispatch(disableAlertSucceeded())
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
captureException(error)
|
|
||||||
await dispatch(disableAlertFailed())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const switchToAccount = (address) => {
|
|
||||||
return async (dispatch) => {
|
|
||||||
try {
|
|
||||||
await dispatch(switchAccountRequested())
|
|
||||||
await dispatch(setSelectedAddress(address))
|
|
||||||
await dispatch(switchAccountSucceeded())
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
captureException(error)
|
|
||||||
await dispatch(switchAccountFailed())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,11 @@ import { captureException } from '@sentry/browser'
|
|||||||
|
|
||||||
import { ALERT_TYPES } from '../../../../app/scripts/controllers/alert'
|
import { ALERT_TYPES } from '../../../../app/scripts/controllers/alert'
|
||||||
import * as actionConstants from '../../store/actionConstants'
|
import * as actionConstants from '../../store/actionConstants'
|
||||||
import { addPermittedAccount, setAlertEnabledness } from '../../store/actions'
|
import {
|
||||||
|
addPermittedAccount,
|
||||||
|
setAlertEnabledness,
|
||||||
|
setSelectedAddress,
|
||||||
|
} from '../../store/actions'
|
||||||
import {
|
import {
|
||||||
getOriginOfCurrentTab,
|
getOriginOfCurrentTab,
|
||||||
getSelectedAddress,
|
getSelectedAddress,
|
||||||
@ -39,9 +43,6 @@ const slice = createSlice({
|
|||||||
connectAccountSucceeded: (state) => {
|
connectAccountSucceeded: (state) => {
|
||||||
state.state = ALERT_STATE.CLOSED
|
state.state = ALERT_STATE.CLOSED
|
||||||
},
|
},
|
||||||
dismissAlert: (state) => {
|
|
||||||
state.state = ALERT_STATE.CLOSED
|
|
||||||
},
|
|
||||||
disableAlertFailed: (state) => {
|
disableAlertFailed: (state) => {
|
||||||
state.state = ALERT_STATE.ERROR
|
state.state = ALERT_STATE.ERROR
|
||||||
},
|
},
|
||||||
@ -51,6 +52,18 @@ const slice = createSlice({
|
|||||||
disableAlertSucceeded: (state) => {
|
disableAlertSucceeded: (state) => {
|
||||||
state.state = ALERT_STATE.CLOSED
|
state.state = ALERT_STATE.CLOSED
|
||||||
},
|
},
|
||||||
|
dismissAlert: (state) => {
|
||||||
|
state.state = ALERT_STATE.CLOSED
|
||||||
|
},
|
||||||
|
switchAccountFailed: (state) => {
|
||||||
|
state.state = ALERT_STATE.ERROR
|
||||||
|
},
|
||||||
|
switchAccountRequested: (state) => {
|
||||||
|
state.state = ALERT_STATE.LOADING
|
||||||
|
},
|
||||||
|
switchAccountSucceeded: (state) => {
|
||||||
|
state.state = ALERT_STATE.CLOSED
|
||||||
|
},
|
||||||
switchedToUnconnectedAccount: (state) => {
|
switchedToUnconnectedAccount: (state) => {
|
||||||
state.state = ALERT_STATE.OPEN
|
state.state = ALERT_STATE.OPEN
|
||||||
},
|
},
|
||||||
@ -81,10 +94,13 @@ const {
|
|||||||
connectAccountFailed,
|
connectAccountFailed,
|
||||||
connectAccountRequested,
|
connectAccountRequested,
|
||||||
connectAccountSucceeded,
|
connectAccountSucceeded,
|
||||||
dismissAlert,
|
|
||||||
disableAlertFailed,
|
disableAlertFailed,
|
||||||
disableAlertRequested,
|
disableAlertRequested,
|
||||||
disableAlertSucceeded,
|
disableAlertSucceeded,
|
||||||
|
dismissAlert,
|
||||||
|
switchAccountFailed,
|
||||||
|
switchAccountRequested,
|
||||||
|
switchAccountSucceeded,
|
||||||
switchedToUnconnectedAccount,
|
switchedToUnconnectedAccount,
|
||||||
} = actions
|
} = actions
|
||||||
|
|
||||||
@ -104,6 +120,20 @@ export const dismissAndDisableAlert = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const switchToAccount = (address) => {
|
||||||
|
return async (dispatch) => {
|
||||||
|
try {
|
||||||
|
await dispatch(switchAccountRequested())
|
||||||
|
await dispatch(setSelectedAddress(address))
|
||||||
|
await dispatch(switchAccountSucceeded())
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
captureException(error)
|
||||||
|
await dispatch(switchAccountFailed())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const connectAccount = () => {
|
export const connectAccount = () => {
|
||||||
return async (dispatch, getState) => {
|
return async (dispatch, getState) => {
|
||||||
const state = getState()
|
const state = getState()
|
||||||
|
@ -5,12 +5,11 @@ import sendReducer from './send/send.duck'
|
|||||||
import appStateReducer from './app/app'
|
import appStateReducer from './app/app'
|
||||||
import confirmTransactionReducer from './confirm-transaction/confirm-transaction.duck'
|
import confirmTransactionReducer from './confirm-transaction/confirm-transaction.duck'
|
||||||
import gasReducer from './gas/gas.duck'
|
import gasReducer from './gas/gas.duck'
|
||||||
import { switchToConnected, unconnectedAccount } from './alerts'
|
import { unconnectedAccount } from './alerts'
|
||||||
import historyReducer from './history/history'
|
import historyReducer from './history/history'
|
||||||
import { ALERT_TYPES } from '../../../app/scripts/controllers/alert'
|
import { ALERT_TYPES } from '../../../app/scripts/controllers/alert'
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
[ALERT_TYPES.switchToConnected]: switchToConnected,
|
|
||||||
[ALERT_TYPES.unconnectedAccount]: unconnectedAccount,
|
[ALERT_TYPES.unconnectedAccount]: unconnectedAccount,
|
||||||
activeTab: (s) => (s === undefined ? null : s),
|
activeTab: (s) => (s === undefined ? null : s),
|
||||||
metamask: metamaskReducer,
|
metamask: metamaskReducer,
|
||||||
|
@ -371,10 +371,8 @@ export const getCurrentLocale = (state) => state.metamask.currentLocale
|
|||||||
|
|
||||||
export const getAlertEnabledness = (state) => state.metamask.alertEnabledness
|
export const getAlertEnabledness = (state) => state.metamask.alertEnabledness
|
||||||
|
|
||||||
export const getSwitchToConnectedAlertEnabledness = (state) => getAlertEnabledness(state)[ALERT_TYPES.switchToConnected]
|
|
||||||
|
|
||||||
export const getUnconnectedAccountAlertEnabledness = (state) => getAlertEnabledness(state)[ALERT_TYPES.unconnectedAccount]
|
export const getUnconnectedAccountAlertEnabledness = (state) => getAlertEnabledness(state)[ALERT_TYPES.unconnectedAccount]
|
||||||
|
|
||||||
export const getSwitchToConnectedAlertShown = (state) => state.metamask.switchToConnectedAlertShown
|
export const getUnconnectedAccountAlertShown = (state) => state.metamask.unconnectedAccountAlertShownOrigins
|
||||||
|
|
||||||
export const getTokens = (state) => state.metamask.tokens
|
export const getTokens = (state) => state.metamask.tokens
|
||||||
|
@ -309,3 +309,27 @@ export function getAccountByAddress (accounts = [], targetAddress) {
|
|||||||
export function stripHttpSchemes (urlString) {
|
export function stripHttpSchemes (urlString) {
|
||||||
return urlString.replace(/^https?:\/\//u, '')
|
return urlString.replace(/^https?:\/\//u, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a URL-like value (object or string) is an extension URL.
|
||||||
|
*
|
||||||
|
* @param {string | URL | object} urlLike - The URL-like value to test.
|
||||||
|
* @returns {boolean} Whether the URL-like value is an extension URL.
|
||||||
|
*/
|
||||||
|
export function isExtensionUrl (urlLike) {
|
||||||
|
|
||||||
|
const EXT_PROTOCOLS = ['chrome-extension:', 'moz-extension:']
|
||||||
|
|
||||||
|
if (typeof urlLike === 'string') {
|
||||||
|
for (const protocol of EXT_PROTOCOLS) {
|
||||||
|
if (urlLike.startsWith(protocol)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlLike?.protocol) {
|
||||||
|
return EXT_PROTOCOLS.includes(urlLike.protocol)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import React, { PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
import { CONNECTED_ROUTE } from '../../helpers/constants/routes'
|
|
||||||
import Popover from '../../components/ui/popover'
|
import Popover from '../../components/ui/popover'
|
||||||
import ConnectedAccountsList from '../../components/app/connected-accounts-list'
|
import ConnectedAccountsList from '../../components/app/connected-accounts-list'
|
||||||
|
import ConnectedAccountsPermissions from '../../components/app/connected-accounts-permissions'
|
||||||
|
|
||||||
export default class ConnectedAccounts extends PureComponent {
|
export default class ConnectedAccounts extends PureComponent {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -17,7 +17,7 @@ export default class ConnectedAccounts extends PureComponent {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
accountToConnect: PropTypes.object,
|
accountToConnect: PropTypes.object,
|
||||||
activeTabOrigin: PropTypes.string.isRequired,
|
activeTabOrigin: PropTypes.string.isRequired,
|
||||||
addPermittedAccount: PropTypes.func.isRequired,
|
connectAccount: PropTypes.func.isRequired,
|
||||||
connectedAccounts: PropTypes.array.isRequired,
|
connectedAccounts: PropTypes.array.isRequired,
|
||||||
mostRecentOverviewPage: PropTypes.string.isRequired,
|
mostRecentOverviewPage: PropTypes.string.isRequired,
|
||||||
permissions: PropTypes.array,
|
permissions: PropTypes.array,
|
||||||
@ -28,16 +28,12 @@ export default class ConnectedAccounts extends PureComponent {
|
|||||||
history: PropTypes.object.isRequired,
|
history: PropTypes.object.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
viewConnectedSites = () => {
|
|
||||||
this.props.history.push(CONNECTED_ROUTE)
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
accountToConnect,
|
accountToConnect,
|
||||||
activeTabOrigin,
|
activeTabOrigin,
|
||||||
isActiveTabExtension,
|
isActiveTabExtension,
|
||||||
addPermittedAccount,
|
connectAccount,
|
||||||
connectedAccounts,
|
connectedAccounts,
|
||||||
history,
|
history,
|
||||||
mostRecentOverviewPage,
|
mostRecentOverviewPage,
|
||||||
@ -58,15 +54,16 @@ export default class ConnectedAccounts extends PureComponent {
|
|||||||
subtitle={connectedAccounts.length ? connectedAccountsDescription : t('connectedAccountsEmptyDescription')}
|
subtitle={connectedAccounts.length ? connectedAccountsDescription : t('connectedAccountsEmptyDescription')}
|
||||||
onClose={() => history.push(mostRecentOverviewPage)}
|
onClose={() => history.push(mostRecentOverviewPage)}
|
||||||
footerClassName="connected-accounts__footer"
|
footerClassName="connected-accounts__footer"
|
||||||
|
footer={<ConnectedAccountsPermissions permissions={permissions} />}
|
||||||
>
|
>
|
||||||
<ConnectedAccountsList
|
<ConnectedAccountsList
|
||||||
accountToConnect={accountToConnect}
|
accountToConnect={accountToConnect}
|
||||||
addPermittedAccount={addPermittedAccount}
|
connectAccount={connectAccount}
|
||||||
connectedAccounts={connectedAccounts}
|
connectedAccounts={connectedAccounts}
|
||||||
permissions={permissions}
|
|
||||||
selectedAddress={selectedAddress}
|
selectedAddress={selectedAddress}
|
||||||
removePermittedAccount={removePermittedAccount}
|
removePermittedAccount={removePermittedAccount}
|
||||||
setSelectedAddress={setSelectedAddress}
|
setSelectedAddress={setSelectedAddress}
|
||||||
|
shouldRenderListOptions
|
||||||
/>
|
/>
|
||||||
</Popover>
|
</Popover>
|
||||||
)
|
)
|
||||||
|
@ -6,11 +6,10 @@ import {
|
|||||||
getPermissionsForActiveTab,
|
getPermissionsForActiveTab,
|
||||||
getSelectedAddress,
|
getSelectedAddress,
|
||||||
} from '../../selectors'
|
} from '../../selectors'
|
||||||
|
import { isExtensionUrl } from '../../helpers/utils/util'
|
||||||
import { addPermittedAccount, removePermittedAccount, setSelectedAddress } from '../../store/actions'
|
import { addPermittedAccount, removePermittedAccount, setSelectedAddress } from '../../store/actions'
|
||||||
import { getMostRecentOverviewPage } from '../../ducks/history/history'
|
import { getMostRecentOverviewPage } from '../../ducks/history/history'
|
||||||
|
|
||||||
const EXT_PROTOCOLS = ['chrome-extension:', 'moz-extension:']
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
const mapStateToProps = (state) => {
|
||||||
const { activeTab } = state
|
const { activeTab } = state
|
||||||
const accountToConnect = getAccountToConnectToActiveTab(state)
|
const accountToConnect = getAccountToConnectToActiveTab(state)
|
||||||
@ -18,7 +17,7 @@ const mapStateToProps = (state) => {
|
|||||||
const permissions = getPermissionsForActiveTab(state)
|
const permissions = getPermissionsForActiveTab(state)
|
||||||
const selectedAddress = getSelectedAddress(state)
|
const selectedAddress = getSelectedAddress(state)
|
||||||
|
|
||||||
const isActiveTabExtension = EXT_PROTOCOLS.includes(activeTab.protocol)
|
const isActiveTabExtension = isExtensionUrl(activeTab)
|
||||||
return {
|
return {
|
||||||
accountToConnect,
|
accountToConnect,
|
||||||
isActiveTabExtension,
|
isActiveTabExtension,
|
||||||
@ -39,14 +38,14 @@ const mapDispatchToProps = (dispatch) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||||
const { activeTabOrigin: origin } = stateProps
|
const { activeTabOrigin } = stateProps
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...ownProps,
|
...ownProps,
|
||||||
...stateProps,
|
...stateProps,
|
||||||
...dispatchProps,
|
...dispatchProps,
|
||||||
addPermittedAccount: (address) => dispatchProps.addPermittedAccount(origin, address),
|
connectAccount: (address) => dispatchProps.addPermittedAccount(activeTabOrigin, address),
|
||||||
removePermittedAccount: (address) => dispatchProps.removePermittedAccount(origin, address),
|
removePermittedAccount: (address) => dispatchProps.removePermittedAccount(activeTabOrigin, address),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +46,6 @@ const AlertsTab = () => {
|
|||||||
const t = useI18nContext()
|
const t = useI18nContext()
|
||||||
|
|
||||||
const alertConfig = {
|
const alertConfig = {
|
||||||
[ALERT_TYPES.switchToConnected]: {
|
|
||||||
title: t('alertSettingsSwitchToConnected'),
|
|
||||||
description: t('alertSettingsSwitchToConnectedDescription'),
|
|
||||||
},
|
|
||||||
[ALERT_TYPES.unconnectedAccount]: {
|
[ALERT_TYPES.unconnectedAccount]: {
|
||||||
title: t('alertSettingsUnconnectedAccount'),
|
title: t('alertSettingsUnconnectedAccount'),
|
||||||
description: t('alertSettingsUnconnectedAccountDescription'),
|
description: t('alertSettingsUnconnectedAccountDescription'),
|
||||||
|
@ -1187,7 +1187,7 @@ export function showAccountDetail (address) {
|
|||||||
log.debug(`background.setSelectedAddress`)
|
log.debug(`background.setSelectedAddress`)
|
||||||
|
|
||||||
const state = getState()
|
const state = getState()
|
||||||
const unconnectedAccountAlertIsEnabled = getUnconnectedAccountAlertEnabledness(state)
|
const unconnectedAccountAccountAlertIsEnabled = getUnconnectedAccountAlertEnabledness(state)
|
||||||
const activeTabOrigin = state.activeTab.origin
|
const activeTabOrigin = state.activeTab.origin
|
||||||
const selectedAddress = getSelectedAddress(state)
|
const selectedAddress = getSelectedAddress(state)
|
||||||
const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab(state)
|
const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab(state)
|
||||||
@ -1207,9 +1207,9 @@ export function showAccountDetail (address) {
|
|||||||
type: actionConstants.SHOW_ACCOUNT_DETAIL,
|
type: actionConstants.SHOW_ACCOUNT_DETAIL,
|
||||||
value: address,
|
value: address,
|
||||||
})
|
})
|
||||||
if (unconnectedAccountAlertIsEnabled && switchingToUnconnectedAddress) {
|
if (unconnectedAccountAccountAlertIsEnabled && switchingToUnconnectedAddress) {
|
||||||
dispatch(switchedToUnconnectedAccount())
|
dispatch(switchedToUnconnectedAccount())
|
||||||
await setSwitchToConnectedAlertShown(activeTabOrigin)
|
await setUnconnectedAccountAlertShown(activeTabOrigin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2139,8 +2139,8 @@ export function setAlertEnabledness (alertId, enabledness) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function setSwitchToConnectedAlertShown (origin) {
|
export async function setUnconnectedAccountAlertShown (origin) {
|
||||||
await promisifiedBackground.setSwitchToConnectedAlertShown(origin)
|
await promisifiedBackground.setUnconnectedAccountAlertShown(origin)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadingMethodDataStarted () {
|
export function loadingMethodDataStarted () {
|
||||||
|
18
ui/index.js
18
ui/index.js
@ -13,10 +13,10 @@ import { ENVIRONMENT_TYPE_POPUP } from '../app/scripts/lib/enums'
|
|||||||
import { fetchLocale } from './app/helpers/utils/i18n-helper'
|
import { fetchLocale } from './app/helpers/utils/i18n-helper'
|
||||||
import switchDirection from './app/helpers/utils/switch-direction'
|
import switchDirection from './app/helpers/utils/switch-direction'
|
||||||
import { getPermittedAccountsForCurrentTab, getSelectedAddress } from './app/selectors'
|
import { getPermittedAccountsForCurrentTab, getSelectedAddress } from './app/selectors'
|
||||||
import { ALERT_STATE } from './app/ducks/alerts/switch-to-connected'
|
import { ALERT_STATE } from './app/ducks/alerts/unconnected-account'
|
||||||
import {
|
import {
|
||||||
getSwitchToConnectedAlertEnabledness,
|
getUnconnectedAccountAlertEnabledness,
|
||||||
getSwitchToConnectedAlertShown,
|
getUnconnectedAccountAlertShown,
|
||||||
} from './app/ducks/metamask/metamask'
|
} from './app/ducks/metamask/metamask'
|
||||||
|
|
||||||
log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn')
|
log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn')
|
||||||
@ -71,18 +71,18 @@ async function startApp (metamaskState, backgroundConnection, opts) {
|
|||||||
const origin = draftInitialState.activeTab.origin
|
const origin = draftInitialState.activeTab.origin
|
||||||
const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab(draftInitialState)
|
const permittedAccountsForCurrentTab = getPermittedAccountsForCurrentTab(draftInitialState)
|
||||||
const selectedAddress = getSelectedAddress(draftInitialState)
|
const selectedAddress = getSelectedAddress(draftInitialState)
|
||||||
const switchToConnectedAlertShown = getSwitchToConnectedAlertShown(draftInitialState)
|
const unconnectedAccountAlertShownOrigins = getUnconnectedAccountAlertShown(draftInitialState)
|
||||||
const switchToConnectedAlertIsEnabled = getSwitchToConnectedAlertEnabledness(draftInitialState)
|
const unconnectedAccountAlertIsEnabled = getUnconnectedAccountAlertEnabledness(draftInitialState)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
origin &&
|
origin &&
|
||||||
switchToConnectedAlertIsEnabled &&
|
unconnectedAccountAlertIsEnabled &&
|
||||||
!switchToConnectedAlertShown[origin] &&
|
!unconnectedAccountAlertShownOrigins[origin] &&
|
||||||
permittedAccountsForCurrentTab.length > 0 &&
|
permittedAccountsForCurrentTab.length > 0 &&
|
||||||
!permittedAccountsForCurrentTab.includes(selectedAddress)
|
!permittedAccountsForCurrentTab.includes(selectedAddress)
|
||||||
) {
|
) {
|
||||||
draftInitialState[ALERT_TYPES.switchToConnected] = { state: ALERT_STATE.OPEN }
|
draftInitialState[ALERT_TYPES.unconnectedAccount] = { state: ALERT_STATE.OPEN }
|
||||||
actions.setSwitchToConnectedAlertShown(origin)
|
actions.setUnconnectedAccountAlertShown(origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user