refactored PendingTransactions

pull/282/head
Szymon Lesisz 6 years ago
parent 24524d7445
commit 7f517041b1

@ -0,0 +1,104 @@
/* @flow */
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import colors from 'config/colors';
import Link from 'components/Link';
import type { Transaction, Network } from 'flowtype';
type Props = {
tx: Transaction,
network: Network,
};
const Wrapper = styled.div`
border-bottom: 1px solid ${colors.DIVIDER};
padding: 14px 0;
display: flex;
flex-direction: row;
&:last-child {
border-bottom: 0px;
}
`;
const Addresses = styled.div`
flex: 1;
`;
const Address = styled.div`
word-break: break-all;
padding: 2px 0px;
&:first-child {
padding-top: 0px;
}
&:last-child {
padding-bottom: 0px;
}
`;
const Date = styled(Link)`
font-size: 12px;
line-height: 18px;
padding-right: 8px;
border-bottom: 0px;
`;
const Value = styled.div`
padding-left: 8px;
white-space: nowrap;
text-align: right;
color: ${colors.GREEN_SECONDARY};
&.send {
color: ${colors.ERROR_PRIMARY};
}
`;
const Amount = styled.div`
border: 1px;
`;
const Fee = styled.div`
border: 1px;
`;
const TransactionItem = ({
tx,
network,
}: Props) => {
const url = `${network.explorer.tx}${tx.hash}`;
const date = typeof tx.timestamp === 'string' && tx.confirmations > 0 ? tx.timestamp : undefined; // TODO: format date
const addresses = (tx.type === 'send' ? tx.outputs : tx.inputs).reduce((arr, item) => arr.concat(item.addresses), []);
const currency = tx.currency || tx.network;
const isToken = currency !== tx.network;
const amount = isToken ? `${tx.amount} ${currency}` : `${tx.total} ${network.symbol}`;
const fee = isToken && tx.type === 'send' ? `${tx.fee} ${network.symbol}` : undefined;
const operation = tx.type === 'send' ? '-' : '+';
return (
<Wrapper>
{ date && (<Date href={url} isGray>{ date }</Date>)}
<Addresses>
{ addresses.map(addr => (<Address key={addr}>{addr}</Address>)) }
{ tx.confirmations <= 0 && (
<Date href={url} isGray>Transaction hash: {tx.hash}</Date>
)}
</Addresses>
<Value className={tx.type}>
<Amount>{operation}{amount}</Amount>
{ fee && (<Fee>{operation}{fee}</Fee>) }
</Value>
</Wrapper>
);
};
TransactionItem.propTypes = {
tx: PropTypes.object.isRequired,
network: PropTypes.object.isRequired,
};
export default TransactionItem;

