1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-30 20:28:09 +00:00

t pushMerge branch 'styled-components-refactor' of github.com:satoshilabs/trezor-wallet into styled-components-refactor

This commit is contained in:
Vladimir Volek 2018-09-05 14:54:28 +02:00
commit 344b783e22
3 changed files with 165 additions and 292 deletions

View File

@ -1,197 +0,0 @@
/* @flow */
import React from 'react';
import Tooltip from 'rc-tooltip';
import TooltipContent from 'components/TooltipContent';
import Link from 'components/Link';
import styled from 'styled-components';
import colors from 'config/colors';
import type { Props as BaseProps } from '../Container';
const GreenSpan = styled.span`
color: ${colors.GREEN_PRIMARY};
`;
type Props = {
selectedAccount: $ElementType<BaseProps, 'selectedAccount'>,
sendForm: $ElementType<BaseProps, 'sendForm'>,
sendFormActions: $ElementType<BaseProps, 'sendFormActions'>,
children?: $ElementType<BaseProps, 'children'>,
};
const AdvancedForm = (props: Props) => {
const {
account,
network,
} = props.selectedAccount;
const {
networkSymbol,
currency,
gasPrice,
gasLimit,
recommendedGasPrice,
calculatingGasLimit,
nonce,
data,
errors,
warnings,
infos,
advanced,
} = props.sendForm;
const {
toggleAdvanced,
onGasPriceChange,
onGasLimitChange,
onNonceChange,
onDataChange,
} = props.sendFormActions;
if (!advanced) {
return (
<div className="advanced-container">
<a className="advanced" onClick={toggleAdvanced}>Advanced settings</a>
{ props.children }
</div>
);
}
const nonceTooltip = (
<TooltipContent>
TODO<br />
</TooltipContent>
);
let gasLimitTooltipCurrency: string;
let gasLimitTooltipValue: string;
if (networkSymbol !== currency) {
gasLimitTooltipCurrency = 'tokens';
gasLimitTooltipValue = network.defaultGasLimitTokens;
} else {
gasLimitTooltipCurrency = networkSymbol;
gasLimitTooltipValue = network.defaultGasLimit;
}
const gasLimitTooltip = (
<TooltipContent>
Gas limit is the amount of gas to send with your transaction.<br />
<GreenSpan>TX fee = gas price * gas limit</GreenSpan> &amp; is paid to miners for including your TX in a block.<br />
Increasing this number will not get your TX mined faster.<br />
Default value for sending {gasLimitTooltipCurrency} is <GreenSpan>{gasLimitTooltipValue}</GreenSpan>
</TooltipContent>
);
const gasPriceTooltip = (
<TooltipContent>
Gas Price is the amount you pay per unit of gas.<br />
<GreenSpan>TX fee = gas price * gas limit</GreenSpan> &amp; is paid to miners for including your TX in a block.<br />
Higher the gas price = faster transaction, but more expensive. Recommended is <GreenSpan>{recommendedGasPrice} GWEI.</GreenSpan><br />
<Link href="https://myetherwallet.github.io/knowledge-base/gas/what-is-gas-ethereum.html" target="_blank" rel="noreferrer noopener" isGreen>Read more</Link>
</TooltipContent>
);
const dataTooltip = (
<TooltipContent>
Data is usually used when you send transactions to contracts.
</TooltipContent>
);
return (
<div className="advanced-container opened">
<a className="advanced" onClick={toggleAdvanced}>Advanced settings</a>
<div className="row gas-row">
{/* <div className="column nonce">
<label>
Nonce
<Tooltip
arrowContent={<div className="rc-tooltip-arrow-inner"></div>}
overlay={ nonceTooltip }
placement="top">
<span className="what-is-it"></span>
</Tooltip>
</label>
<input
type="text"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={ nonce }
onChange={ event => onNonceChange(event.target.value) } />
{ errors.nonce ? (<span className="error">{ errors.nonce }</span>) : null }
{ warnings.nonce ? (<span className="warning">{ warnings.nonce }</span>) : null }
</div> */}
<div className="column">
<label>
Gas limit
<Tooltip
arrowContent={<div className="rc-tooltip-arrow-inner" />}
overlay={gasLimitTooltip}
placement="top"
>
<span className="what-is-it" />
</Tooltip>
</label>
<input
type="text"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={gasLimit}
disabled={networkSymbol === currency && data.length > 0}
onChange={event => onGasLimitChange(event.target.value)}
/>
{ errors.gasLimit ? (<span className="error">{ errors.gasLimit }</span>) : null }
{ warnings.gasLimit ? (<span className="warning">{ warnings.gasLimit }</span>) : null }
{ calculatingGasLimit ? (<span className="info">Calculating...</span>) : null }
</div>
<div className="column">
<label>
Gas price
<Tooltip
arrowContent={<div className="rc-tooltip-arrow-inner" />}
overlay={gasPriceTooltip}
placement="top"
>
<span className="what-is-it" />
</Tooltip>
</label>
<input
type="text"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={gasPrice}
onChange={event => onGasPriceChange(event.target.value)}
/>
{ errors.gasPrice ? (<span className="error">{ errors.gasPrice }</span>) : null }
</div>
</div>
<div className="row">
<label>
Data
<Tooltip
arrowContent={<div className="rc-tooltip-arrow-inner" />}
overlay={dataTooltip}
placement="top"
>
<span className="what-is-it" />
</Tooltip>
</label>
<textarea disabled={networkSymbol !== currency} value={networkSymbol !== currency ? '' : data} onChange={event => onDataChange(event.target.value)} />
{ errors.data ? (<span className="error">{ errors.data }</span>) : null }
</div>
<div className="row">
{ props.children }
</div>
</div>
);
};
export default AdvancedForm;

