From 70fe5fb120508c5b471a1703210b31dede8d236a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Neves?= Date: Thu, 24 Jan 2019 00:08:20 -0500 Subject: [PATCH 1/2] feature: animation and general improvements to the send and receive views --- app/components/wallet-address.js | 82 ++++++++++----- app/views/receive.js | 165 ++++++++++++++++++++++++++----- app/views/send.js | 141 ++++++++++++++++---------- 3 files changed, 287 insertions(+), 101 deletions(-) diff --git a/app/components/wallet-address.js b/app/components/wallet-address.js index 5e674f2..6f1ea57 100644 --- a/app/components/wallet-address.js +++ b/app/components/wallet-address.js @@ -1,6 +1,7 @@ // @flow -import React, { Component } from 'react'; +import React, { PureComponent } from 'react'; import styled from 'styled-components'; +import { Transition, animated } from 'react-spring'; import { ColumnComponent } from './column'; import { Button } from './button'; @@ -36,16 +37,16 @@ const Input = styled.input` const Btn = styled(Button)` border-width: 1px; - font-weight: ${props => props.theme.fontWeight.light}; + font-weight: ${props => props.theme.fontWeight.regular}; border-color: ${props => (props.isVisible ? props.theme.colors.primary : props.theme.colors.buttonBorderColor )}; - padding: 6px 10px; - width: 50%; + padding: 8px 10px; + min-width: 260px; img { height: 12px; - width: 16px; + width: 20px; } `; @@ -59,36 +60,50 @@ const QRCodeWrapper = styled.div` width: 100%; `; +const RevealsMain = styled.div` + width: 100%; + height: 100%; + position: relative; + display: flex; + align-items: flex-start; + justify-content: flex-start; + + & > div { + top: 0; + right: 0; + left: 0; + } +`; + type Props = { address: string, + isVisible?: boolean, }; type State = { isVisible: boolean, }; -export class WalletAddress extends Component { - state = { +export class WalletAddress extends PureComponent { + static defaultProps = { isVisible: false, - }; + } - show = () => { - this.setState( - () => ({ isVisible: true }), - ); - }; + constructor(props: Props) { + super(props); - hide = () => { - this.setState( - () => ({ isVisible: false }), - ); - }; + this.state = { isVisible: props.isVisible }; + } + show = () => this.setState(() => ({ isVisible: true })); + + hide = () => this.setState(() => ({ isVisible: false })); render() { const { address } = this.props; const { isVisible } = this.state; const toggleVisibility = isVisible ? this.hide : this.show; + const buttonLabel = `${isVisible ? 'Hide' : 'Show'} details and QR Code`; return ( @@ -100,19 +115,34 @@ export class WalletAddress extends Component { /> - {isVisible - ? ( - - - - ) - : null} + + + {show => show && (props => ( + + + + + + ))} + + ); } diff --git a/app/views/receive.js b/app/views/receive.js index 9119948..d09a536 100644 --- a/app/views/receive.js +++ b/app/views/receive.js @@ -1,50 +1,171 @@ // @flow -import React, { PureComponent } from 'react'; +import React, { Fragment, PureComponent } from 'react'; import styled from 'styled-components'; +import { Transition, animated } from 'react-spring'; import { InputLabelComponent } from '../components/input-label'; import { RowComponent } from '../components/row'; +import { TextComponent } from '../components/text'; import { WalletAddress } from '../components/wallet-address'; -type Props = { - addresses: Array, - loadAddresses: () => void, -}; - -const Wrapper = styled.div` - margin-top: ${props => props.theme.layoutContentPaddingTop}; -`; +import MenuIcon from '../assets/images/menu_icon.svg'; const Row = styled(RowComponent)` margin-bottom: 10px; `; const Label = styled(InputLabelComponent)` - margin-left: 0; - margin-right: 0; - margin-bottom: 10px; - margin-top: 10px; + text-transform: uppercase; + color: ${props => props.theme.colors.transactionsDate}; + font-size: ${props => `${props.theme.fontSize.regular * 0.9}em`}; + font-weight: ${props => props.theme.fontWeight.bold}; + margin-bottom: 5px; `; -export class ReceiveView extends PureComponent { +const ShowMoreButton = styled.button` + background: none; + border: none; + cursor: pointer; + width: 100%; + color: ${props => props.theme.colors.text}; + outline: none; + display: flex; + align-items: center; + margin-top: 30px; + opacity: 0.7; + + &:hover { + opacity: 1; + } +`; + +const ShowMoreIcon = styled.img` + width: 25px; + height: 25px; + border: 1px solid ${props => props.theme.colors.text}; + border-radius: 100%; + margin-right: 11.5px; +`; + +const RevealsMain = styled.div` + width: 100%; + height: 100%; + position: relative; + display: flex; + align-items: flex-start; + justify-content: flex-start; + + & > div { + top: 0; + right: 0; + left: 0; + } +`; + +type Props = { + addresses: Array, + loadAddresses: () => void, +}; + +type State = { + showAdditionalOptions: boolean, +} + +export class ReceiveView extends PureComponent { + state = { + showAdditionalOptions: false, + }; + componentDidMount() { const { loadAddresses } = this.props; loadAddresses(); } + toggleAdditionalOptions = () => this.setState((prevState: State) => ({ + showAdditionalOptions: !prevState.showAdditionalOptions, + })); + + renderShieldedAddresses = (address: string) => { + const { showAdditionalOptions } = this.state; + const buttonText = `${showAdditionalOptions ? 'Hide' : 'Show'} Other Address Types`; + + return ( + + + ); + } + + renderTransparentAddresses = (address: string) => { + const { showAdditionalOptions } = this.state; + + return ( + + + {show => show && (props => ( + + + ))} + + + ); + } + render() { const { addresses } = this.props; return ( - - +
+ {(addresses || []).map((address, index) => { + if (index === 0) return this.renderShieldedAddresses(address); + return this.renderTransparentAddresses(address); + })} +
); } } diff --git a/app/views/send.js b/app/views/send.js index 74465d3..1fad1c4 100644 --- a/app/views/send.js +++ b/app/views/send.js @@ -1,7 +1,8 @@ // @flow -import React, { PureComponent } from 'react'; +import React, { Fragment, PureComponent } from 'react'; import styled, { keyframes } from 'styled-components'; import { BigNumber } from 'bignumber.js'; +import { Transition, animated } from 'react-spring'; import FEES from '../constants/fees'; @@ -75,19 +76,6 @@ const AmountInput = styled(InputComponent)` padding-left: ${props => (props.isEmpty ? '15' : '50')}px; `; -// const ShowFeeButton = styled.button` -// align-items: center; -// background: none; -// border: none; -// cursor: pointer; -// display: flex; -// width: 100%; -// color: ${props => props.theme.colors.text}; -// outline: none; -// margin-bottom: 15px; -// margin-top: 15px; -// `; - const ShowFeeButton = styled.button` background: none; border: none; @@ -97,7 +85,7 @@ const ShowFeeButton = styled.button` outline: none; display: flex; align-items: center; - margin-top: 30px; + margin: 30px 0; opacity: 0.7; &:hover { @@ -115,7 +103,7 @@ const SeeMoreIcon = styled.img` const FeeWrapper = styled.div` background-color: #000; - border-radius: 6px; + border-radius: 4px; padding: 13px 19px; margin-bottom: 20px; `; @@ -141,6 +129,7 @@ const InfoCardUSD = styled(TextComponent)` `; const FormButton = styled(Button)` + width: 100%; margin: 10px 0; border-color: ${props => (props.focused ? props.theme.colors.activeItem @@ -202,11 +191,27 @@ const ValidateStatusIcon = styled.img` margin-right: 7px; `; +const RevealsMain = styled.div` + width: 100%; + height: 100%; + position: relative; + display: flex; + align-items: flex-start; + justify-content: flex-start; + + & > div { + top: 0; + right: 0; + left: 0; + } +`; + type Props = SendState & { balance: number, zecPrice: number, addresses: string[], sendTransaction: SendTransactionInput => void, + loadAddresses: () => void, resetSendView: () => void, validateAddress: ({ address: string }) => void, }; @@ -235,7 +240,9 @@ export class SendView extends PureComponent { state = initialState; componentDidMount() { - const { resetSendView } = this.props; + const { resetSendView, addresses, loadAddresses } = this.props; + + if (addresses.length === 0) loadAddresses(); resetSendView(); } @@ -344,16 +351,16 @@ export class SendView extends PureComponent { if (isSending) { return ( - <> + - + ); } if (operationId) { return ( - <> + { > Send again! - + ); } @@ -478,42 +485,65 @@ export class SendView extends PureComponent { placeholder='Enter a text here' /> this.setState(state => ({ showFee: !state.showFee })) - } + onClick={() => this.setState(state => ({ + showFee: !state.showFee, + }))} > - + - {showFee && ( - - - - - - - - ({ - label: cur.toLowerCase(), - value: String(FEES[cur]), - }))} - placement='top' - bgColor={theme.colors.blackTwo} - /> - - - - )} + + + {show => show && (props => ( + + + + + + + + + ({ + label: cur.toLowerCase(), + value: String(FEES[cur]), + }))} + /> + + + + + ))} + + {feeType === FEES.CUSTOM && ( )} @@ -540,6 +570,7 @@ export class SendView extends PureComponent { label='Send' variant='secondary' focused + isFluid onClick={this.showModal(toggle)} /> )} @@ -548,7 +579,11 @@ export class SendView extends PureComponent { > {toggle => ( - {this.renderModalContent({ valueSent, valueSentInUsd, toggle })} + {this.renderModalContent({ + valueSent, + valueSentInUsd, + toggle, + })} )} From 291e011eb705867296d8a25e1ee185ffc66483e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Neves?= Date: Fri, 25 Jan 2019 16:57:12 -0500 Subject: [PATCH 2/2] chore: electron default window height refactor: modal background overlay rgba change refactor: fix transitions on all relevant components --- app/components/loading-screen.js | 5 +++-- app/components/modal.js | 2 +- app/components/wallet-address.js | 21 +++++++++++++-------- app/views/receive.js | 16 +++++----------- app/views/send.js | 14 ++++++++------ config/electron.js | 2 +- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/app/components/loading-screen.js b/app/components/loading-screen.js index 5ce858f..e12f923 100644 --- a/app/components/loading-screen.js +++ b/app/components/loading-screen.js @@ -64,12 +64,13 @@ export class LoadingScreen extends PureComponent { {() => props => ( diff --git a/app/components/modal.js b/app/components/modal.js index c110779..5cec0da 100644 --- a/app/components/modal.js +++ b/app/components/modal.js @@ -13,7 +13,7 @@ const ModalWrapper = styled.div` top: 0; left: 0; z-index: 10; - background-color: rgba(0, 0, 0, 0.4); + background-color: rgba(0, 0, 0, 0.5); `; const ChildrenWrapper = styled.div` diff --git a/app/components/wallet-address.js b/app/components/wallet-address.js index 6f1ea57..bffb7ea 100644 --- a/app/components/wallet-address.js +++ b/app/components/wallet-address.js @@ -67,6 +67,8 @@ const RevealsMain = styled.div` display: flex; align-items: flex-start; justify-content: flex-start; + height: ${props => (props.isVisible ? '178px' : 0)} + transition: all 0.25s ease-in-out; & > div { top: 0; @@ -92,7 +94,7 @@ export class WalletAddress extends PureComponent { constructor(props: Props) { super(props); - this.state = { isVisible: props.isVisible }; + this.state = { isVisible: Boolean(props.isVisible) }; } show = () => this.setState(() => ({ isVisible: true })); @@ -121,17 +123,20 @@ export class WalletAddress extends PureComponent { isVisible={isVisible} /> - + {show => show && (props => ( diff --git a/app/views/receive.js b/app/views/receive.js index d09a536..666f2a8 100644 --- a/app/views/receive.js +++ b/app/views/receive.js @@ -97,10 +97,7 @@ export class ReceiveView extends PureComponent { alignItems='center' justifyContent='space-between' > - + { {show => show && (props => ( diff --git a/app/views/send.js b/app/views/send.js index c6eeb90..023fdc5 100644 --- a/app/views/send.js +++ b/app/views/send.js @@ -258,7 +258,7 @@ export class SendView extends PureComponent { if (field === 'to') { // eslint-disable-next-line max-len this.setState(() => ({ [field]: value }), - () => validateAddress({ address: value }) ); + () => validateAddress({ address: value })); } else { this.setState(() => ({ [field]: value })); } @@ -517,16 +517,18 @@ export class SendView extends PureComponent { {show => show && (props => ( diff --git a/config/electron.js b/config/electron.js index 2096627..b6fcbf1 100644 --- a/config/electron.js +++ b/config/electron.js @@ -53,7 +53,7 @@ const createWindow = () => { mainWindow = new BrowserWindow({ width: 1000, - height: 600, + height: 660, transparent: false, frame: true, resizable: true,