mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Refactor NetworkDisplay, ConnectedStatusIndicator, etc to use ColorIndicator (#10214)
This commit is contained in:
parent
569672027c
commit
3806e0a2a6
@ -171,7 +171,7 @@ describe('MetaMask', function () {
|
||||
it('changes the network', async function () {
|
||||
await driver.switchToWindow(extension)
|
||||
|
||||
await driver.clickElement(By.css('.network-name'))
|
||||
await driver.clickElement(By.css('.network-display'))
|
||||
await driver.delay(regularDelayMs)
|
||||
|
||||
await driver.clickElement(By.xpath(`//span[contains(text(), 'Ropsten')]`))
|
||||
|
@ -177,7 +177,7 @@ describe('Using MetaMask with an existing account', function () {
|
||||
|
||||
describe('Add an account', function () {
|
||||
it('switches to localhost', async function () {
|
||||
await driver.clickElement(By.css('.network-name'))
|
||||
await driver.clickElement(By.css('.network-display'))
|
||||
await driver.delay(regularDelayMs)
|
||||
|
||||
await driver.clickElement(
|
||||
|
@ -205,11 +205,13 @@ describe('MetaMask', function () {
|
||||
})
|
||||
|
||||
it('switches to localhost', async function () {
|
||||
await driver.clickElement(By.css('.network-name'))
|
||||
await driver.clickElement(By.css('.network-display'))
|
||||
await driver.delay(regularDelayMs)
|
||||
|
||||
await driver.clickElement(
|
||||
By.xpath(`//span[contains(text(), 'Localhost')]`),
|
||||
By.xpath(
|
||||
`//span[contains(@class, 'network-name-item') and contains(text(), 'Localhost 8545')]`,
|
||||
),
|
||||
)
|
||||
await driver.delay(largeDelayMs * 2)
|
||||
})
|
||||
|
@ -1723,7 +1723,7 @@ describe('MetaMask', function () {
|
||||
const rpcUrl = 'http://127.0.0.1:8545/1'
|
||||
const chainId = '0x539' // Ganache default, decimal 1337
|
||||
|
||||
await driver.clickElement(By.css('.network-name'))
|
||||
await driver.clickElement(By.css('.network-display'))
|
||||
await driver.delay(regularDelayMs)
|
||||
|
||||
await driver.clickElement(
|
||||
@ -1753,7 +1753,7 @@ describe('MetaMask', function () {
|
||||
const rpcUrl = 'http://127.0.0.1:8545/2'
|
||||
const chainId = '0x539' // Ganache default, decimal 1337
|
||||
|
||||
await driver.clickElement(By.css('.network-name'))
|
||||
await driver.clickElement(By.css('.network-display'))
|
||||
await driver.delay(regularDelayMs)
|
||||
|
||||
await driver.clickElement(
|
||||
@ -1780,7 +1780,7 @@ describe('MetaMask', function () {
|
||||
})
|
||||
|
||||
it('selects another provider', async function () {
|
||||
await driver.clickElement(By.css('.network-name'))
|
||||
await driver.clickElement(By.css('.network-display'))
|
||||
await driver.delay(regularDelayMs)
|
||||
|
||||
await driver.clickElement(
|
||||
@ -1790,7 +1790,7 @@ describe('MetaMask', function () {
|
||||
})
|
||||
|
||||
it('finds all recent RPCs in history', async function () {
|
||||
await driver.clickElement(By.css('.network-name'))
|
||||
await driver.clickElement(By.css('.network-display'))
|
||||
await driver.delay(regularDelayMs)
|
||||
|
||||
// only recent 3 are found and in correct order (most recent at the top)
|
||||
|
@ -4,13 +4,11 @@ import classnames from 'classnames'
|
||||
import Identicon from '../../ui/identicon'
|
||||
import MetaFoxLogo from '../../ui/metafox-logo'
|
||||
import { DEFAULT_ROUTE } from '../../../helpers/constants/routes'
|
||||
import NetworkIndicator from '../network'
|
||||
import NetworkDisplay from '../network-display'
|
||||
|
||||
export default class AppHeader extends PureComponent {
|
||||
static propTypes = {
|
||||
history: PropTypes.object,
|
||||
network: PropTypes.string,
|
||||
provider: PropTypes.object,
|
||||
networkDropdownOpen: PropTypes.bool,
|
||||
showNetworkDropdown: PropTypes.func,
|
||||
hideNetworkDropdown: PropTypes.func,
|
||||
@ -37,8 +35,14 @@ export default class AppHeader extends PureComponent {
|
||||
networkDropdownOpen,
|
||||
showNetworkDropdown,
|
||||
hideNetworkDropdown,
|
||||
disabled,
|
||||
disableNetworkIndicator,
|
||||
} = this.props
|
||||
|
||||
if (disabled || disableNetworkIndicator) {
|
||||
return
|
||||
}
|
||||
|
||||
if (networkDropdownOpen === false) {
|
||||
this.context.metricsEvent({
|
||||
eventOpts: {
|
||||
@ -91,8 +95,6 @@ export default class AppHeader extends PureComponent {
|
||||
render() {
|
||||
const {
|
||||
history,
|
||||
network,
|
||||
provider,
|
||||
isUnlocked,
|
||||
hideNetworkIndicator,
|
||||
disableNetworkIndicator,
|
||||
@ -119,9 +121,10 @@ export default class AppHeader extends PureComponent {
|
||||
<div className="app-header__account-menu-container">
|
||||
{!hideNetworkIndicator && (
|
||||
<div className="app-header__network-component-wrapper">
|
||||
<NetworkIndicator
|
||||
network={network}
|
||||
provider={provider}
|
||||
<NetworkDisplay
|
||||
colored={false}
|
||||
outline
|
||||
iconClassName="app-header__network-down-arrow"
|
||||
onClick={(event) => this.handleNetworkIndicatorClick(event)}
|
||||
disabled={disabled || disableNetworkIndicator}
|
||||
/>
|
||||
|
@ -95,13 +95,12 @@
|
||||
flex: 1 0 auto;
|
||||
width: 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.network-component.pointer {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.network-indicator {
|
||||
width: 100%;
|
||||
}
|
||||
&__network-down-arrow {
|
||||
background-image: url(/images/icons/caret-down.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import sinon from 'sinon'
|
||||
import { shallow } from 'enzyme'
|
||||
import MetaFoxLogo from '../../../ui/metafox-logo'
|
||||
import AppHeader from '..'
|
||||
import NetworkDisplay from '../../network-display'
|
||||
|
||||
describe('App Header', function () {
|
||||
let wrapper
|
||||
@ -49,7 +50,7 @@ describe('App Header', function () {
|
||||
|
||||
describe('Network', function () {
|
||||
it('shows network dropdown when networkDropdownOpen is false', function () {
|
||||
const network = wrapper.find({ network: 'test' })
|
||||
const network = wrapper.find(NetworkDisplay)
|
||||
|
||||
network.simulate('click', {
|
||||
preventDefault: () => undefined,
|
||||
@ -61,7 +62,7 @@ describe('App Header', function () {
|
||||
|
||||
it('hides network dropdown when networkDropdownOpen is true', function () {
|
||||
wrapper.setProps({ networkDropdownOpen: true })
|
||||
const network = wrapper.find({ network: 'test' })
|
||||
const network = wrapper.find(NetworkDisplay)
|
||||
|
||||
network.simulate('click', {
|
||||
preventDefault: () => undefined,
|
||||
|
@ -10,6 +10,11 @@
|
||||
padding: 4px 13px 4px 13px;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
|
||||
& .network-display {
|
||||
margin-right: 0;
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
&__back-button-container {
|
||||
|
@ -1,71 +0,0 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import {
|
||||
STATUS_CONNECTED,
|
||||
STATUS_CONNECTED_TO_ANOTHER_ACCOUNT,
|
||||
STATUS_NOT_CONNECTED,
|
||||
} from '../../../helpers/constants/connected-sites'
|
||||
|
||||
export default class ConnectedStatusIndicator extends Component {
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
status: PropTypes.oneOf([
|
||||
STATUS_CONNECTED,
|
||||
STATUS_CONNECTED_TO_ANOTHER_ACCOUNT,
|
||||
STATUS_NOT_CONNECTED,
|
||||
]),
|
||||
onClick: PropTypes.func,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
status: STATUS_NOT_CONNECTED,
|
||||
onClick: undefined,
|
||||
}
|
||||
|
||||
renderStatusCircle = () => {
|
||||
const { status } = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames({
|
||||
'connected-status-indicator__green-circle':
|
||||
status === STATUS_CONNECTED,
|
||||
'connected-status-indicator__yellow-circle':
|
||||
status === STATUS_CONNECTED_TO_ANOTHER_ACCOUNT,
|
||||
'connected-status-indicator__grey-circle':
|
||||
status === STATUS_NOT_CONNECTED,
|
||||
})}
|
||||
>
|
||||
<span className="connected-status-indicator__inner-circle" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderStatusText = () => {
|
||||
const { t } = this.context
|
||||
const { status } = this.props
|
||||
|
||||
const text =
|
||||
status === STATUS_CONNECTED
|
||||
? t('statusConnected')
|
||||
: t('statusNotConnected')
|
||||
|
||||
return <div className="connected-status-indicator__text">{text}</div>
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<button
|
||||
className="connected-status-indicator"
|
||||
onClick={this.props.onClick}
|
||||
>
|
||||
{this.renderStatusCircle()}
|
||||
{this.renderStatusText()}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import { findKey } from 'lodash'
|
||||
import { connect } from 'react-redux'
|
||||
import {
|
||||
STATUS_CONNECTED,
|
||||
STATUS_CONNECTED_TO_ANOTHER_ACCOUNT,
|
||||
STATUS_NOT_CONNECTED,
|
||||
} from '../../../helpers/constants/connected-sites'
|
||||
import {
|
||||
getAddressConnectedDomainMap,
|
||||
getOriginOfCurrentTab,
|
||||
getSelectedAddress,
|
||||
} from '../../../selectors'
|
||||
import ConnectedStatusIndicator from './connected-status-indicator.component'
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
const selectedAddress = getSelectedAddress(state)
|
||||
const addressConnectedDomainMap = getAddressConnectedDomainMap(state)
|
||||
const originOfCurrentTab = getOriginOfCurrentTab(state)
|
||||
|
||||
const selectedAddressDomainMap = addressConnectedDomainMap[selectedAddress]
|
||||
const currentTabIsConnectedToSelectedAddress = Boolean(
|
||||
selectedAddressDomainMap && selectedAddressDomainMap[originOfCurrentTab],
|
||||
)
|
||||
|
||||
let status
|
||||
if (currentTabIsConnectedToSelectedAddress) {
|
||||
status = STATUS_CONNECTED
|
||||
} else if (findKey(addressConnectedDomainMap, originOfCurrentTab)) {
|
||||
status = STATUS_CONNECTED_TO_ANOTHER_ACCOUNT
|
||||
} else {
|
||||
status = STATUS_NOT_CONNECTED
|
||||
}
|
||||
|
||||
return {
|
||||
status,
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(ConnectedStatusIndicator)
|
@ -0,0 +1,66 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { findKey } from 'lodash'
|
||||
import {
|
||||
STATUS_CONNECTED,
|
||||
STATUS_CONNECTED_TO_ANOTHER_ACCOUNT,
|
||||
STATUS_NOT_CONNECTED,
|
||||
} from '../../../helpers/constants/connected-sites'
|
||||
import ColorIndicator from '../../ui/color-indicator'
|
||||
import { COLORS } from '../../../helpers/constants/design-system'
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext'
|
||||
import {
|
||||
getAddressConnectedDomainMap,
|
||||
getOriginOfCurrentTab,
|
||||
getSelectedAddress,
|
||||
} from '../../../selectors'
|
||||
|
||||
export default function ConnectedStatusIndicator({ onClick }) {
|
||||
const t = useI18nContext()
|
||||
|
||||
const selectedAddress = useSelector(getSelectedAddress)
|
||||
const addressConnectedDomainMap = useSelector(getAddressConnectedDomainMap)
|
||||
const originOfCurrentTab = useSelector(getOriginOfCurrentTab)
|
||||
|
||||
const selectedAddressDomainMap = addressConnectedDomainMap[selectedAddress]
|
||||
const currentTabIsConnectedToSelectedAddress = Boolean(
|
||||
selectedAddressDomainMap && selectedAddressDomainMap[originOfCurrentTab],
|
||||
)
|
||||
let status
|
||||
if (currentTabIsConnectedToSelectedAddress) {
|
||||
status = STATUS_CONNECTED
|
||||
} else if (findKey(addressConnectedDomainMap, originOfCurrentTab)) {
|
||||
status = STATUS_CONNECTED_TO_ANOTHER_ACCOUNT
|
||||
} else {
|
||||
status = STATUS_NOT_CONNECTED
|
||||
}
|
||||
|
||||
let indicatorType = ColorIndicator.TYPES.OUTLINE
|
||||
let indicatorColor = COLORS.UI4
|
||||
|
||||
if (status === STATUS_CONNECTED) {
|
||||
indicatorColor = COLORS.SUCCESS1
|
||||
indicatorType = ColorIndicator.TYPES.PARTIAL
|
||||
} else if (status === STATUS_CONNECTED_TO_ANOTHER_ACCOUNT) {
|
||||
indicatorColor = COLORS.ALERT1
|
||||
}
|
||||
|
||||
const text =
|
||||
status === STATUS_CONNECTED ? t('statusConnected') : t('statusNotConnected')
|
||||
|
||||
return (
|
||||
<button className="connected-status-indicator" onClick={onClick}>
|
||||
<ColorIndicator color={indicatorColor} type={indicatorType} />
|
||||
<div className="connected-status-indicator__text">{text}</div>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
ConnectedStatusIndicator.defaultProps = {
|
||||
onClick: undefined,
|
||||
}
|
||||
|
||||
ConnectedStatusIndicator.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
}
|
@ -1 +1 @@
|
||||
export { default } from './connected-status-indicator.container'
|
||||
export { default } from './connected-status-indicator'
|
||||
|
@ -73,6 +73,12 @@ export class DropdownMenuItem extends Component {
|
||||
onClick()
|
||||
closeMenu()
|
||||
}}
|
||||
onKeyPress={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
onClick()
|
||||
closeMenu()
|
||||
}
|
||||
}}
|
||||
style={{
|
||||
listStyle: 'none',
|
||||
padding: '8px 0px',
|
||||
@ -85,6 +91,7 @@ export class DropdownMenuItem extends Component {
|
||||
color: 'white',
|
||||
...style,
|
||||
}}
|
||||
tabIndex="0"
|
||||
>
|
||||
{children}
|
||||
</li>
|
||||
|
@ -1,48 +0,0 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
|
||||
function NetworkDropdownIcon(props) {
|
||||
const { backgroundColor, isSelected, innerBorder, diameter, loading } = props
|
||||
|
||||
return loading ? (
|
||||
<span
|
||||
className="pointer network-indicator"
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
}}
|
||||
>
|
||||
<img alt="" style={{ width: '27px' }} src="images/loading.svg" />
|
||||
</span>
|
||||
) : (
|
||||
<div className={`menu-icon-circle${isSelected ? '--active' : ''}`}>
|
||||
<div
|
||||
style={{
|
||||
background: backgroundColor,
|
||||
border: innerBorder,
|
||||
height: `${diameter}px`,
|
||||
width: `${diameter}px`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
NetworkDropdownIcon.defaultProps = {
|
||||
backgroundColor: undefined,
|
||||
loading: false,
|
||||
innerBorder: 'none',
|
||||
diameter: '12',
|
||||
isSelected: false,
|
||||
}
|
||||
|
||||
NetworkDropdownIcon.propTypes = {
|
||||
backgroundColor: PropTypes.string,
|
||||
loading: PropTypes.bool,
|
||||
innerBorder: PropTypes.string,
|
||||
diameter: PropTypes.string,
|
||||
isSelected: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default NetworkDropdownIcon
|
@ -14,8 +14,9 @@ import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
|
||||
import { isPrefixedFormattedHexString } from '../../../../../shared/modules/utils'
|
||||
import { getEnvironmentType } from '../../../../../app/scripts/lib/util'
|
||||
|
||||
import ColorIndicator from '../../ui/color-indicator'
|
||||
import { COLORS } from '../../../helpers/constants/design-system'
|
||||
import { Dropdown, DropdownMenuItem } from './components/dropdown'
|
||||
import NetworkDropdownIcon from './components/network-dropdown-icon'
|
||||
|
||||
// classes from nodes of the toggle element.
|
||||
const notToggleElementClassnames = [
|
||||
@ -26,6 +27,12 @@ const notToggleElementClassnames = [
|
||||
'network-component',
|
||||
]
|
||||
|
||||
const DROP_DOWN_MENU_ITEM_STYLE = {
|
||||
fontSize: '16px',
|
||||
lineHeight: '20px',
|
||||
padding: '12px 0',
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
provider: state.metamask.provider,
|
||||
@ -140,9 +147,11 @@ class NetworkDropdown extends Component {
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#d6d9dc"
|
||||
isSelected={isCurrentRpcTarget}
|
||||
<ColorIndicator
|
||||
color={COLORS.UI2}
|
||||
size={ColorIndicator.SIZES.LARGE}
|
||||
type={ColorIndicator.TYPES.FILLED}
|
||||
borderColor={isCurrentRpcTarget ? COLORS.WHITE : COLORS.UI2}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
@ -192,19 +201,48 @@ class NetworkDropdown extends Component {
|
||||
return name
|
||||
}
|
||||
|
||||
renderNetworkEntry(network) {
|
||||
const {
|
||||
provider: { type: providerType },
|
||||
} = this.props
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={network}
|
||||
closeMenu={this.props.hideNetworkDropdown}
|
||||
onClick={() => this.handleClick(network)}
|
||||
style={DROP_DOWN_MENU_ITEM_STYLE}
|
||||
>
|
||||
{providerType === network ? (
|
||||
<i className="fa fa-check" />
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<ColorIndicator
|
||||
color={network}
|
||||
size={ColorIndicator.SIZES.LARGE}
|
||||
type={ColorIndicator.TYPES.FILLED}
|
||||
borderColor={providerType === network ? COLORS.WHITE : network}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
style={{
|
||||
color: providerType === network ? '#ffffff' : '#9b9b9b',
|
||||
}}
|
||||
>
|
||||
{this.context.t(network)}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
provider: { type: providerType, rpcUrl: activeNetwork },
|
||||
provider: { rpcUrl: activeNetwork },
|
||||
setNetworksTabAddMode,
|
||||
setSelectedSettingsRpcUrl,
|
||||
} = this.props
|
||||
const rpcListDetail = this.props.frequentRpcListDetail
|
||||
const isOpen = this.props.networkDropdownOpen
|
||||
const dropdownMenuItemStyle = {
|
||||
fontSize: '16px',
|
||||
lineHeight: '20px',
|
||||
padding: '12px 0',
|
||||
}
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
@ -241,126 +279,12 @@ class NetworkDropdown extends Component {
|
||||
{this.context.t('defaultNetwork')}
|
||||
</div>
|
||||
</div>
|
||||
<DropdownMenuItem
|
||||
key="main"
|
||||
closeMenu={() => this.props.hideNetworkDropdown()}
|
||||
onClick={() => this.handleClick('mainnet')}
|
||||
style={{ ...dropdownMenuItemStyle, borderColor: '#038789' }}
|
||||
>
|
||||
{providerType === 'mainnet' ? (
|
||||
<i className="fa fa-check" />
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#29B6AF"
|
||||
isSelected={providerType === 'mainnet'}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
style={{
|
||||
color: providerType === 'mainnet' ? '#ffffff' : '#9b9b9b',
|
||||
}}
|
||||
>
|
||||
{this.context.t('mainnet')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
key="ropsten"
|
||||
closeMenu={() => this.props.hideNetworkDropdown()}
|
||||
onClick={() => this.handleClick('ropsten')}
|
||||
style={dropdownMenuItemStyle}
|
||||
>
|
||||
{providerType === 'ropsten' ? (
|
||||
<i className="fa fa-check" />
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#ff4a8d"
|
||||
isSelected={providerType === 'ropsten'}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
style={{
|
||||
color: providerType === 'ropsten' ? '#ffffff' : '#9b9b9b',
|
||||
}}
|
||||
>
|
||||
{this.context.t('ropsten')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
key="kovan"
|
||||
closeMenu={() => this.props.hideNetworkDropdown()}
|
||||
onClick={() => this.handleClick('kovan')}
|
||||
style={dropdownMenuItemStyle}
|
||||
>
|
||||
{providerType === 'kovan' ? (
|
||||
<i className="fa fa-check" />
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#7057ff"
|
||||
isSelected={providerType === 'kovan'}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
style={{
|
||||
color: providerType === 'kovan' ? '#ffffff' : '#9b9b9b',
|
||||
}}
|
||||
>
|
||||
{this.context.t('kovan')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
key="rinkeby"
|
||||
closeMenu={() => this.props.hideNetworkDropdown()}
|
||||
onClick={() => this.handleClick('rinkeby')}
|
||||
style={dropdownMenuItemStyle}
|
||||
>
|
||||
{providerType === 'rinkeby' ? (
|
||||
<i className="fa fa-check" />
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#f6c343"
|
||||
isSelected={providerType === 'rinkeby'}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
style={{
|
||||
color: providerType === 'rinkeby' ? '#ffffff' : '#9b9b9b',
|
||||
}}
|
||||
>
|
||||
{this.context.t('rinkeby')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
key="goerli"
|
||||
closeMenu={() => this.props.hideNetworkDropdown()}
|
||||
onClick={() => this.handleClick('goerli')}
|
||||
style={dropdownMenuItemStyle}
|
||||
>
|
||||
{providerType === 'goerli' ? (
|
||||
<i className="fa fa-check" />
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#3099f2"
|
||||
isSelected={providerType === 'goerli'}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
style={{
|
||||
color: providerType === 'goerli' ? '#ffffff' : '#9b9b9b',
|
||||
}}
|
||||
>
|
||||
{this.context.t('goerli')}
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
{this.renderNetworkEntry('mainnet')}
|
||||
{this.renderNetworkEntry('ropsten')}
|
||||
{this.renderNetworkEntry('kovan')}
|
||||
{this.renderNetworkEntry('rinkeby')}
|
||||
{this.renderNetworkEntry('goerli')}
|
||||
|
||||
{this.renderCustomRpcList(rpcListDetail, this.props.provider)}
|
||||
<DropdownMenuItem
|
||||
closeMenu={() => this.props.hideNetworkDropdown()}
|
||||
@ -373,16 +297,18 @@ class NetworkDropdown extends Component {
|
||||
setSelectedSettingsRpcUrl('')
|
||||
setNetworksTabAddMode(true)
|
||||
}}
|
||||
style={dropdownMenuItemStyle}
|
||||
style={DROP_DOWN_MENU_ITEM_STYLE}
|
||||
>
|
||||
{activeNetwork === 'custom' ? (
|
||||
<i className="fa fa-check" />
|
||||
) : (
|
||||
<div className="network-check__transparent">✓</div>
|
||||
)}
|
||||
<NetworkDropdownIcon
|
||||
isSelected={activeNetwork === 'custom'}
|
||||
innerBorder="1px solid #9b9b9b"
|
||||
<ColorIndicator
|
||||
type={ColorIndicator.TYPES.FILLED}
|
||||
color={COLORS.TRANSPARENT}
|
||||
borderColor={COLORS.UI2}
|
||||
size={ColorIndicator.SIZES.LARGE}
|
||||
/>
|
||||
<span
|
||||
className="network-name-item"
|
||||
|
@ -1,22 +0,0 @@
|
||||
import assert from 'assert'
|
||||
import React from 'react'
|
||||
import { shallow } from 'enzyme'
|
||||
import NetworkDropdownIcon from '../components/network-dropdown-icon'
|
||||
|
||||
describe('Network Dropdown Icon', function () {
|
||||
it('adds style props based on props', function () {
|
||||
const wrapper = shallow(
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="red"
|
||||
isSelected={false}
|
||||
innerBorder="none"
|
||||
diameter="12"
|
||||
/>,
|
||||
)
|
||||
const styleProp = wrapper.find('.menu-icon-circle').children().prop('style')
|
||||
assert.strictEqual(styleProp.background, 'red')
|
||||
assert.strictEqual(styleProp.border, 'none')
|
||||
assert.strictEqual(styleProp.height, '12px')
|
||||
assert.strictEqual(styleProp.width, '12px')
|
||||
})
|
||||
})
|
@ -5,7 +5,7 @@ import thunk from 'redux-thunk'
|
||||
import { mountWithRouter } from '../../../../../../test/lib/render-helpers'
|
||||
import NetworkDropdown from '../network-dropdown'
|
||||
import { DropdownMenuItem } from '../components/dropdown'
|
||||
import NetworkDropdownIcon from '../components/network-dropdown-icon'
|
||||
import ColorIndicator from '../../../ui/color-indicator'
|
||||
|
||||
describe('Network Dropdown', function () {
|
||||
let wrapper
|
||||
@ -65,46 +65,41 @@ describe('Network Dropdown', function () {
|
||||
assert.strictEqual(wrapper.find(DropdownMenuItem).length, 8)
|
||||
})
|
||||
|
||||
it('checks background color for first NetworkDropdownIcon', function () {
|
||||
assert.strictEqual(
|
||||
wrapper.find(NetworkDropdownIcon).at(0).prop('backgroundColor'),
|
||||
'#29B6AF',
|
||||
) // Ethereum Mainnet Teal
|
||||
it('checks background color for first ColorIndicator', function () {
|
||||
const colorIndicator = wrapper.find(ColorIndicator).at(0)
|
||||
assert.strictEqual(colorIndicator.prop('color'), 'mainnet')
|
||||
assert.strictEqual(colorIndicator.prop('borderColor'), 'mainnet')
|
||||
})
|
||||
|
||||
it('checks background color for second NetworkDropdownIcon', function () {
|
||||
assert.strictEqual(
|
||||
wrapper.find(NetworkDropdownIcon).at(1).prop('backgroundColor'),
|
||||
'#ff4a8d',
|
||||
) // Ropsten Red
|
||||
it('checks background color for second ColorIndicator', function () {
|
||||
const colorIndicator = wrapper.find(ColorIndicator).at(1)
|
||||
assert.strictEqual(colorIndicator.prop('color'), 'ropsten')
|
||||
assert.strictEqual(colorIndicator.prop('borderColor'), 'ropsten')
|
||||
})
|
||||
|
||||
it('checks background color for third NetworkDropdownIcon', function () {
|
||||
assert.strictEqual(
|
||||
wrapper.find(NetworkDropdownIcon).at(2).prop('backgroundColor'),
|
||||
'#7057ff',
|
||||
) // Kovan Purple
|
||||
it('checks background color for third ColorIndicator', function () {
|
||||
const colorIndicator = wrapper.find(ColorIndicator).at(2)
|
||||
assert.strictEqual(colorIndicator.prop('color'), 'kovan')
|
||||
assert.strictEqual(colorIndicator.prop('borderColor'), 'kovan')
|
||||
})
|
||||
|
||||
it('checks background color for fourth NetworkDropdownIcon', function () {
|
||||
assert.strictEqual(
|
||||
wrapper.find(NetworkDropdownIcon).at(3).prop('backgroundColor'),
|
||||
'#f6c343',
|
||||
) // Rinkeby Yellow
|
||||
it('checks background color for fourth ColorIndicator', function () {
|
||||
const colorIndicator = wrapper.find(ColorIndicator).at(3)
|
||||
assert.strictEqual(colorIndicator.prop('color'), 'rinkeby')
|
||||
assert.strictEqual(colorIndicator.prop('borderColor'), 'rinkeby')
|
||||
})
|
||||
|
||||
it('checks background color for fifth NetworkDropdownIcon', function () {
|
||||
assert.strictEqual(
|
||||
wrapper.find(NetworkDropdownIcon).at(4).prop('backgroundColor'),
|
||||
'#3099f2',
|
||||
) // Goerli Blue
|
||||
it('checks background color for fifth ColorIndicator', function () {
|
||||
const colorIndicator = wrapper.find(ColorIndicator).at(4)
|
||||
assert.strictEqual(colorIndicator.prop('color'), 'goerli')
|
||||
assert.strictEqual(colorIndicator.prop('borderColor'), 'goerli')
|
||||
})
|
||||
|
||||
it('checks background color for sixth NetworkDropdownIcon', function () {
|
||||
assert.strictEqual(
|
||||
wrapper.find(NetworkDropdownIcon).at(5).prop('backgroundColor'),
|
||||
'#d6d9dc',
|
||||
) // "Custom network grey"
|
||||
it('checks background color for sixth ColorIndicator', function () {
|
||||
const colorIndicator = wrapper.find(ColorIndicator).at(5)
|
||||
const customNetworkGray = 'ui-2'
|
||||
assert.strictEqual(colorIndicator.prop('color'), customNetworkGray)
|
||||
assert.strictEqual(colorIndicator.prop('borderColor'), customNetworkGray)
|
||||
})
|
||||
|
||||
it('checks dropdown for frequestRPCList from state', function () {
|
||||
|
@ -1,3 +1 @@
|
||||
import NetworkDisplay from './network-display.container'
|
||||
|
||||
export default NetworkDisplay
|
||||
export { default } from './network-display'
|
||||
|
@ -1,66 +1,58 @@
|
||||
.network-display {
|
||||
&__container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 0 10px;
|
||||
border-radius: 4px;
|
||||
height: 25px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 0 10px;
|
||||
border-radius: 4px;
|
||||
min-height: 25px;
|
||||
cursor: pointer;
|
||||
|
||||
&--colored {
|
||||
background-color: lighten(rgb(125, 128, 130), 45%);
|
||||
}
|
||||
|
||||
&--mainnet {
|
||||
background-color: lighten($blue-lagoon, 68%);
|
||||
}
|
||||
|
||||
&--ropsten {
|
||||
background-color: lighten($crimson, 45%);
|
||||
}
|
||||
|
||||
&--kovan {
|
||||
background-color: lighten($purple, 65%);
|
||||
}
|
||||
|
||||
&--rinkeby {
|
||||
background-color: lighten($tulip-tree, 35%);
|
||||
}
|
||||
|
||||
&--goerli {
|
||||
background-color: lighten($dodger-blue, 35%);
|
||||
}
|
||||
&--disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&__name {
|
||||
@include H7;
|
||||
&--colored {
|
||||
background-color: lighten(rgb(125, 128, 130), 45%);
|
||||
}
|
||||
|
||||
padding-left: 5px;
|
||||
&--mainnet {
|
||||
background-color: lighten($blue-lagoon, 68%);
|
||||
}
|
||||
|
||||
&--ropsten {
|
||||
background-color: lighten($crimson, 45%);
|
||||
}
|
||||
|
||||
&--kovan {
|
||||
background-color: lighten($purple, 65%);
|
||||
}
|
||||
|
||||
&--rinkeby {
|
||||
background-color: lighten($tulip-tree, 35%);
|
||||
}
|
||||
|
||||
&--goerli {
|
||||
background-color: lighten($dodger-blue, 35%);
|
||||
}
|
||||
|
||||
|
||||
& .chip__label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
& .chip__left-icon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
& .chip__right-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-radius: 10px;
|
||||
|
||||
&--mainnet {
|
||||
background-color: $blue-lagoon;
|
||||
}
|
||||
|
||||
&--ropsten {
|
||||
background-color: $crimson;
|
||||
}
|
||||
|
||||
&--kovan {
|
||||
background-color: $purple;
|
||||
}
|
||||
|
||||
&--rinkeby {
|
||||
background-color: $tulip-tree;
|
||||
}
|
||||
|
||||
&--goerli {
|
||||
background-color: $dodger-blue;
|
||||
}
|
||||
height: 8px;
|
||||
width: 12px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
@ -1,71 +0,0 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
|
||||
|
||||
export default class NetworkDisplay extends Component {
|
||||
static defaultProps = {
|
||||
colored: true,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
networkNickname: PropTypes.string.isRequired,
|
||||
networkType: PropTypes.string.isRequired,
|
||||
colored: PropTypes.bool,
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
}
|
||||
|
||||
renderNetworkIcon() {
|
||||
const { networkType } = this.props
|
||||
|
||||
return networkType ? (
|
||||
<div
|
||||
className={`network-display__icon network-display__icon--${networkType}`}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
className="i fa fa-question-circle fa-med"
|
||||
style={{
|
||||
margin: '0 4px',
|
||||
color: 'rgb(125, 128, 130)',
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { colored, networkNickname, networkType } = this.props
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames('network-display__container', {
|
||||
'network-display__container--colored': colored,
|
||||
[`network-display__container--${networkType}`]:
|
||||
colored && networkType,
|
||||
})}
|
||||
>
|
||||
{networkType ? (
|
||||
<div
|
||||
className={`network-display__icon network-display__icon--${networkType}`}
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
className="i fa fa-question-circle fa-med"
|
||||
style={{
|
||||
margin: '0 4px',
|
||||
color: 'rgb(125, 128, 130)',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<div className="network-display__name">
|
||||
{networkType === NETWORK_TYPE_RPC && networkNickname
|
||||
? networkNickname
|
||||
: this.context.t(networkType)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import { connect } from 'react-redux'
|
||||
import NetworkDisplay from './network-display.component'
|
||||
|
||||
const mapStateToProps = ({
|
||||
metamask: {
|
||||
provider: { nickname, type },
|
||||
},
|
||||
}) => {
|
||||
return {
|
||||
networkNickname: nickname,
|
||||
networkType: type,
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(NetworkDisplay)
|
78
ui/app/components/app/network-display/network-display.js
Normal file
78
ui/app/components/app/network-display/network-display.js
Normal file
@ -0,0 +1,78 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { NETWORK_TYPE_RPC } from '../../../../../shared/constants/network'
|
||||
|
||||
import LoadingIndicator from '../../ui/loading-indicator'
|
||||
import ColorIndicator from '../../ui/color-indicator'
|
||||
import { COLORS, TYPOGRAPHY } from '../../../helpers/constants/design-system'
|
||||
import Chip from '../../ui/chip/chip'
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext'
|
||||
|
||||
export default function NetworkDisplay({
|
||||
colored,
|
||||
outline,
|
||||
iconClassName,
|
||||
disabled,
|
||||
onClick,
|
||||
}) {
|
||||
const { network, networkNickname, networkType } = useSelector((state) => ({
|
||||
network: state.metamask.network,
|
||||
networkNickname: state.metamask.provider.nickname,
|
||||
networkType: state.metamask.provider.type,
|
||||
}))
|
||||
const t = useI18nContext()
|
||||
|
||||
return (
|
||||
<Chip
|
||||
borderColor={outline ? COLORS.UI3 : COLORS.TRANSPARENT}
|
||||
onClick={onClick}
|
||||
leftIcon={
|
||||
<LoadingIndicator
|
||||
alt={t('attemptingConnect')}
|
||||
title={t('attemptingConnect')}
|
||||
isLoading={network === 'loading'}
|
||||
>
|
||||
<ColorIndicator
|
||||
color={networkType === NETWORK_TYPE_RPC ? COLORS.UI4 : networkType}
|
||||
size={ColorIndicator.SIZES.LARGE}
|
||||
type={ColorIndicator.TYPES.FILLED}
|
||||
iconClassName={
|
||||
networkType === NETWORK_TYPE_RPC ? 'fa fa-question' : undefined
|
||||
}
|
||||
/>
|
||||
</LoadingIndicator>
|
||||
}
|
||||
rightIcon={
|
||||
iconClassName && (
|
||||
<i className={classnames('network-display__icon', iconClassName)} />
|
||||
)
|
||||
}
|
||||
label={
|
||||
networkType === NETWORK_TYPE_RPC
|
||||
? networkNickname ?? t('privateNetwork')
|
||||
: t(networkType)
|
||||
}
|
||||
className={classnames('network-display', {
|
||||
'network-display--colored': colored,
|
||||
'network-display--disabled': disabled,
|
||||
[`network-display--${networkType}`]: colored && networkType,
|
||||
})}
|
||||
labelProps={{
|
||||
variant: TYPOGRAPHY.H7,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
NetworkDisplay.propTypes = {
|
||||
colored: PropTypes.bool,
|
||||
outline: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
iconClassName: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
}
|
||||
|
||||
NetworkDisplay.defaultProps = {
|
||||
colored: true,
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import React, { Component } from 'react'
|
||||
import classnames from 'classnames'
|
||||
import NetworkDropdownIcon from './dropdowns/components/network-dropdown-icon'
|
||||
|
||||
function NetworkIndicator({
|
||||
disabled,
|
||||
children,
|
||||
hoverText,
|
||||
onClick,
|
||||
providerName,
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={classnames('network-component pointer', {
|
||||
'network-component--disabled': disabled,
|
||||
'ethereum-network': providerName === 'mainnet',
|
||||
'ropsten-test-network': providerName === 'ropsten',
|
||||
'kovan-test-network': providerName === 'kovan',
|
||||
'rinkeby-test-network': providerName === 'rinkeby',
|
||||
'goerli-test-network': providerName === 'goerli',
|
||||
})}
|
||||
title={hoverText}
|
||||
onClick={(event) => {
|
||||
if (!disabled) {
|
||||
onClick(event)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="network-indicator">
|
||||
{children}
|
||||
<div className="network-indicator__down-arrow" />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
NetworkIndicator.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
hoverText: PropTypes.string,
|
||||
onClick: PropTypes.func,
|
||||
providerName: PropTypes.string,
|
||||
}
|
||||
|
||||
export default class Network extends Component {
|
||||
static contextTypes = {
|
||||
t: PropTypes.func,
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
network: PropTypes.string.isRequired,
|
||||
provider: PropTypes.shape({
|
||||
type: PropTypes.string,
|
||||
nickname: PropTypes.string,
|
||||
rpcUrl: PropTypes.string,
|
||||
}).isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
onClick: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { t } = this.context
|
||||
|
||||
const { disabled, network: networkNumber, onClick, provider } = this.props
|
||||
|
||||
let providerName, providerNick, providerUrl
|
||||
if (provider) {
|
||||
providerName = provider.type
|
||||
providerNick = provider.nickname || ''
|
||||
providerUrl = provider.rpcUrl
|
||||
}
|
||||
|
||||
switch (providerName) {
|
||||
case 'mainnet':
|
||||
return (
|
||||
<NetworkIndicator
|
||||
disabled={disabled}
|
||||
hoverText={t('mainnet')}
|
||||
onClick={onClick}
|
||||
providerName={providerName}
|
||||
>
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#038789"
|
||||
nonSelectBackgroundColor="#15afb2"
|
||||
loading={networkNumber === 'loading'}
|
||||
/>
|
||||
<div className="network-name">{t('mainnet')}</div>
|
||||
</NetworkIndicator>
|
||||
)
|
||||
|
||||
case 'ropsten':
|
||||
return (
|
||||
<NetworkIndicator
|
||||
disabled={disabled}
|
||||
hoverText={t('ropsten')}
|
||||
onClick={onClick}
|
||||
providerName={providerName}
|
||||
>
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#e91550"
|
||||
nonSelectBackgroundColor="#ec2c50"
|
||||
loading={networkNumber === 'loading'}
|
||||
/>
|
||||
<div className="network-name">{t('ropsten')}</div>
|
||||
</NetworkIndicator>
|
||||
)
|
||||
|
||||
case 'kovan':
|
||||
return (
|
||||
<NetworkIndicator
|
||||
disabled={disabled}
|
||||
hoverText={t('kovan')}
|
||||
onClick={onClick}
|
||||
providerName={providerName}
|
||||
>
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#690496"
|
||||
nonSelectBackgroundColor="#b039f3"
|
||||
loading={networkNumber === 'loading'}
|
||||
/>
|
||||
<div className="network-name">{t('kovan')}</div>
|
||||
</NetworkIndicator>
|
||||
)
|
||||
|
||||
case 'rinkeby':
|
||||
return (
|
||||
<NetworkIndicator
|
||||
disabled={disabled}
|
||||
hoverText={t('rinkeby')}
|
||||
onClick={onClick}
|
||||
providerName={providerName}
|
||||
>
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#ebb33f"
|
||||
nonSelectBackgroundColor="#ecb23e"
|
||||
loading={networkNumber === 'loading'}
|
||||
/>
|
||||
<div className="network-name">{t('rinkeby')}</div>
|
||||
</NetworkIndicator>
|
||||
)
|
||||
|
||||
case 'goerli':
|
||||
return (
|
||||
<NetworkIndicator
|
||||
disabled={disabled}
|
||||
hoverText={t('goerli')}
|
||||
onClick={onClick}
|
||||
providerName={providerName}
|
||||
>
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="#3099f2"
|
||||
nonSelectBackgroundColor="#ecb23e"
|
||||
loading={networkNumber === 'loading'}
|
||||
/>
|
||||
<div className="network-name">{t('goerli')}</div>
|
||||
</NetworkIndicator>
|
||||
)
|
||||
|
||||
default:
|
||||
return (
|
||||
<NetworkIndicator
|
||||
disabled={disabled}
|
||||
hoverText={providerNick || providerName || providerUrl || null}
|
||||
onClick={onClick}
|
||||
providerName={providerName}
|
||||
>
|
||||
{networkNumber === 'loading' ? (
|
||||
<span
|
||||
className="pointer network-loading-spinner"
|
||||
onClick={(event) => onClick(event)}
|
||||
>
|
||||
<img
|
||||
title={t('attemptingConnect')}
|
||||
src="images/loading.svg"
|
||||
alt={t('attemptingConnect')}
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
<i
|
||||
className="fa fa-question-circle fa-lg"
|
||||
style={{ color: 'rgb(125, 128, 130)' }}
|
||||
/>
|
||||
)}
|
||||
<div className="network-name">
|
||||
{providerNick || t('privateNetwork')}
|
||||
</div>
|
||||
</NetworkIndicator>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,2 @@
|
||||
export { default } from './permission-page-container.container'
|
||||
export { default as PermissionPageContainerContent } from './permission-page-container-content'
|
||||
export { default as PermissionPageContainerHeader } from './permission-page-container-header'
|
||||
|
@ -1 +0,0 @@
|
||||
export { default } from './permission-page-container-header.component'
|
@ -1,12 +0,0 @@
|
||||
import React from 'react'
|
||||
import NetworkDisplay from '../../network-display'
|
||||
|
||||
const ProviderPageContainerHeader = () => {
|
||||
return (
|
||||
<div className="provider-approval-container__header">
|
||||
<NetworkDisplay colored={false} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ProviderPageContainerHeader
|
@ -16,16 +16,10 @@
|
||||
.signature-request-header {
|
||||
flex: 1;
|
||||
|
||||
.network-display__container {
|
||||
.network-display {
|
||||
padding: 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.network-display__name {
|
||||
@include H7;
|
||||
|
||||
white-space: nowrap;
|
||||
font-weight: 500;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,16 @@ export default function Chip({
|
||||
rightIcon,
|
||||
onClick,
|
||||
}) {
|
||||
const onKeyPress = (event) => {
|
||||
if (event.key === 'Enter' && onClick) {
|
||||
onClick(event)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={onClick}
|
||||
onKeyPress={onKeyPress}
|
||||
className={classnames(className, 'chip', {
|
||||
'chip--with-left-icon': Boolean(leftIcon),
|
||||
'chip--with-right-icon': Boolean(rightIcon),
|
||||
|
1
ui/app/components/ui/loading-indicator/index.js
Normal file
1
ui/app/components/ui/loading-indicator/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './loading-indicator'
|
29
ui/app/components/ui/loading-indicator/loading-indicator.js
Normal file
29
ui/app/components/ui/loading-indicator/loading-indicator.js
Normal file
@ -0,0 +1,29 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default function LoadingIndicator({
|
||||
alt,
|
||||
title,
|
||||
isLoading,
|
||||
children = null,
|
||||
}) {
|
||||
return isLoading ? (
|
||||
<span className="loading-indicator">
|
||||
<img
|
||||
className="loading-indicator__spinner"
|
||||
alt={alt}
|
||||
title={title}
|
||||
src="images/loading.svg"
|
||||
/>
|
||||
</span>
|
||||
) : (
|
||||
children
|
||||
)
|
||||
}
|
||||
|
||||
LoadingIndicator.propTypes = {
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
alt: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
children: PropTypes.node,
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
.loading-indicator {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-left: 5px;
|
||||
|
||||
&__spinner {
|
||||
width: 27px;
|
||||
height: 26px;
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
left: -6px;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
@import 'identicon/index';
|
||||
@import 'info-tooltip/index';
|
||||
@import 'list-item/index';
|
||||
@import 'loading-indicator/loading-indicator';
|
||||
@import 'loading-screen/index';
|
||||
@import 'menu/menu';
|
||||
@import 'page-container/index';
|
||||
|
@ -41,42 +41,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.network-indicator {
|
||||
@include H8;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&__down-arrow {
|
||||
height: 8px;
|
||||
width: 12px;
|
||||
display: block;
|
||||
background-image: url(/images/icons/caret-down.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.fa-question-circle {
|
||||
font-size: $font-size-paragraph;
|
||||
margin: 0 4px 0 6px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.network-name {
|
||||
@include H7;
|
||||
|
||||
padding: 0 4px;
|
||||
flex: 1 1 auto;
|
||||
color: $tundora;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dropdown-menu-item .fa.delete {
|
||||
margin-right: 10px;
|
||||
display: none;
|
||||
@ -89,6 +53,10 @@
|
||||
.network-droppo {
|
||||
right: 2px;
|
||||
|
||||
.color-indicator {
|
||||
margin: 0 14px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 576px) {
|
||||
right: calc(((100% - 85vw) / 2) + 2px);
|
||||
}
|
||||
|
@ -142,8 +142,9 @@
|
||||
display: flex;
|
||||
padding: 13px 0 13px 17px;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
|
||||
.menu-icon-circle {
|
||||
.color-indicator {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ import {
|
||||
NETWORKS_ROUTE,
|
||||
NETWORKS_FORM_ROUTE,
|
||||
} from '../../../helpers/constants/routes'
|
||||
import NetworkDropdownIcon from '../../../components/app/dropdowns/components/network-dropdown-icon'
|
||||
import ColorIndicator from '../../../components/ui/color-indicator'
|
||||
import { COLORS } from '../../../helpers/constants/design-system'
|
||||
import NetworkForm from './network-form'
|
||||
|
||||
export default class NetworksTab extends PureComponent {
|
||||
@ -80,8 +81,6 @@ export default class NetworksTab extends PureComponent {
|
||||
isFullScreen,
|
||||
} = this.props
|
||||
const {
|
||||
border,
|
||||
iconColor,
|
||||
label,
|
||||
labelKey,
|
||||
rpcUrl,
|
||||
@ -111,9 +110,10 @@ export default class NetworksTab extends PureComponent {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor={iconColor || 'white'}
|
||||
innerBorder={border}
|
||||
<ColorIndicator
|
||||
color={labelKey}
|
||||
type={ColorIndicator.TYPES.FILLED}
|
||||
size={ColorIndicator.SIZES.LARGE}
|
||||
/>
|
||||
<div
|
||||
className={classnames('networks-tab__networks-list-name', {
|
||||
@ -155,9 +155,11 @@ export default class NetworksTab extends PureComponent {
|
||||
)}
|
||||
{networksTabIsInAddMode && (
|
||||
<div className="networks-tab__networks-list-item">
|
||||
<NetworkDropdownIcon
|
||||
backgroundColor="white"
|
||||
innerBorder="1px solid rgb(106, 115, 125)"
|
||||
<ColorIndicator
|
||||
type={ColorIndicator.TYPES.FILLED}
|
||||
color={COLORS.WHITE}
|
||||
borderColor={COLORS.UI4}
|
||||
size={ColorIndicator.SIZES.LARGE}
|
||||
/>
|
||||
<div className="networks-tab__networks-list-name networks-tab__networks-list-name--selected">
|
||||
{this.context.t('newNetwork')}
|
||||
|
Loading…
Reference in New Issue
Block a user