From 9463062912de37e679c72f04d86e4e8ee2aee031 Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Tue, 20 Feb 2018 13:46:57 -0600 Subject: [PATCH 01/21] feature(value): add value component and use it in activity feed --- app/components/Value/Value.js | 23 +++++++++++++++++ app/components/Value/Value.scss | 0 app/components/Value/index.js | 3 +++ .../components/components/Invoice/Invoice.js | 23 ++++++++--------- .../components/components/Payment/Payment.js | 23 ++++++++--------- .../components/Transaction/Transaction.js | 23 ++++++++--------- .../components/Transaction/Transaction.scss | 25 +++---------------- 7 files changed, 63 insertions(+), 57 deletions(-) create mode 100644 app/components/Value/Value.js create mode 100644 app/components/Value/Value.scss create mode 100644 app/components/Value/index.js diff --git a/app/components/Value/Value.js b/app/components/Value/Value.js new file mode 100644 index 00000000..180168f0 --- /dev/null +++ b/app/components/Value/Value.js @@ -0,0 +1,23 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { btc } from 'utils' + +const Value = ({ value, currency, currentTicker }) => { + const renderValue = () => { + if (currency === 'btc') { + return btc.satoshisToBtc(value) + } + + return 'gang' + } + + return ( + {renderValue()} + ) +} + +Value.propTypes = { + +} + +export default Value diff --git a/app/components/Value/Value.scss b/app/components/Value/Value.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/components/Value/index.js b/app/components/Value/index.js new file mode 100644 index 00000000..bc42655d --- /dev/null +++ b/app/components/Value/index.js @@ -0,0 +1,3 @@ +import Value from './Value' + +export default Value \ No newline at end of file diff --git a/app/routes/activity/components/components/Invoice/Invoice.js b/app/routes/activity/components/components/Invoice/Invoice.js index 42e5cd06..b356837f 100644 --- a/app/routes/activity/components/components/Invoice/Invoice.js +++ b/app/routes/activity/components/components/Invoice/Invoice.js @@ -5,6 +5,7 @@ import 'moment-timezone' import Isvg from 'react-inlinesvg' import { FaBolt } from 'react-icons/lib/fa' import { btc } from 'utils' +import Value from 'components/Value' import checkmarkIcon from 'icons/check_circle.svg' import clockIcon from 'icons/clock.svg' import styles from '../Activity.scss' @@ -47,20 +48,18 @@ const Invoice = ({
+ - { - ticker.currency === 'usd' ? - btc.satoshisToUsd(invoice.value, currentTicker.price_usd) - : - btc.satoshisToBtc(invoice.value) - } + - { - ticker.currency === 'usd' ? - btc.satoshisToUsd(invoice.fee, currentTicker.price_usd) - : - btc.satoshisToBtc(invoice.fee) - } +
diff --git a/app/routes/activity/components/components/Payment/Payment.js b/app/routes/activity/components/components/Payment/Payment.js index 2b97e060..f27ed7bb 100644 --- a/app/routes/activity/components/components/Payment/Payment.js +++ b/app/routes/activity/components/components/Payment/Payment.js @@ -5,6 +5,7 @@ import 'moment-timezone' import Isvg from 'react-inlinesvg' import { FaBolt } from 'react-icons/lib/fa' import { btc } from 'utils' +import Value from 'components/Value' import checkmarkIcon from 'icons/check_circle.svg' import styles from '../Activity.scss' @@ -39,20 +40,18 @@ const Payment = ({
- - { - ticker.currency === 'usd' ? - btc.satoshisToUsd(payment.value, currentTicker.price_usd) - : - btc.satoshisToBtc(payment.value) - } + - { - ticker.currency === 'usd' ? - btc.satoshisToUsd(payment.fee, currentTicker.price_usd) - : - btc.satoshisToBtc(payment.fee) - } +
diff --git a/app/routes/activity/components/components/Transaction/Transaction.js b/app/routes/activity/components/components/Transaction/Transaction.js index 1660946f..d3594d4e 100644 --- a/app/routes/activity/components/components/Transaction/Transaction.js +++ b/app/routes/activity/components/components/Transaction/Transaction.js @@ -5,6 +5,7 @@ import 'moment-timezone' import Isvg from 'react-inlinesvg' import { FaChain } from 'react-icons/lib/fa' import { btc } from 'utils' +import Value from 'components/Value' import checkmarkIcon from 'icons/check_circle.svg' import styles from '../Activity.scss' @@ -39,20 +40,18 @@ const Transaction = ({
0 ? styles.positive : styles.negative}`}> 0 ? styles.plus : styles.minus}>{ transaction.amount > 0 ? '+' : '-' } - { - ticker.currency === 'usd' ? - btc.satoshisToUsd(transaction.amount, currentTicker.price_usd) - : - btc.satoshisToBtc(transaction.amount) - } + - { - ticker.currency === 'usd' ? - btc.satoshisToUsd(transaction.total_fees, currentTicker.price_usd) - : - btc.satoshisToBtc(transaction.total_fees) - } +
diff --git a/app/routes/activity/components/components/Transaction/Transaction.scss b/app/routes/activity/components/components/Transaction/Transaction.scss index 5bf06196..37e30d6c 100644 --- a/app/routes/activity/components/components/Transaction/Transaction.scss +++ b/app/routes/activity/components/components/Transaction/Transaction.scss @@ -75,27 +75,6 @@ font-weight: 500; } - section { - display: inline-block; - vertical-align: top; - text-align: right; - font-size: 0; - margin: 0; - padding: 0; - - &:nth-child(1) { - width: 20%; - } - - &:nth-child(2) { - width: 80%; - } - } - - svg { - font-size: 20px; - } - span { display: block; @@ -106,6 +85,10 @@ &:nth-child(2) { font-size: 10px; } + + .value { + font-size: 14px; + } } } From 98b3c52e1198b27ee6bc460aa79da706a85fc31e Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Tue, 20 Feb 2018 15:05:36 -0600 Subject: [PATCH 02/21] feature(value): add value component to wallet --- app/components/Value/Value.js | 15 ++++++--- app/components/Wallet/Wallet.js | 27 +++++++++++++-- app/components/Wallet/Wallet.scss | 29 +++++++++++++--- app/routes/activity/components/Activity.js | 16 ++------- .../activity/containers/ActivityContainer.js | 33 +++++++++++++------ app/utils/btc.js | 25 +++++++++++++- 6 files changed, 110 insertions(+), 35 deletions(-) diff --git a/app/components/Value/Value.js b/app/components/Value/Value.js index 180168f0..d711335e 100644 --- a/app/components/Value/Value.js +++ b/app/components/Value/Value.js @@ -4,11 +4,18 @@ import { btc } from 'utils' const Value = ({ value, currency, currentTicker }) => { const renderValue = () => { - if (currency === 'btc') { - return btc.satoshisToBtc(value) + switch (currency) { + case 'btc': + return btc.satoshisToBtc(value) + case 'bits': + return btc.satoshisToBits(value) + case 'sats': + return value + case 'usd': + return btc.satoshisToUsd(value, currentTicker.price_usd) + default: + return value } - - return 'gang' } return ( diff --git a/app/components/Wallet/Wallet.js b/app/components/Wallet/Wallet.js index 280a2c9c..6bb2195a 100644 --- a/app/components/Wallet/Wallet.js +++ b/app/components/Wallet/Wallet.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import { FaAngleDown } from 'react-icons/lib/fa' import Isvg from 'react-inlinesvg' import { btc } from 'utils' +import Value from 'components/Value' import bitcoinIcon from 'icons/bitcoin.svg' import zapLogo from 'icons/zap_logo.svg' import qrCode from 'icons/qrcode.svg' @@ -22,17 +23,18 @@ class Wallet extends Component { render() { const { + setCurrency, balance, address, info, newAddress, + ticker, currentTicker, openPayForm, openRequestForm } = this.props const { modalOpen, qrCodeType } = this.state - const usdAmount = btc.satoshisToUsd((parseInt(balance.walletBalance, 10) + parseInt(balance.channelBalance, 10)), currentTicker.price_usd) const changeQrCode = () => { const qrCodeNum = this.state.qrCodeType === 1 ? 2 : 1 @@ -76,13 +78,31 @@ class Wallet extends Component {

- {btc.satoshisToBtc(parseFloat(balance.walletBalance) + parseFloat(balance.channelBalance))}BTC + + {btc.renderCurrency(ticker.currency)} this.setState({ modalOpen: true })}>

- ≈ ${usdAmount ? usdAmount.toLocaleString() : ''} +
+
setCurrency('btc')}> + BTC +
+
setCurrency('bits')}> + Bits +
+
setCurrency('sats')}> + Satoshis +
+
setCurrency('usd')}> + USD +
+
@@ -103,6 +123,7 @@ Wallet.propTypes = { address: PropTypes.string.isRequired, info: PropTypes.object.isRequired, newAddress: PropTypes.func.isRequired, + ticker: PropTypes.object.isRequired, currentTicker: PropTypes.object.isRequired, openPayForm: PropTypes.func.isRequired, openRequestForm: PropTypes.func.isRequired diff --git a/app/components/Wallet/Wallet.scss b/app/components/Wallet/Wallet.scss index db643089..c8a4eecb 100644 --- a/app/components/Wallet/Wallet.scss +++ b/app/components/Wallet/Wallet.scss @@ -79,12 +79,33 @@ opacity: 0.5; } } + + .currency { + margin-left: 2.5px; + } } - .usdValue { - font-size: 12px; - margin-left: 10px; - font-style: italic; + .tickerButtons { + display: flex; + flex-direction: row; + + section { + margin: 5px; + font-size: 10px; + border-radius: 5px; + border: 1px solid $white; + padding: 5px 10px; + cursor: pointer; + opacity: 0.5; + transition: 0.25s all; + + &.active { + background: $main; + color: $spaceborder; + border-color: $spaceborder; + opacity: 1; + } + } } } diff --git a/app/routes/activity/components/Activity.js b/app/routes/activity/components/Activity.js index 726721b8..c0229b7c 100644 --- a/app/routes/activity/components/Activity.js +++ b/app/routes/activity/components/Activity.js @@ -56,8 +56,8 @@ class Activity extends Component { changeFilter, currentActivity, newAddress, - openPayForm, - openRequestForm + + walletProps } = this.props if (invoiceLoading || paymentLoading) { return } @@ -74,15 +74,7 @@ class Activity extends Component { currentTicker={currentTicker} /> - +
@@ -130,8 +122,6 @@ Activity.propTypes = { hideActivityModal: PropTypes.func.isRequired, changeFilter: PropTypes.func.isRequired, newAddress: PropTypes.func.isRequired, - openPayForm: PropTypes.func.isRequired, - openRequestForm: PropTypes.func.isRequired, activity: PropTypes.object.isRequired, currentActivity: PropTypes.array.isRequired, diff --git a/app/routes/activity/containers/ActivityContainer.js b/app/routes/activity/containers/ActivityContainer.js index 5437ca83..e21b781c 100644 --- a/app/routes/activity/containers/ActivityContainer.js +++ b/app/routes/activity/containers/ActivityContainer.js @@ -1,5 +1,5 @@ import { connect } from 'react-redux' -import { tickerSelectors } from 'reducers/ticker' +import { setCurrency, tickerSelectors } from 'reducers/ticker' import { fetchBalance } from 'reducers/balance' import { fetchInvoices, @@ -26,6 +26,7 @@ import { setFormType } from 'reducers/form' import Activity from '../components/Activity' const mapDispatchToProps = { + setCurrency, setPayment, setInvoice, fetchPayments, @@ -64,15 +65,27 @@ const mapStateToProps = state => ({ nonActiveFilters: activitySelectors.nonActiveFilters(state) }) -const mergeProps = (stateProps, dispatchProps, ownProps) => ({ - ...stateProps, - ...dispatchProps, - ...ownProps, +const mergeProps = (stateProps, dispatchProps, ownProps) => { + const walletProps = { + balance: stateProps.balance, + address: stateProps.address.address, + info: stateProps.info, + ticker: stateProps.ticker, + currentTicker: stateProps.currentTicker, + + setCurrency: dispatchProps.setCurrency, + newAddress: dispatchProps.newAddress, + openPayForm: () => dispatchProps.setFormType('PAY_FORM'), + openRequestForm: () => dispatchProps.setFormType('REQUEST_FORM') + } - // action to open the pay form - openPayForm: () => dispatchProps.setFormType('PAY_FORM'), - // action to open the request form - openRequestForm: () => dispatchProps.setFormType('REQUEST_FORM') -}) + return { + ...stateProps, + ...dispatchProps, + ...ownProps, + + walletProps + } +} export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(Activity) diff --git a/app/utils/btc.js b/app/utils/btc.js index 4d72b776..93e9edc9 100644 --- a/app/utils/btc.js +++ b/app/utils/btc.js @@ -13,6 +13,13 @@ export function satoshisToBtc(satoshis) { return btcAmount > 0 ? btcAmount : btcAmount * -1 } +export function satoshisToBits(satoshis) { + if (satoshis === undefined || satoshis === null || satoshis === '') return null + + const bitsAmount = satoshis / 100 + return bitsAmount > 0 ? bitsAmount : bitsAmount * -1 +} + export function btcToUsd(btc, price) { const amount = parseFloat(btc * price).toFixed(2) return (btc > 0 && amount <= 0) ? '< 0.01' : amount.toLocaleString('en') @@ -24,10 +31,26 @@ export function satoshisToUsd(satoshis, price) { return btcToUsd(satoshisToBtc(satoshis), price) } +export function renderCurrency(currency) { + switch (currency) { + case 'btc': + return 'BTC' + case 'bits': + return 'bits' + case 'sats': + return 'satoshis' + case 'usd': + return 'USD' + default: + return 'satoshis' + } +} export default { btcToSatoshis, satoshisToBtc, + satoshisToBits, satoshisToUsd, - btcToUsd + btcToUsd, + renderCurrency } From 04798ac7f99f47fe4b61c7c5c1cf7fc789d4a69d Mon Sep 17 00:00:00 2001 From: Jack Mallers Date: Wed, 21 Feb 2018 11:39:07 -0600 Subject: [PATCH 03/21] feature(payform): new pay form MVP --- app/components/Form/Form.js | 21 +-- app/components/Form/Form.scss | 58 ++------ app/components/Form/Pay.js | 156 ++++++++++++++++++++++ app/components/Form/Pay.scss | 123 +++++++++++++++++ app/components/Wallet/Wallet.js | 5 +- app/icons/link.svg | 1 + app/icons/paper_plane.svg | 16 +++ app/icons/x.svg | 1 + app/icons/zap.svg | 1 + app/main.dev.js | 4 +- app/reducers/payform.js | 19 ++- app/routes/app/containers/AppContainer.js | 2 + app/utils/btc.js | 2 - 13 files changed, 345 insertions(+), 64 deletions(-) create mode 100644 app/components/Form/Pay.js create mode 100644 app/components/Form/Pay.scss create mode 100644 app/icons/link.svg create mode 100644 app/icons/paper_plane.svg create mode 100644 app/icons/x.svg create mode 100644 app/icons/zap.svg diff --git a/app/components/Form/Form.js b/app/components/Form/Form.js index dfc9476b..cbaece23 100644 --- a/app/components/Form/Form.js +++ b/app/components/Form/Form.js @@ -1,15 +1,19 @@ import React from 'react' import PropTypes from 'prop-types' +import Isvg from 'react-inlinesvg' import { MdClose } from 'react-icons/lib/md' +import Pay from './Pay' import PayForm from './PayForm' import RequestForm from './RequestForm' +import x from 'icons/x.svg' import styles from './Form.scss' const FORM_TYPES = { - PAY_FORM: PayForm, + // PAY_FORM: PayForm, + PAY_FORM: Pay, REQUEST_FORM: RequestForm } @@ -18,16 +22,13 @@ const Form = ({ formType, formProps, closeForm }) => { const FormComponent = FORM_TYPES[formType] return ( -
-
-
- -
- -
- -
+
+
+ + +
+
) } diff --git a/app/components/Form/Form.scss b/app/components/Form/Form.scss index 25a54ff0..d0fa3879 100644 --- a/app/components/Form/Form.scss +++ b/app/components/Form/Form.scss @@ -1,59 +1,27 @@ @import '../../variables.scss'; -.outtercontainer { - position: absolute; - top: 0; - bottom: 0; - width: 100%; - height: 100vh; - background: $white; - z-index: 0; - opacity: 0; - transition: all 0.5s; - - &.open { - opacity: 1; - z-index: 20; - } -} - -.innercontainer { +.container { position: relative; height: 100vh; - margin: 5%; + background: $spaceblue; } -.esc { - position: absolute; - top: 0; - right: 0; - color: $darkestgrey; - cursor: pointer; - padding: 20px; - border-radius: 50%; +.closeContainer { + text-align: right; + padding: 20px 40px 0px; - &:hover { - color: $bluegrey; - background: $darkgrey; - } + span { + cursor: pointer; + opacity: 1.0; + transition: 0.25s all; - &:active { - color: $white; - background: $main; + &:hover { + opacity: 0.5; + } } svg { - width: 32px; - height: 32px; + color: $white; } } -.content { - width: 50%; - margin: 0 auto; - display: flex; - flex-direction: column; - height: 75vh; - justify-content: center; - align-items: center; -} diff --git a/app/components/Form/Pay.js b/app/components/Form/Pay.js new file mode 100644 index 00000000..a88dd950 --- /dev/null +++ b/app/components/Form/Pay.js @@ -0,0 +1,156 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +import Isvg from 'react-inlinesvg' +import paperPlane from 'icons/paper_plane.svg' + +import { FaBolt, FaChain, FaAngleDown } from 'react-icons/lib/fa' +import LoadingBolt from 'components/LoadingBolt' +import CurrencyIcon from 'components/CurrencyIcon' + +import styles from './Pay.scss' + +class Pay extends Component { + componentDidUpdate(prevProps) { + const { + isOnchain, isLn, payform: { payInput }, fetchInvoice + } = this.props + + // If on-chain, focus on amount to let user know it's editable + if (isOnchain) { this.amountInput.focus() } + + // If LN go retrieve invoice details + if ((prevProps.payform.payInput !== payInput) && isLn) { + fetchInvoice(payInput) + } + } + + render() { + const { + payform: { amount, payInput, showErrors }, + currency, + crypto, + + isOnchain, + isLn, + currentAmount, + usdAmount, + inputCaption, + showPayLoadingScreen, + payFormIsValid: { errors, isValid }, + + setPayAmount, + onPayAmountBlur, + + setPayInput, + onPayInputBlur, + + onPaySubmit + } = this.props + + console.log('usdAmount: ', usdAmount) + + return ( +
+ {showPayLoadingScreen && } +
+ +

Make Payment

+
+ +
+
+
+ + + +
+
+