diff --git a/package.json b/package.json index 39397433..0ae27e1a 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "ethereumjs-tx": "^1.3.3", "ethereumjs-units": "^0.2.0", "ethereumjs-util": "^5.1.4", + "flow-webpack-plugin": "^1.2.0", "git-revision-webpack-plugin": "^3.0.3", "hdkey": "^0.8.0", "html-webpack-plugin": "^3.2.0", @@ -49,8 +50,7 @@ "react-router-redux": "next", "react-scale-text": "^1.2.2", "react-select": "2.0.0", - "react-sticky-el": "^1.0.20", - "react-transition-group": "^2.2.1", + "react-transition-group": "^2.4.0", "redbox-react": "^1.6.0", "redux": "4.0.0", "redux-logger": "^3.0.6", diff --git a/src/actions/SendFormActions.js b/src/actions/SendFormActions.js index 6288c9d6..6b59279a 100644 --- a/src/actions/SendFormActions.js +++ b/src/actions/SendFormActions.js @@ -13,6 +13,7 @@ import { initialState } from 'reducers/SendFormReducer'; import { findToken } from 'reducers/TokensReducer'; import { findDevice, getPendingAmount, getPendingNonce } from 'reducers/utils'; import * as stateUtils from 'reducers/utils'; +import { validateAddress } from 'utils/ethUtils'; import type { Dispatch, @@ -345,32 +346,19 @@ export const validation = (props: Props): void => { if (state.untouched) return; // valid address if (state.touched.address) { - /* if (state.address.length < 1) { - errors.address = 'Address is not set'; - } else if (!EthereumjsUtil.isValidAddress(state.address)) { - errors.address = 'Address is not valid'; - } else { - // address warning or info are set in addressValidation ThunkAction - // do not override this - if (state.warnings.address) { - warnings.address = state.warnings.address; - } else if (state.infos.address) { - infos.address = state.infos.address; - } - } */ - - /* eslint (no-lonely-if) */ - if (state.address.length < 1) { - errors.address = 'Address is not set'; - } else if (!EthereumjsUtil.isValidAddress(state.address)) { - errors.address = 'Address is not valid'; - } else if (state.warnings.address) { - // address warning or info are set in addressValidation ThunkAction - // do not override this + const addressError = validateAddress(state.address); + if (addressError) { + errors.address = addressError; + } + + // address warning or info may be set in addressValidation ThunkAction + // do not override them + if (state.warnings.address) { warnings.address = state.warnings.address; - if (state.infos.address) { - infos.address = state.infos.address; - } + } + + if (state.infos.address) { + infos.address = state.infos.address; } } diff --git a/src/components/Checkbox/index.js b/src/components/Checkbox/index.js index 0201a2f1..fad58722 100644 --- a/src/components/Checkbox/index.js +++ b/src/components/Checkbox/index.js @@ -76,7 +76,12 @@ class Checkbox extends PureComponent { {checked && ( - + ) } diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js index 656c0b19..8f94ad15 100644 --- a/src/components/Tooltip/index.js +++ b/src/components/Tooltip/index.js @@ -3,19 +3,13 @@ import RcTooltip from 'rc-tooltip'; import colors from 'config/colors'; import styled from 'styled-components'; import PropTypes from 'prop-types'; -import { FONT_SIZE } from 'config/variables'; - -const TooltipContent = styled.div` - width: ${props => (props.isAside ? '260px' : '320px')}; - font-size: ${FONT_SIZE.SMALLEST}; -`; const Wrapper = styled.div` .rc-tooltip { + max-width: ${props => `${props.maxWidth}px` || 'auto'}; position: absolute; z-index: 1070; display: block; - background: red; visibility: visible; border: 1px solid ${colors.DIVIDER}; border-radius: 3px; @@ -178,9 +172,11 @@ class Tooltip extends Component { placement, content, children, + maxWidth, } = this.props; return ( { this.tooltipContainerRef = node; }} > @@ -188,7 +184,7 @@ class Tooltip extends Component { getTooltipContainer={() => this.tooltipContainerRef} arrowContent={
} placement={placement} - overlay={{content}} + overlay={content} > {children} @@ -204,6 +200,7 @@ Tooltip.propTypes = { PropTypes.element, PropTypes.string, ]), + maxWidth: PropTypes.number, content: PropTypes.oneOfType([ PropTypes.element, PropTypes.string, diff --git a/src/components/modals/confirm/SignTx/index.js b/src/components/modals/confirm/SignTx/index.js index 351d0345..7b3110de 100644 --- a/src/components/modals/confirm/SignTx/index.js +++ b/src/components/modals/confirm/SignTx/index.js @@ -5,6 +5,7 @@ import P from 'components/Paragraph'; import Icon from 'components/Icon'; import icons from 'config/icons'; import { H3 } from 'components/Heading'; +import { LINE_HEIGHT } from 'config/variables'; const Wrapper = styled.div` width: 390px; @@ -21,6 +22,12 @@ const Content = styled.div` padding: 24px 48px; `; +const StyledP = styled(P)` + word-wrap: break-word; + padding: 5px 0; + line-height: ${LINE_HEIGHT.SMALL} +`; + const Label = styled.div` padding-top: 5px; font-size: 10px; @@ -49,7 +56,7 @@ const ConfirmSignTx = (props) => {

{`${amount} ${currency}` }

-

{ address }

+ { address }

{ selectedFeeLevel.label }

diff --git a/src/config/variables.js b/src/config/variables.js index 964c3873..542e6986 100644 --- a/src/config/variables.js +++ b/src/config/variables.js @@ -41,5 +41,6 @@ export const TRANSITION = { }; export const LINE_HEIGHT = { + SMALL: '1.4', BASE: '1.8', }; diff --git a/src/support/BaseStyles.js b/src/support/BaseStyles.js index bd8fd525..74e21313 100644 --- a/src/support/BaseStyles.js +++ b/src/support/BaseStyles.js @@ -63,6 +63,44 @@ const baseStyles = () => injectGlobal` url('./fonts/roboto/roboto-mono-v4-greek_cyrillic-ext_greek-ext_latin_cyrillic_vietnamese_latin-ext-regular.svg#RobotoMono') format('svg'); /* Legacy iOS */ } + .slide-left-enter { + transform: translate(100%); + pointer-events: none; + } + + .slide-left-enter.slide-left-enter-active { + transform: translate(0%); + transition: transform 300ms ease-in-out; + } + + .slide-left-exit { + transform: translate(-100%); + } + + .slide-left-exit.slide-left-exit-active { + transform: translate(0%); + transition: transform 300ms ease-in-out; + } + + .slide-right-enter { + transform: translate(-100%); + pointer-events: none; + } + + .slide-right-enter.slide-right-enter-active { + transform: translate(0%); + transition: transform 300ms ease-in-out; + } + + .slide-right-exit { + transform: translate(-100%); + } + + .slide-right-exit.slide-right-exit-active { + transform: translate(-200%); + transition: transform 300ms ease-in-out; + } + `; export default baseStyles; \ No newline at end of file diff --git a/src/utils/ethUtils.js b/src/utils/ethUtils.js index 7b8ad313..82d5744a 100644 --- a/src/utils/ethUtils.js +++ b/src/utils/ethUtils.js @@ -1,6 +1,7 @@ /* @flow */ import BigNumber from 'bignumber.js'; +import EthereumjsUtil from 'ethereumjs-util'; export const decimalToHex = (dec: number): string => new BigNumber(dec).toString(16); @@ -28,4 +29,16 @@ export const strip = (str: string): string => { return padLeftEven(str); }; -export const calcGasPrice = (price: BigNumber, limit: string): string => price.times(limit).toString(); \ No newline at end of file +export const calcGasPrice = (price: BigNumber, limit: string): string => price.times(limit).toString(); + +export const validateAddress = (address: string): ?string => { + const hasUpperCase = new RegExp('^(.*[A-Z].*)$'); + if (address.length < 1) { + return 'Address is not set'; + } else if (!EthereumjsUtil.isValidAddress(address)) { + return 'Address is not valid'; + } else if (address.match(hasUpperCase) && !EthereumjsUtil.isValidChecksumAddress(address)) { + return 'Address is not a valid checksum'; + } + return null; +} \ No newline at end of file diff --git a/src/views/Landing/components/ConnectDevice/index.js b/src/views/Landing/components/ConnectDevice/index.js index 443b49ae..3d249c1e 100644 --- a/src/views/Landing/components/ConnectDevice/index.js +++ b/src/views/Landing/components/ConnectDevice/index.js @@ -86,7 +86,7 @@ class ConnectDevice extends Component { )} - {this.props.showWebUsb && ( + {this.props.showWebUsb && !this.props.showDisconnect && (

and