View File

@ -1,95 +0,0 @@
/* @flow */
import React from 'react';
import ColorHash from 'color-hash';
import { H2 } from 'components/Heading';
import ScaleText from 'react-scale-text';
import { findAccountTokens } from 'reducers/TokensReducer';
import type { Coin } from 'reducers/LocalStorageReducer';
import type { Token } from 'reducers/TokensReducer';
import type { Props as BaseProps } from '../Container';
type Props = {
pending: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'pending'>,
tokens: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'tokens'>,
network: Coin
}
type Style = {
+color: string,
+background: string,
+borderColor: string
}
const PendingTransactions = (props: Props) => {
const pending = props.pending.filter(tx => !tx.rejected);
if (pending.length < 1) return null;
const tokens: Array<Token> = props.tokens;
const bgColorFactory = new ColorHash({ lightness: 0.7 });
const textColorFactory = new ColorHash();
const pendingTxs: React$Element<string> = pending.map((tx, i) => {
let iconColor: Style;
let symbol: string;
let name: string;
const isSmartContractTx: boolean = tx.currency !== props.network.symbol;
if (isSmartContractTx) {
const token: ?Token = tokens.find(t => t.symbol === tx.currency);
if (!token) {
iconColor = {
color: '#ffffff',
background: '#000000',
borderColor: '#000000',
};
symbol = 'Unknown';
name = 'Unknown';
} else {
const bgColor: string = bgColorFactory.hex(token.name);
iconColor = {
color: textColorFactory.hex(token.name),
background: bgColor,
borderColor: bgColor,
};
symbol = token.symbol.toUpperCase();
name = token.name;
}
} else {
iconColor = {
color: textColorFactory.hex(tx.network),
background: bgColorFactory.hex(tx.network),
borderColor: bgColorFactory.hex(tx.network),
};
symbol = props.network.symbol;
name = props.network.name;
}
return (
<div key={i} className="tx">
<div className="icon" style={iconColor}>
<div className="icon-inner">
<ScaleText widthOnly><p>{ symbol }</p></ScaleText>
</div>
</div>
<div className="name">
<a href={`${props.network.explorer.tx}${tx.id}`} target="_blank" rel="noreferrer noopener">{ name }</a>
</div>
<div className="amount">{ isSmartContractTx ? tx.amount : tx.total } { symbol }</div>
</div>
);
});
return (
<div className="pending-transactions">
<H2>Pending transactions</H2>
{ pendingTxs }
</div>
);
};
export default PendingTransactions;

View File

@ -0,0 +1,165 @@
/* @flow */
import React, { Component } 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 type { Coin } from 'reducers/LocalStorageReducer';
import type { Token } from 'reducers/TokensReducer';
import type { Props as BaseProps } from '../Container';
type Props = {
pending: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'pending'>,
tokens: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'tokens'>,
network: Coin
}
type Style = {
+color: string,
+background: string,
+borderColor: string
}
const Wrapper = styled.div`
border-top: 1px solid ${colors.DIVIDER};
`;
const TransactionWrapper = styled.div`
border-bottom: 1px solid ${colors.DIVIDER};
padding: 14px 48px;
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: 30px;
text-transform: uppercase;
user-select: none;
text-align: center;
color: ${props => props.color};
background: ${props => props.background};
border-color: ${props => props.borderColor};
`;
const P = styled.p``;
const TransactionName = styled.div`
flex: 1;
`;
const TransactionAmount = styled.div``;
class PendingTransactions extends Component<Props> {
getPendingTransactions() {
return this.props.pending.filter(tx => !tx.rejected);
}
getTransactionIconColors(tx: any) {
let iconColors = { };
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 = {
color: '#ffffff',
background: '#000000',
borderColor: '#000000',
};
} else {
const bgColor: string = bgColorFactory.hex(token.name);
iconColors = {
color: textColorFactory.hex(token.name),
background: bgColor,
borderColor: bgColor,
};
}
} else {
iconColors = {
color: 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>
<TransactionIcon
color={() => this.getTransactionIconColors(tx).color}
background={() => this.getTransactionIconColors(tx).background}
borderColor={() => this.getTransactionIconColors(tx).borderColor}
>
<ScaleText widthOnly>
<P>{this.getTransactionSymbol(tx)}</P>
</ScaleText>
</TransactionIcon>
<TransactionName>
<Link
href={`${this.props.network.explorer.tx}${tx.id}`}
target="_blank"
rel="noreferrer noopener"
>
{this.getTransactionName(tx)}
</Link>
</TransactionName>
<TransactionAmount>
{tx.currency !== this.props.network.symbol ? tx.amount : tx.total} {this.getTransactionSymbol(tx)}
</TransactionAmount>
</TransactionWrapper>
))}
</Wrapper>
);
}
}
export default PendingTransactions;