simplify tx confirmations display (#3559)
* Hash component * DRY code by using Hash component * TxHash component: show hash inline * TxHash component: less verbose confirmations display * TxHash component: rename ui/Hash to ui/ShortenedHash * signer: center message in TransactionFinished * style fixes
This commit is contained in:
parent
eec99ebad8
commit
2b178d8233
@ -18,6 +18,8 @@ import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import ShortenedHash from '../ShortenedHash';
|
||||
|
||||
const defaultName = 'UNNAMED';
|
||||
|
||||
class IdentityName extends Component {
|
||||
@ -41,7 +43,7 @@ class IdentityName extends Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
const addressFallback = shorten ? this.formatHash(address) : address;
|
||||
const addressFallback = shorten ? (<ShortenedHash data={ address } />) : address;
|
||||
const fallback = unknown ? defaultName : addressFallback;
|
||||
const isUuid = hasAccount && account.name === account.uuid;
|
||||
const displayName = (name && name.toUpperCase().trim()) ||
|
||||
@ -55,14 +57,6 @@ class IdentityName extends Component {
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
formatHash (hash) {
|
||||
if (!hash || hash.length <= 16) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
return `${hash.substr(2, 6)}...${hash.slice(-6)}`;
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps (state) {
|
||||
|
17
js/src/ui/ShortenedHash/index.js
Normal file
17
js/src/ui/ShortenedHash/index.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './shortenedHash';
|
21
js/src/ui/ShortenedHash/shortenedHash.css
Normal file
21
js/src/ui/ShortenedHash/shortenedHash.css
Normal file
@ -0,0 +1,21 @@
|
||||
/* Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.hash {
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
}
|
41
js/src/ui/ShortenedHash/shortenedHash.js
Normal file
41
js/src/ui/ShortenedHash/shortenedHash.js
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import styles from './shortenedHash.css';
|
||||
|
||||
export default class ShortenedHash extends Component {
|
||||
static propTypes = {
|
||||
data: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const { data } = this.props;
|
||||
|
||||
let shortened = data.toLowerCase();
|
||||
if (shortened.slice(0, 2) === '0x') {
|
||||
shortened = shortened.slice(2);
|
||||
}
|
||||
if (shortened.length > (6 + 6)) {
|
||||
shortened = shortened.slice(0, 6) + '…' + shortened.slice(-6);
|
||||
}
|
||||
|
||||
return (
|
||||
<abbr className={ styles.hash } title={ shortened }>{ shortened }</abbr>
|
||||
);
|
||||
}
|
||||
}
|
@ -15,19 +15,12 @@
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.details {
|
||||
}
|
||||
|
||||
.header {
|
||||
}
|
||||
|
||||
.hash {
|
||||
padding-top: 1em;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.confirm {
|
||||
padding-top: 1em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,9 @@ import React, { Component, PropTypes } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { LinearProgress } from 'material-ui';
|
||||
|
||||
import { txLink } from '../../3rdparty/etherscan/links';
|
||||
import ShortenedHash from '../ShortenedHash';
|
||||
|
||||
import styles from './txHash.css';
|
||||
|
||||
@ -62,22 +64,23 @@ class TxHash extends Component {
|
||||
|
||||
render () {
|
||||
const { hash, isTest, summary } = this.props;
|
||||
let header = null;
|
||||
|
||||
if (!summary) {
|
||||
header = (
|
||||
<div className={ styles.header }>
|
||||
The transaction has been posted to the network with a transaction hash of
|
||||
</div>
|
||||
);
|
||||
const link = (
|
||||
<a href={ txLink(hash, isTest) } target='_blank'>
|
||||
<ShortenedHash data={ hash } />
|
||||
</a>
|
||||
);
|
||||
|
||||
let header = (
|
||||
<p>The transaction has been posted to the network, with a hash of { link }.</p>
|
||||
);
|
||||
if (summary) {
|
||||
header = (<p>{ link }</p>);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.details }>
|
||||
<div>
|
||||
{ header }
|
||||
<div className={ styles.hash }>
|
||||
<a href={ txLink(hash, isTest) } target='_blank'>{ hash }</a>
|
||||
</div>
|
||||
{ this.renderConfirmations() }
|
||||
</div>
|
||||
);
|
||||
@ -87,17 +90,29 @@ class TxHash extends Component {
|
||||
const { maxConfirmations } = this.props;
|
||||
const { blockNumber, transaction } = this.state;
|
||||
|
||||
let txBlock = 'Pending';
|
||||
let confirmations = 'No';
|
||||
let value = 0;
|
||||
|
||||
if (transaction && transaction.blockNumber && transaction.blockNumber.gt(0)) {
|
||||
const num = blockNumber.minus(transaction.blockNumber).plus(1);
|
||||
txBlock = `#${transaction.blockNumber.toFormat(0)}`;
|
||||
confirmations = num.toFormat(0);
|
||||
value = num.gt(maxConfirmations) ? maxConfirmations : num.toNumber();
|
||||
if (!(transaction && transaction.blockNumber && transaction.blockNumber.gt(0))) {
|
||||
return (
|
||||
<div className={ styles.confirm }>
|
||||
<LinearProgress
|
||||
className={ styles.progressbar }
|
||||
color='white'
|
||||
mode='indeterminate'
|
||||
/>
|
||||
<div className={ styles.progressinfo }>waiting for confirmations</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const confirmations = blockNumber.minus(transaction.blockNumber).plus(1);
|
||||
const value = Math.min(confirmations.toNumber(), maxConfirmations);
|
||||
let count;
|
||||
if (confirmations.gt(maxConfirmations)) {
|
||||
count = confirmations.toFormat(0);
|
||||
} else {
|
||||
count = confirmations.toFormat(0) + `/${maxConfirmations}`;
|
||||
}
|
||||
const unit = value === 1 ? 'confirmation' : 'confirmations';
|
||||
|
||||
return (
|
||||
<div className={ styles.confirm }>
|
||||
<LinearProgress
|
||||
@ -106,9 +121,10 @@ class TxHash extends Component {
|
||||
max={ maxConfirmations }
|
||||
value={ value }
|
||||
color='white'
|
||||
mode='determinate' />
|
||||
mode='determinate'
|
||||
/>
|
||||
<div className={ styles.progressinfo }>
|
||||
{ txBlock } / { confirmations } confirmations
|
||||
<abbr title={ `block #${blockNumber.toFormat(0)}` }>{ count } { unit }</abbr>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -37,6 +37,7 @@ import Modal, { Busy as BusyStep, Completed as CompletedStep } from './Modal';
|
||||
import muiTheme from './Theme';
|
||||
import Page from './Page';
|
||||
import ParityBackground from './ParityBackground';
|
||||
import ShortenedHash from './ShortenedHash';
|
||||
import SignerIcon from './SignerIcon';
|
||||
import Tags from './Tags';
|
||||
import Tooltips, { Tooltip } from './Tooltips';
|
||||
@ -79,6 +80,7 @@ export {
|
||||
Page,
|
||||
ParityBackground,
|
||||
RadioButtons,
|
||||
ShortenedHash,
|
||||
SignerIcon,
|
||||
Tags,
|
||||
Tooltip,
|
||||
|
@ -19,6 +19,7 @@ import React, { Component, PropTypes } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { IdentityIcon, IdentityName, MethodDecoding } from '../../../../ui';
|
||||
import ShortenedHash from '../../../../ui/ShortenedHash';
|
||||
import { txLink, addressLink } from '../../../../3rdparty/etherscan/links';
|
||||
|
||||
import styles from '../transactions.css';
|
||||
@ -95,7 +96,7 @@ export default class Transaction extends Component {
|
||||
href={ txLink(transaction.hash, isTest) }
|
||||
target='_blank'
|
||||
>
|
||||
{ this.formatHash(transaction.hash) }
|
||||
<ShortenedHash data={ transaction.hash } />
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
@ -150,14 +151,6 @@ export default class Transaction extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
formatHash (hash) {
|
||||
if (!hash || hash.length <= 16) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
return `${hash.substr(2, 6)}...${hash.slice(-6)}`;
|
||||
}
|
||||
|
||||
formatNumber (number) {
|
||||
return new BigNumber(number).toFormat();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import moment from 'moment';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { IdentityIcon, IdentityName, Input, InputAddress } from '../../../../ui';
|
||||
import ShortenedHash from '../../../../ui/ShortenedHash';
|
||||
import { txLink } from '../../../../3rdparty/etherscan/links';
|
||||
|
||||
import styles from '../../contract.css';
|
||||
@ -71,7 +72,7 @@ export default class Event extends Component {
|
||||
<div className={ styles.eventType }>
|
||||
{ event.type }({ keys })
|
||||
</div>
|
||||
<a href={ url } target='_blank'>{ this.formatHash(event.transactionHash) }</a>
|
||||
<a href={ url } target='_blank'><ShortenedHash data={ event.transactionHash } /></a>
|
||||
</td>
|
||||
<td className={ styles.eventDetails }>
|
||||
<div className={ styles.eventParams }>
|
||||
@ -82,14 +83,6 @@ export default class Event extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
formatHash (hash) {
|
||||
if (!hash || hash.length <= 16) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
return `${hash.substr(2, 6)}...${hash.slice(-6)}`;
|
||||
}
|
||||
|
||||
renderAddressName (address, withName = true) {
|
||||
return (
|
||||
<span className={ styles.eventAddress }>
|
||||
|
Loading…
Reference in New Issue
Block a user