You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-wallet/src/js/components/wallet/account/send/SendForm.js

208 lines
6.8 KiB

/* @flow */
import React, { Component } from 'react';
import styled from 'styled-components';
import Select from 'react-select';
import { H2 } from 'components/common/Heading';
import AdvancedForm from './AdvancedForm';
import PendingTransactions from './PendingTransactions';
import { FeeSelectValue, FeeSelectOption } from './FeeSelect';
import SelectedAccount from '../SelectedAccount';
import { findAccountTokens } from 'reducers/TokensReducer';
import { calculate, validation } from 'actions/SendFormActions';
import { findToken } from 'reducers/TokensReducer';
import type { Props } from './index';
import type { Token } from 'flowtype';
export default class SendContainer extends Component<Props> {
componentWillReceiveProps(newProps: Props) {
calculate(this.props, newProps);
validation(newProps);
this.props.saveSessionStorage();
}
render() {
return (
<SelectedAccount {...this.props}>
<Send {...this.props} />
</SelectedAccount>
);
}
}
const StyledH2 = styled(H2)`
padding: 20px 48px;
`;
const Send = (props: Props) => {
const device = props.wallet.selectedDevice;
const {
account,
network,
discovery,
tokens,
} = props.selectedAccount;
if (!device || !account || !discovery || !network) return null;
const {
address,
amount,
setMax,
networkSymbol,
currency,
feeLevels,
selectedFeeLevel,
gasPriceNeedsUpdate,
total,
errors,
warnings,
infos,
advanced,
data,
sending,
} = props.sendForm;
const {
onAddressChange,
onAmountChange,
onSetMax,
onCurrencyChange,
onFeeLevelChange,
updateFeeLevels,
onSend,
} = props.sendFormActions;
const fiatRate = props.fiat.find(f => f.network === network);
const tokensSelectData = tokens.map(t => ({ value: t.symbol, label: t.symbol }));
tokensSelectData.unshift({ value: network.symbol, label: network.symbol });
const setMaxClassName: string = setMax ? 'set-max enabled' : 'set-max';
let updateFeeLevelsButton = null;
if (gasPriceNeedsUpdate) {
updateFeeLevelsButton = (
<span className="update-fee-levels">Recommended fees updated. <a onClick={updateFeeLevels}>Click here to use them</a></span>
);
}
let addressClassName: ?string;
if (errors.address) {
addressClassName = 'not-valid';
} else if (warnings.address) {
addressClassName = 'warning';
} else if (address.length > 0) {
addressClassName = 'valid';
}
let buttonDisabled: boolean = Object.keys(errors).length > 0 || total === '0' || amount.length === 0 || address.length === 0 || sending;
let buttonLabel: string = 'Send';
if (networkSymbol !== currency && amount.length > 0 && !errors.amount) {
buttonLabel += ` ${amount} ${currency.toUpperCase()}`;
} else if (networkSymbol === currency && total !== '0') {
buttonLabel += ` ${total} ${network.symbol}`;
}
if (!device.connected) {
buttonLabel = 'Device is not connected';
buttonDisabled = true;
} else if (!device.available) {
buttonLabel = 'Device is unavailable';
buttonDisabled = true;
} else if (!discovery.completed) {
buttonLabel = 'Loading accounts';
buttonDisabled = true;
}
return (
<section className="send-form">
<StyledH2>Send Ethereum or tokens</StyledH2>
<div className="row address-input">
<label>Address</label>
<input
type="text"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={address}
className={addressClassName}
onChange={event => onAddressChange(event.target.value)}
/>
<span className="input-icon" />
{ errors.address ? (<span className="error">{ errors.address }</span>) : null }
{ warnings.address ? (<span className="warning">{ warnings.address }</span>) : null }
{ infos.address ? (<span className="info">{ infos.address }</span>) : null }
</div>
<div className="row">
<label>Amount</label>
<div className="amount-input">
<input
type="text"
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
value={amount}
className={errors.amount ? 'not-valid' : null}
onChange={event => onAmountChange(event.target.value)}
/>
<a className={setMaxClassName} onClick={onSetMax}>Set max</a>
<Select
name="currency"
className="currency"
searchable={false}
clearable={false}
multi={false}
value={currency}
disabled={tokensSelectData.length < 2}
onChange={onCurrencyChange}
options={tokensSelectData}
/>
</div>
{ errors.amount ? (<span className="error">{ errors.amount }</span>) : null }
{ warnings.amount ? (<span className="warning">{ warnings.amount }</span>) : null }
</div>
<div className="row">
<label>Fee{ updateFeeLevelsButton }</label>
<Select
name="fee"
className="fee"
searchable={false}
clearable={false}
value={selectedFeeLevel}
onChange={onFeeLevelChange}
valueComponent={FeeSelectValue}
optionComponent={FeeSelectOption}
disabled={networkSymbol === currency && data.length > 0}
optionClassName="fee-option"
options={feeLevels}
/>
</div>
<AdvancedForm
selectedAccount={props.selectedAccount}
sendForm={props.sendForm}
sendFormActions={props.sendFormActions}
>
<button disabled={buttonDisabled} onClick={event => onSend()}>{ buttonLabel }</button>
</AdvancedForm>
<PendingTransactions
pending={props.selectedAccount.pending}
tokens={props.selectedAccount.tokens}
network={network}
/>
</section>
);
};