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

Address various UI styling issues (#6744)

* Add loading spinner to pending tx status label.

* Add border around account icon in top right

* Change style of settings toggle buttons; wrap with local components

* Eliminate large space after settings labels when no description

* Remove network form from advanced tab of settings

* Keep new account container height to contents when in full screen
This commit is contained in:
Dan J Miller 2019-07-08 15:28:35 -02:30 committed by GitHub
parent 6df65069a2
commit 32a3f5ad7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 155 additions and 175 deletions

View File

@ -237,9 +237,15 @@
"bytes": {
"message": "Bytes"
},
"off": {
"message": "Off"
},
"ok": {
"message": "Ok"
},
"on": {
"message": "On"
},
"optionalBlockExplorerUrl": {
"message": "Block Explorer URL (optional)"
},

View File

@ -463,13 +463,13 @@ describe('MetaMask', function () {
await advancedTab.click()
await delay(regularDelayMs)
const showConversionToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(7) .settings-page__content-item-col > div'))
const showConversionToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(6) .settings-page__content-item-col > div > div'))
await showConversionToggle.click()
const advancedGasTitle = await findElement(driver, By.xpath(`//span[contains(text(), 'Advanced gas controls')]`))
await driver.executeScript('arguments[0].scrollIntoView(true)', advancedGasTitle)
const advancedGasToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(5) .settings-page__content-item-col > div'))
const advancedGasToggle = await findElement(driver, By.css('.settings-page__content-row:nth-of-type(4) .settings-page__content-item-col > div > div'))
await advancedGasToggle.click()
windowHandles = await driver.getAllWindowHandles()
extension = windowHandles[0]

View File

@ -70,6 +70,7 @@ export default class AppHeader extends PureComponent {
<Identicon
address={selectedAddress}
diameter={32}
addBorder={true}
/>
</div>
)

View File

@ -77,3 +77,5 @@
@import 'gas-customization/index';
@import 'gas-customization/gas-price-button-group/index';
@import '../ui/toggle-button/index';

View File

@ -43,4 +43,10 @@
border: 1px solid $monzo;
}
}
&__pending-spinner {
height: 16px;
width: 16px;
margin-right: 6px;
}
}

View File

