Display 0x00..00 as null (#3950)

* Display 0x00..00 as null (custom black icon)

* rendering test for null
This commit is contained in:
Jaco Greeff 2016-12-22 18:30:59 +01:00 committed by Gav Wood
parent f0387c33c6
commit 077069c452
5 changed files with 43 additions and 15 deletions

View File

@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -62,6 +63,7 @@ class InputAddress extends Component {
classes.push(!icon ? styles.inputEmpty : styles.input); classes.push(!icon ? styles.inputEmpty : styles.input);
const containerClasses = [ styles.container ]; const containerClasses = [ styles.container ];
const nullName = new BigNumber(value).eq(0) ? 'null' : null;
if (small) { if (small) {
containerClasses.push(styles.small); containerClasses.push(styles.small);
@ -82,7 +84,7 @@ class InputAddress extends Component {
value={ value={
text && account text && account
? account.name ? account.name
: value : (nullName || value)
} /> } />
{ icon } { icon }
</div> </div>

View File

@ -16,6 +16,7 @@
import AddIcon from 'material-ui/svg-icons/content/add'; import AddIcon from 'material-ui/svg-icons/content/add';
import CancelIcon from 'material-ui/svg-icons/content/clear'; import CancelIcon from 'material-ui/svg-icons/content/clear';
import ContractIcon from 'material-ui/svg-icons/action/code';
import DoneIcon from 'material-ui/svg-icons/action/done-all'; import DoneIcon from 'material-ui/svg-icons/action/done-all';
import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back'; import PrevIcon from 'material-ui/svg-icons/navigation/arrow-back';
import NextIcon from 'material-ui/svg-icons/navigation/arrow-forward'; import NextIcon from 'material-ui/svg-icons/navigation/arrow-forward';
@ -24,6 +25,7 @@ import SnoozeIcon from 'material-ui/svg-icons/av/snooze';
export { export {
AddIcon, AddIcon,
CancelIcon, CancelIcon,
ContractIcon,
DoneIcon, DoneIcon,
PrevIcon, PrevIcon,
NextIcon, NextIcon,

View File

@ -14,12 +14,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import ContractIcon from 'material-ui/svg-icons/action/code';
import { createIdentityImg } from '~/api/util/identity'; import { createIdentityImg } from '~/api/util/identity';
import ContractIcon from '../Icons';
import styles from './identityIcon.css'; import styles from './identityIcon.css';
@ -108,9 +109,20 @@ class IdentityIcon extends Component {
<ContractIcon <ContractIcon
className={ classes } className={ classes }
style={ { style={ {
width: size, background: '#eee',
height: size, height: size,
background: '#eee' width: size
} } />
);
} else if (new BigNumber(address).eq(0)) {
return (
<div
className={ classes }
style={ {
background: '#333',
display: 'inline-block',
height: size,
width: size
} } /> } } />
); );
} }

View File

@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -24,35 +25,41 @@ const defaultName = 'UNNAMED';
class IdentityName extends Component { class IdentityName extends Component {
static propTypes = { static propTypes = {
className: PropTypes.string,
address: PropTypes.string,
accountsInfo: PropTypes.object, accountsInfo: PropTypes.object,
tokens: PropTypes.object, address: PropTypes.string,
className: PropTypes.string,
empty: PropTypes.bool, empty: PropTypes.bool,
name: PropTypes.string,
shorten: PropTypes.bool, shorten: PropTypes.bool,
unknown: PropTypes.bool, tokens: PropTypes.object,
name: PropTypes.string unknown: PropTypes.bool
} }
render () { render () {
const { address, accountsInfo, tokens, empty, name, shorten, unknown, className } = this.props; const { address, accountsInfo, className, empty, name, shorten, tokens, unknown } = this.props;
const account = accountsInfo[address] || tokens[address]; const account = accountsInfo[address] || tokens[address];
if (!account && empty) { if (!account && empty) {
return null; return null;
} }
const addressFallback = shorten ? (<ShortenedHash data={ address } />) : address; const nullName = new BigNumber(address).eq(0) ? 'null' : null;
const addressFallback = nullName || (shorten ? (<ShortenedHash data={ address } />) : address);
const fallback = unknown ? defaultName : addressFallback; const fallback = unknown ? defaultName : addressFallback;
const isUuid = account && account.name === account.uuid; const isUuid = account && account.name === account.uuid;
const displayName = (name && name.toUpperCase().trim()) || const displayName = (name && name.toUpperCase().trim()) ||
(account && !isUuid (account && !isUuid
? account.name.toUpperCase().trim() ? account.name.toUpperCase().trim()
: fallback); : fallback
);
return ( return (
<span className={ className }> <span className={ className }>
{ displayName && displayName.length ? displayName : fallback } {
displayName && displayName.length
? displayName
: fallback
}
</span> </span>
); );
} }

View File

@ -23,6 +23,7 @@ import IdentityName from './identityName';
const ADDR_A = '0x123456789abcdef0123456789A'; const ADDR_A = '0x123456789abcdef0123456789A';
const ADDR_B = '0x123456789abcdef0123456789B'; const ADDR_B = '0x123456789abcdef0123456789B';
const ADDR_C = '0x123456789abcdef0123456789C'; const ADDR_C = '0x123456789abcdef0123456789C';
const ADDR_NULL = '0x0000000000000000000000000000000000000000';
const STORE = { const STORE = {
dispatch: sinon.stub(), dispatch: sinon.stub(),
subscribe: sinon.stub(), subscribe: sinon.stub(),
@ -52,7 +53,7 @@ function render (props) {
describe('ui/IdentityName', () => { describe('ui/IdentityName', () => {
describe('rendering', () => { describe('rendering', () => {
it('renders defaults', () => { it('renders defaults', () => {
expect(render()).to.be.ok; expect(render({ address: ADDR_A })).to.be.ok;
}); });
describe('account not found', () => { describe('account not found', () => {
@ -71,6 +72,10 @@ describe('ui/IdentityName', () => {
it('renders unknown with flag', () => { it('renders unknown with flag', () => {
expect(render({ address: ADDR_C, unknown: true }).text()).to.equal('UNNAMED'); expect(render({ address: ADDR_C, unknown: true }).text()).to.equal('UNNAMED');
}); });
it('renders 0x000...000 as null', () => {
expect(render({ address: ADDR_NULL }).text()).to.equal('null');
});
}); });
}); });
}); });