@ -1,19 +1,17 @@
/* @flow */
import React, { PureComponent } from 'react';
import React from 'react';
import styled from 'styled-components';
import colors from 'config/colors';
import ColorHash from 'color-hash';
import { H2 } from 'components/Heading';
import Link from 'components/Link';
import ScaleText from 'react-scale-text';
import Transaction from 'components/Transaction';
import type { Network } from 'reducers/LocalStorageReducer';
import type { Token } from 'reducers/TokensReducer';
import type { BaseProps } from '../../index';
import testData from './test.data';
type Props = {
pending: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'pending'>,
tokens: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'tokens'>,
network: Network
}
@ -22,153 +20,18 @@ const Wrapper = styled.div`
border-top: 1px solid ${colors.DIVIDER};
`;
const StyledLink = styled(Link)`
text-decoration: none;
`;
const TransactionWrapper = styled.div`
border-bottom: 1px solid ${colors.DIVIDER};
padding: 14px 0;
display: flex;
flex-direction: row;
align-items: center;
&:last-child {
border-bottom: 0px;
}
`;
const TransactionIcon = styled.div`
padding: 6px;
margin-right: 10px;
width: 36px;
height: 36px;
border-radius: 50%;
line-height: 25px;
text-transform: uppercase;
user-select: none;
text-align: center;
color: ${props => props.textColor};
background: ${props => props.background};
border-color: ${props => props.borderColor};
&:before {
content: ${props => props.color};
}
`;
const P = styled.p``;
const TransactionName = styled.div`
flex: 1;
`;
const TransactionAmount = styled.div`
color: colors.TEXT_SECONDARY;
`;
class PendingTransactions extends PureComponent<Props> {
getPendingTransactions() {
return this.props.pending.filter(tx => !tx.rejected);
}
getTransactionIconColors(tx: any) {
let iconColors = {
textColor: '#fff',
background: '#000',
borderColor: '#000',
};
const bgColorFactory = new ColorHash({ lightness: 0.7 });
const textColorFactory = new ColorHash();
const isSmartContractTx = tx.currency !== this.props.network.symbol;
if (isSmartContractTx) {
const token: ?Token = this.findTransactionToken(tx.currency);
if (!token) {
iconColors = {
textColor: '#ffffff',
background: '#000000',
borderColor: '#000000',
};
} else {
const bgColor: string = bgColorFactory.hex(token.name);
iconColors = {
textColor: textColorFactory.hex(token.name),
background: bgColor,
borderColor: bgColor,
};
}
} else {
iconColors = {
textColor: textColorFactory.hex(tx.network),
background: bgColorFactory.hex(tx.network),
borderColor: bgColorFactory.hex(tx.network),
};
}
return iconColors;
}
getTransactionSymbol(tx: any) {
let { symbol } = this.props.network;
const isSmartContractTx = tx.currency !== this.props.network.symbol;
if (isSmartContractTx) {
const token: ?Token = this.findTransactionToken(tx.currency);
symbol = token ? token.symbol.toUpperCase() : 'Unknown';
}
return symbol;
}
getTransactionName(tx: any) {
let { name } = this.props.network;
const isSmartContractTx = tx.currency !== this.props.network.symbol;
if (isSmartContractTx) {
const token: ?Token = this.findTransactionToken(tx.currency);
name = token ? token.symbol.toUpperCase() : 'Unknown';
}
return name;
}
findTransactionToken(transactionCurrency: string) {
return this.props.tokens.find(t => t.symbol === transactionCurrency);
}
render() {
return (
<Wrapper>
<H2>Pending transactions</H2>
{this.getPendingTransactions().map(tx => (
<TransactionWrapper
key={tx.hash}
>
<TransactionIcon
textColor={() => this.getTransactionIconColors(tx).textColor}
background={() => this.getTransactionIconColors(tx).background}
borderColor={() => this.getTransactionIconColors(tx).borderColor}
>
<ScaleText widthOnly>
<P>{this.getTransactionSymbol(tx)}</P>
</ScaleText>
</TransactionIcon>
<TransactionName>
<StyledLink
href={`${this.props.network.explorer.tx}${tx.hash}`}
isGray
>
{this.getTransactionName(tx)}
</StyledLink>
</TransactionName>
<TransactionAmount>
{tx.currency !== this.props.network.symbol ? tx.amount : tx.total} {this.getTransactionSymbol(tx)}
</TransactionAmount>
</TransactionWrapper>
))}
</Wrapper>
);
}
}
const PendingTransactions = (props: Props) => {
// const pending = props.pending.filter(tx => !tx.rejected).concat(testData);
const pending = props.pending.filter(tx => !tx.rejected);
return (
<Wrapper>
<H2>Pending transactions</H2>
{pending.map(tx => (
<Transaction key={tx.hash} network={props.network} tx={tx} />
))}
</Wrapper>
);
};
export default PendingTransactions;

@ -0,0 +1,99 @@
export default [
{
type: 'recv',
timestamp: '16:20',
address: 'a',
deviceState: 'a',
status: 'pending',
confirmations: 0,
inputs: [
{
addresses: ['in1'],
},
{
addresses: ['in2'],
},
],
outputs: [
{
addresses: ['out1', 'out2'],
},
],
sequence: 1,
hash: '1234',
network: 'eth',
currency: 'eth',
amount: '0.001',
total: '0.001001',
fee: '0.000001',
},
{
type: 'send',
address: 'a',
deviceState: 'a',
confirmations: 0,
status: 'pending',
inputs: [
{
addresses: ['in1', 'in2'],
},
],
outputs: [
{
addresses: ['out1'],
},
],
sequence: 1,
hash: '12345',
network: 'eth',
currency: 'T01',
amount: '0.001',
total: '0.001001',
fee: '0.000001',
},
{
address: '0x73d0385F4d8E00C5e6504C6030F47BF6212736A8',
amount: '1',
confirmations: 0,
currency: 'T01',
deviceState: '4058d01c7c964787b7d06f0f32ce229088e123a042bf95aad658f1b1b99c73fc',
fee: '0.0002',
hash: '0xbf6ac83bdf29abacbca91cd4100ddd5cd8de16e72911ea7d1daec17ccbfc6099',
inputs: [{
addresses: ['0x73d0385F4d8E00C5e6504C6030F47BF6212736A8'],
}],
network: 'trop',
outputs: [{
addresses: ['0xFA01a39f8Abaeb660c3137f14A310d0b414b2A15'],
}],
sequence: 249,
status: 'pending',
timestamp: '',
total: '0.0002',
type: 'send',
},
{
address: '0x73d0385F4d8E00C5e6504C6030F47BF6212736A8',
amount: '1',
confirmations: 0,
currency: 'trop',
deviceState: '4058d01c7c964787b7d06f0f32ce229088e123a042bf95aad658f1b1b99c73fc',
fee: '0.0002',
hash: '0xbf6ac83bdf29abacbca91cd4100ddd5cd8de16e72911ea7d1daec17ccbfc6099',
inputs: [{
addresses: ['0x73d0385F4d8E00C5e6504C6030F47BF6212736A8'],
}],
network: 'trop',
outputs: [{
addresses: ['0xFA01a39f8Abaeb660c3137f14A310d0b414b2A15'],
}],
sequence: 249,
status: 'pending',
timestamp: '',
total: '0.0002',
type: 'send',
},
];
Loading…
Cancel
Save