@ -2,6 +2,8 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import Tooltip from '../../ui/tooltip-v2'
import Spinner from '../../ui/spinner'
import {
UNAPPROVED_STATUS,
REJECTED_STATUS,
@ -51,6 +53,7 @@ export default class TransactionStatus extends PureComponent {
return (
<div className={classnames('transaction-status', className, statusToClassNameHash[statusKey])}>
{ statusToTextHash[statusKey] === 'pending' ? <Spinner className="transaction-status__pending-spinner" /> : null }
<Tooltip
position="top"
title={title}

View File

@ -16,6 +16,7 @@ const getStyles = diameter => (
export default class Identicon extends PureComponent {
static propTypes = {
addBorder: PropTypes.bool,
address: PropTypes.string,
className: PropTypes.string,
diameter: PropTypes.number,
@ -70,7 +71,7 @@ export default class Identicon extends PureComponent {
}
render () {
const { className, address, image, diameter, useBlockie } = this.props
const { className, address, image, diameter, useBlockie, addBorder } = this.props
if (image) {
return this.renderImage()
@ -83,9 +84,11 @@ export default class Identicon extends PureComponent {
return this.renderJazzicon()
}
return useBlockie
? this.renderBlockie()
: this.renderJazzicon()
return (
<div className={classnames({ 'identicon__address-wrapper': addBorder })}>
{ useBlockie ? this.renderBlockie() : this.renderJazzicon() }
</div>
)
}
return (

View File

@ -4,4 +4,17 @@
align-items: center;
justify-content: center;
overflow: hidden;
&__address-wrapper {
height: 40px;
width: 40px;
border-radius: 18px;
display: flex;
justify-content: center;
align-items: center;
border-style: solid;
border-radius: 50%;
border-width: 2px;
border-color: $curious-blue;
}
}

View File

@ -0,0 +1,2 @@
import ToggleButton from './toggle-button.component'
module.exports = ToggleButton

View File

@ -0,0 +1,14 @@
.toggle-button {
display: flex;
&__status-label {
font-family: Roboto;
font-style: normal;
font-weight: normal;
font-size: 16px;
line-height: 23px;
display: flex;
align-items: center;
text-transform: uppercase;
}
}

View File

@ -0,0 +1,75 @@
import React from 'react'
import PropTypes from 'prop-types'
import ReactToggleButton from 'react-toggle-button'
const trackStyle = {
width: '40px',
height: '24px',
padding: '0px',
borderRadius: '26px',
border: '2px solid rgb(3, 125, 214)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}
const offTrackStyle = {
...trackStyle,
border: '2px solid #8E8E8E',
}
const thumbStyle = {
width: '18px',
height: '18px',
display: 'flex',
boxShadow: 'none',
alignSelf: 'center',
borderRadius: '50%',
position: 'relative',
}
const colors = {
activeThumb: {
base: '#037DD6',
},
inactiveThumb: {
base: '#037DD6',
},
active: {
base: '#ffffff',
hover: '#ffffff',
},
inactive: {
base: '#DADADA',
hover: '#DADADA',
},
}
const ToggleButton = props => {
const { value, onToggle, offLabel, onLabel } = props
return (
<div className="toggle-button">
<ReactToggleButton
value={value}
onToggle={onToggle}
activeLabel=""
inactiveLabel=""
trackStyle={value ? trackStyle : offTrackStyle}
thumbStyle={thumbStyle}
thumbAnimateRange={[3, 18]}
colors={colors}
/>
<div className="toggle-button__status-label">{ value ? onLabel : offLabel }</div>
</div>
)
}
ToggleButton.propTypes = {
value: PropTypes.bool,
onToggle: PropTypes.func,
offLabel: PropTypes.string,
onLabel: PropTypes.string,
}
export default ToggleButton

View File

@ -3,7 +3,11 @@
background-color: #FFFFFF;
box-shadow: 0 0 7px 0 rgba(0,0,0,0.08);
z-index: 25;
height: 100%;
height: unset;
@media screen and (min-width: 576px) {
position: absolute;
}
&__header {
display: flex;

View File

@ -1,8 +1,7 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import validUrl from 'valid-url'
import { exportAsFile } from '../../../helpers/utils/util'
import ToggleButton from 'react-toggle-button'
import ToggleButton from '../../../components/ui/toggle-button'
import TextField from '../../../components/ui/text-field'
import Button from '../../../components/ui/button'
import { MOBILE_SYNC_ROUTE } from '../../../helpers/constants/routes'
@ -29,155 +28,7 @@ export default class AdvancedTab extends PureComponent {
setShowFiatConversionOnTestnetsPreference: PropTypes.func.isRequired,
}
state = {
newRpc: '',
chainId: '',
showOptions: false,
ticker: '',
nickname: '',
}
renderNewRpcUrl () {
const { t } = this.context
const { newRpc, chainId, ticker, nickname } = this.state
return (
<div className="settings-page__content-row">
<div className="settings-page__content-item">
<span>{ t('newNetwork') }</span>
</div>
<div className="settings-page__content-item">
<div className="settings-page__content-item-col">
<TextField
type="text"
id="new-rpc"
placeholder={t('rpcUrl')}
value={newRpc}
onChange={e => this.setState({ newRpc: e.target.value })}
onKeyPress={e => {
if (e.key === 'Enter') {
this.validateRpc(newRpc, chainId, ticker, nickname)
}
}}
fullWidth
margin="dense"
/>
<TextField
type="text"
id="chainid"
placeholder={t('optionalChainId')}
value={chainId}
onChange={e => this.setState({ chainId: e.target.value })}
onKeyPress={e => {
if (e.key === 'Enter') {
this.validateRpc(newRpc, chainId, ticker, nickname)
}
}}
style={{
display: this.state.showOptions ? null : 'none',
}}
fullWidth
margin="dense"
/>
<TextField
type="text"
id="ticker"
placeholder={t('optionalSymbol')}
value={ticker}
onChange={e => this.setState({ ticker: e.target.value })}
onKeyPress={e => {
if (e.key === 'Enter') {
this.validateRpc(newRpc, chainId, ticker, nickname)
}
}}
style={{
display: this.state.showOptions ? null : 'none',
}}
fullWidth
margin="dense"
/>
<TextField
type="text"
id="nickname"
placeholder={t('optionalNickname')}
value={nickname}
onChange={e => this.setState({ nickname: e.target.value })}
onKeyPress={e => {
if (e.key === 'Enter') {
this.validateRpc(newRpc, chainId, ticker, nickname)
}
}}
style={{
display: this.state.showOptions ? null : 'none',
}}
fullWidth
margin="dense"
/>
<div className="flex-row flex-align-center space-between">
<span className="settings-tab__advanced-link"
onClick={e => {
e.preventDefault()
this.setState({ showOptions: !this.state.showOptions })
}}
>
{ t(this.state.showOptions ? 'hideAdvancedOptions' : 'showAdvancedOptions') }
</span>
<button
className="button btn-primary settings-tab__rpc-save-button"
onClick={e => {
e.preventDefault()
this.validateRpc(newRpc, chainId, ticker, nickname)
}}
>
{ t('save') }
</button>
</div>
</div>
</div>
</div>
)
}
validateRpc (newRpc, chainId, ticker = 'ETH', nickname) {
const { setRpcTarget, displayWarning } = this.props
if (validUrl.isWebUri(newRpc)) {
this.context.metricsEvent({
eventOpts: {
category: 'Settings',
action: 'Custom RPC',
name: 'Success',
},
customVariables: {
networkId: newRpc,
chainId,
},
})
if (!!chainId && Number.isNaN(parseInt(chainId))) {
return displayWarning(`${this.context.t('invalidInput')} chainId`)
}
setRpcTarget(newRpc, chainId, ticker, nickname)
} else {
this.context.metricsEvent({
eventOpts: {
category: 'Settings',
action: 'Custom RPC',
name: 'Error',
},
customVariables: {
networkId: newRpc,
chainId,
},
})
const appendedRpc = `http://${newRpc}`
if (validUrl.isWebUri(appendedRpc)) {
displayWarning(this.context.t('uriErrorMsg'))
} else {
displayWarning(this.context.t('invalidRPC'))
}
}
}
state = { autoLogoutTimeLimit: this.props.autoLogoutTimeLimit }
renderMobileSync () {
const { t } = this.context
@ -293,8 +144,8 @@ export default class AdvancedTab extends PureComponent {
<ToggleButton
value={sendHexData}
onToggle={value => setHexDataFeatureFlag(!value)}
activeLabel=""
inactiveLabel=""
offLabel={t('off')}
onLabel={t('on')}
/>
</div>
</div>
@ -319,8 +170,8 @@ export default class AdvancedTab extends PureComponent {
<ToggleButton
value={advancedInlineGas}
onToggle={value => setAdvancedInlineGasFeatureFlag(!value)}
activeLabel=""
inactiveLabel=""
offLabel={t('off')}
onLabel={t('on')}
/>
</div>
</div>
@ -348,8 +199,8 @@ export default class AdvancedTab extends PureComponent {
<ToggleButton
value={showFiatInTestnets}
onToggle={value => setShowFiatConversionOnTestnetsPreference(!value)}
activeLabel=""
inactiveLabel=""
offLabel={t('off')}
onLabel={t('on')}
/>
</div>
</div>
@ -407,7 +258,6 @@ export default class AdvancedTab extends PureComponent {
{ warning && <div className="settings-tab__error">{ warning }</div> }
{ this.renderStateLogs() }
{ this.renderMobileSync() }
{ this.renderNewRpcUrl() }
{ this.renderResetAccount() }
{ this.renderAdvancedGasInputInline() }
{ this.renderHexDataOptIn() }

View File

@ -16,7 +16,7 @@ describe('AdvancedTab Component', () => {
}
)
assert.equal(root.find('.settings-page__content-row').length, 8)
assert.equal(root.find('.settings-page__content-row').length, 7)
})
it('should update autoLogoutTimeLimit', () => {

View File

@ -142,7 +142,7 @@
min-width: 0;
display: flex;
flex-direction: column;
min-height: 71px;
margin-bottom: 20px;
@media screen and (max-width: 575px) {
height: initial;

View File

@ -1,7 +1,7 @@
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { exportAsFile } from '../../../helpers/utils/util'
import ToggleButton from 'react-toggle-button'
import ToggleButton from '../../../components/ui/toggle-button'
import { REVEAL_SEED_ROUTE } from '../../../helpers/constants/routes'
import Button from '../../../components/ui/button'
@ -140,8 +140,8 @@ export default class SecurityTab extends PureComponent {
<ToggleButton
value={privacyMode}
onToggle={value => setPrivacyMode(!value)}
activeLabel=""
inactiveLabel=""
offLabel={t('off')}
onLabel={t('on')}
/>
</div>
</div>
@ -166,8 +166,8 @@ export default class SecurityTab extends PureComponent {
<ToggleButton
value={participateInMetaMetrics}
onToggle={value => setParticipateInMetaMetrics(!value)}
activeLabel=""
inactiveLabel=""
offLabel={t('off')}
onLabel={t('on')}
/>
</div>
</div>

View File

@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import infuraCurrencies from '../../../helpers/constants/infura-conversion.json'
import SimpleDropdown from '../../../components/app/dropdowns/simple-dropdown'
import ToggleButton from 'react-toggle-button'
import ToggleButton from '../../../components/ui/toggle-button'
import locales from '../../../../../app/_locales/index.json'
const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
@ -105,6 +105,7 @@ export default class SettingsTab extends PureComponent {
renderBlockieOptIn () {
const { t } = this.context
const { useBlockie, setUseBlockie } = this.props
return (
@ -117,8 +118,8 @@ export default class SettingsTab extends PureComponent {
<ToggleButton
value={useBlockie}
onToggle={value => setUseBlockie(!value)}
activeLabel=""
inactiveLabel=""
offLabel={t('off')}
onLabel={t('on')}
/>
</div>
</div>