/* @flow */ import React, { useState } from 'react'; import styled, { css } from 'styled-components'; import { FormattedMessage } from 'react-intl'; import { Button, Select, Input, Icon, Link, P, colors, icons as ICONS } from 'trezor-ui-components'; import { FONT_SIZE, FONT_WEIGHT, SCREEN_SIZE } from 'config/variables'; import { FIAT_CURRENCIES } from 'config/app'; import Title from 'views/Wallet/components/Title'; import l10nCommonMessages from 'views/common.messages'; import Content from 'views/Wallet/components/Content'; import { getBottomText } from 'utils/uiUtils'; import PendingTransactions from '../components/PendingTransactions'; import AdvancedForm from './components/AdvancedForm'; import l10nMessages from './index.messages'; import l10nSendMessages from '../../common.messages'; import type { Props } from './Container'; const AmountInputLabelWrapper = styled.div` display: flex; justify-content: space-between; `; const AmountInputLabel = styled.span` text-align: right; color: ${colors.TEXT_SECONDARY}; `; const InputRow = styled.div` padding-bottom: 28px; `; const SetMaxAmountButton = styled(Button)` padding: 0 10px; font-size: ${FONT_SIZE.SMALL}; transition: all 0s; border-radius: 0; border-right: 0; border-left: 0; `; const CurrencySelect = styled(Select)` min-width: 77px; height: 40px; flex: 0.2; `; const FeeOptionWrapper = styled.div` display: flex; justify-content: space-between; `; const OptionValue = styled(P)` flex: 1 0 auto; min-width: 70px; margin-right: 5px; `; const OptionLabel = styled(P)` flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; text-align: right; word-break: break-all; `; const FeeLabelWrapper = styled.div` display: flex; align-items: center; padding-bottom: 10px; `; const FeeLabel = styled.span` color: ${colors.TEXT_SECONDARY}; `; const UpdateFeeWrapper = styled.span` margin-left: 8px; display: flex; align-items: center; font-size: ${FONT_SIZE.SMALL}; color: ${colors.WARNING_PRIMARY}; `; const StyledLink = styled(Link)` margin-left: 4px; white-space: nowrap; `; const ToggleAdvancedSettingsWrapper = styled.div` min-height: 40px; margin-bottom: 20px; display: flex; flex-direction: row; justify-content: space-between; @media screen and (max-width: ${SCREEN_SIZE.MD}) { ${props => props.isAdvancedSettingsHidden && css` flex-direction: column; `} } `; const ToggleAdvancedSettingsButton = styled(Button)` min-height: 40px; padding: 0; display: flex; flex: 1 1 0; align-items: center; font-weight: ${FONT_WEIGHT.MEDIUM}; justify-content: flex-start; `; const FormButtons = styled.div` display: flex; flex: 1 1; @media screen and (max-width: ${SCREEN_SIZE.MD}) { margin-top: ${props => (props.isAdvancedSettingsHidden ? '10px' : 0)}; } button + button { margin-left: 5px; } `; const SendButton = styled(Button)` word-break: break-all; flex: 1; `; const ClearButton = styled(Button)``; const AdvancedSettingsIcon = styled(Icon)` margin-left: 10px; `; const QrButton = styled(Button)` border-top-left-radius: 0px; border-bottom-left-radius: 0px; border-left: 0px; height: 40px; padding: 0 10px; `; const LocalAmountWrapper = styled.div` display: flex; align-self: flex-start; margin-top: 26px; @media screen and (max-width: ${SCREEN_SIZE.MD}) { flex: 1 0 100%; justify-content: flex-end; margin-top: 0px; padding-top: 28px; } `; const AmountRow = styled(InputRow)` display: flex; align-items: flex-end; padding-bottom: 28px; @media screen and (max-width: ${SCREEN_SIZE.MD}) { flex-wrap: wrap; } `; const LocalAmountInput = styled(Input)` @media screen and (max-width: ${SCREEN_SIZE.MD}) { flex: 1 1 100%; } `; const LocalCurrencySelect = styled(Select)` min-width: 77px; height: 40px; @media screen and (max-width: ${SCREEN_SIZE.MD}) { flex: 1 1 0; } `; const EqualsSign = styled.div` align-self: center; padding: 0 10px; font-size: ${FONT_SIZE.BIGGER}; @media screen and (max-width: ${SCREEN_SIZE.MD}) { display: none; } `; const StyledIcon = styled(Icon)` margin-right: 6px; `; // render helpers const getAddressInputState = ( address: string, addressErrors: boolean, addressWarnings: boolean ): ?string => { let state = null; if (address && !addressErrors) { state = 'success'; } if (addressWarnings && !addressErrors) { state = 'warning'; } if (addressErrors) { state = 'error'; } return state; }; const getAmountInputState = (amountErrors: boolean, amountWarnings: boolean): ?string => { let state = null; if (amountWarnings && !amountErrors) { state = 'warning'; } if (amountErrors) { state = 'error'; } return state; }; const buildCurrencyOption = currency => { return { value: currency, label: currency.toUpperCase() }; }; // stateless component const AccountSend = (props: Props) => { const device = props.wallet.selectedDevice; const { account, network, discovery, shouldRender } = props.selectedAccount; const { address, amount, localAmount, localCurrency, setMax, feeLevels, selectedFeeLevel, feeNeedsUpdate, total, errors, warnings, infos, sending, advanced, } = props.sendForm; const { toggleAdvanced, onAddressChange, onAmountChange, onLocalAmountChange, onLocalCurrencyChange, onSetMax, onFeeLevelChange, updateFeeLevels, onSend, onClear, } = props.sendFormActions; const [touched, setTouched] = useState(false); if (!device || !account || !discovery || !network || !shouldRender) { const { loader, exceptionPage } = props.selectedAccount; return ; } let isSendButtonDisabled: boolean = Object.keys(errors).length > 0 || total === '0' || amount.length === 0 || address.length === 0 || sending || account.imported; let sendButtonText = ; if (total !== '0') { sendButtonText = ( ); } if (!device.connected) { sendButtonText = ; isSendButtonDisabled = true; } else if (!device.available) { sendButtonText = ; isSendButtonDisabled = true; } else if (!discovery.completed) { sendButtonText = ; isSendButtonDisabled = true; } const tokensSelectData: Array<{ value: string, label: string }> = [ { value: network.symbol, label: network.symbol }, ]; const tokensSelectValue = tokensSelectData[0]; const isAdvancedSettingsHidden = !advanced; const accountReserve: ?string = account.networkType === 'ripple' && !account.empty ? account.reserve : null; return ( <FormattedMessage {...l10nMessages.TR_SEND_RIPPLE} /> onAddressChange(event.target.value)} sideAddons={[ , ]} /> {accountReserve && ( )} } value={amount} onChange={event => onAmountChange(event.target.value)} bottomText={getBottomText(errors.amount, warnings.amount, infos.amount)} sideAddons={[ onSetMax()} isWhite={!setMax}> {!setMax && ( )} {setMax && ( )} , , ]} /> = onLocalAmountChange(event.target.value)} sideAddons={[ onLocalCurrencyChange(option)} value={buildCurrencyOption(localCurrency)} options={FIAT_CURRENCIES.map(c => buildCurrencyOption(c))} />, ]} /> {feeNeedsUpdate && ( {' '} )}