Browse Source

feature(sendcoins): use formSelectors to determine whether a user is using LN or onchain

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
5e72178adb
  1. 21
      app/reducers/form.js
  2. 6
      app/routes/app/components/App.js
  3. 11
      app/routes/app/components/components/Form/Form.js
  4. 56
      app/routes/app/components/components/Form/components/Pay/Pay.js
  5. 3
      app/routes/app/components/components/Form/components/Pay/Pay.scss
  6. 7
      app/routes/app/containers/AppContainer.js

21
app/reducers/form.js

@ -1,3 +1,5 @@
import { createSelector } from 'reselect'
// Initial State // Initial State
const initialState = { const initialState = {
modalOpen: false, modalOpen: false,
@ -94,6 +96,25 @@ const ACTION_HANDLERS = {
[RESET_FORM]: () => (initialState) [RESET_FORM]: () => (initialState)
} }
// ------------------------------------
// Selector
// ------------------------------------
const formSelectors = {}
const paymentRequestSelector = state => state.form.payment_request
const paymentTypeSelector = state => state.form.paymentType
formSelectors.isOnchain = createSelector(
paymentRequestSelector,
paymentRequest => paymentRequest.length === 42
)
formSelectors.isLn = createSelector(
paymentRequestSelector,
paymentRequest => paymentRequest.length === 124
)
export { formSelectors }
// ------------------------------------ // ------------------------------------
// Reducer // Reducer
// ------------------------------------ // ------------------------------------

6
app/routes/app/components/App.js

@ -33,6 +33,8 @@ class App extends Component {
payInvoice, payInvoice,
fetchInvoice, fetchInvoice,
currentTicker, currentTicker,
isOnchain,
isLn,
children children
} = this.props } = this.props
@ -58,6 +60,8 @@ class App extends Component {
fetchInvoice={fetchInvoice} fetchInvoice={fetchInvoice}
formInvoice={formInvoice} formInvoice={formInvoice}
currentTicker={currentTicker} currentTicker={currentTicker}
isOnchain={isOnchain}
isLn={isLn}
/> />
<Nav <Nav
ticker={ticker} ticker={ticker}
@ -95,6 +99,8 @@ App.propTypes = {
fetchInvoice: PropTypes.func.isRequired, fetchInvoice: PropTypes.func.isRequired,
fetchInfo: PropTypes.func.isRequired, fetchInfo: PropTypes.func.isRequired,
currentTicker: PropTypes.object, currentTicker: PropTypes.object,
isOnchain: PropTypes.bool.isRequired,
isLn: PropTypes.bool.isRequired,
children: PropTypes.object.isRequired children: PropTypes.object.isRequired
} }

11
app/routes/app/components/components/Form/Form.js

@ -21,8 +21,11 @@ const Form = ({
payInvoice, payInvoice,
fetchInvoice, fetchInvoice,
formInvoice, formInvoice,
currentTicker currentTicker,
isOnchain,
isLn
}) => { }) => {
return ( return (
<div className={`${styles.formContainer} ${isOpen ? styles.open : ''}`}> <div className={`${styles.formContainer} ${isOpen ? styles.open : ''}`}>
<div className={styles.container}> <div className={styles.container}>
@ -45,6 +48,8 @@ const Form = ({
currency={currency} currency={currency}
crypto={crypto} crypto={crypto}
close={close} close={close}
isOnchain={isOnchain}
isLn={isLn}
/> />
: :
<Request <Request
@ -81,7 +86,9 @@ Form.propTypes = {
payInvoice: PropTypes.func.isRequired, payInvoice: PropTypes.func.isRequired,
fetchInvoice: PropTypes.func.isRequired, fetchInvoice: PropTypes.func.isRequired,
formInvoice: PropTypes.object.isRequired, formInvoice: PropTypes.object.isRequired,
currentTicker: PropTypes.object.isRequired currentTicker: PropTypes.object.isRequired,
isOnchain: PropTypes.bool.isRequired,
isLn: PropTypes.bool.isRequired
} }
export default Form export default Form

56
app/routes/app/components/components/Form/components/Pay/Pay.js

@ -6,8 +6,11 @@ import { btc } from '../../../../../../../utils'
import styles from './Pay.scss' import styles from './Pay.scss'
class Pay extends Component { class Pay extends Component {
componentDidUpdate() { componentDidUpdate(prevProps) {
if (this.props.paymentType !== 'lnd') { this.amountInput.focus() } const { isOnchain, isLn, fetchInvoice, payment_request } = this.props
if (isOnchain) { this.amountInput.focus() }
if ((prevProps.payment_request !== payment_request) && isLn) { fetchInvoice(payment_request) }
} }
render() { render() {
@ -23,27 +26,18 @@ class Pay extends Component {
payInvoice, payInvoice,
currency, currency,
crypto, crypto,
close close,
isOnchain,
isLn
} = this.props } = this.props
const payClicked = () => { const payClicked = () => {
if (payment_request.length !== 124) { return } if (!isOnchain || !isLn) { return }
payInvoice(payment_request) // if (isOnchain) { sendcoins() }
if (isLn) { payInvoice(payment_request) }
close() close()
} }
const paymentRequestOnChange = payreq => {
setPaymentRequest(payreq)
if (payreq.length === 124) {
setPaymentType('ln')
fetchInvoice(payreq)
} else if (payreq.length === 42) {
setPaymentType('onchain')
} else {
setPaymentType('')
}
}
const calculateAmount = value => (currency === 'usd' ? btc.satoshisToUsd(value, currentTicker.price_usd) : btc.satoshisToBtc(value)) const calculateAmount = value => (currency === 'usd' ? btc.satoshisToUsd(value, currentTicker.price_usd) : btc.satoshisToBtc(value))
return ( return (
@ -57,62 +51,62 @@ class Pay extends Component {
ref={(input) => this.amountInput = input} ref={(input) => this.amountInput = input}
size='' size=''
style={ style={
paymentType === 'ln' ? isLn ?
{ width: '75%', fontSize: '85px' } { width: '75%', fontSize: '85px' }
: :
{ width: `${onchainAmount.length > 1 ? (onchainAmount.length * 15) - 5 : 25}%`, fontSize: `${190 - (onchainAmount.length ** 2)}px` } { width: `${onchainAmount.length > 1 ? (onchainAmount.length * 15) - 5 : 25}%`, fontSize: `${190 - (onchainAmount.length ** 2)}px` }
} }
value={paymentType === 'ln' ? calculateAmount(invoiceAmount) : onchainAmount} value={isLn ? calculateAmount(invoiceAmount) : onchainAmount}
onChange={event => setOnchainAmount(event.target.value)} onChange={event => setOnchainAmount(event.target.value)}
id='amount' id='amount'
readOnly={paymentType === 'ln'} readOnly={isLn}
/> />
</section> </section>
<div className={styles.inputContainer}> <div className={styles.inputContainer}>
<div className={styles.info}> <div className={styles.info}>
{(() => { {(() => {
switch(paymentType) { if (isOnchain) {
case 'onchain':
return ( return (
<span>{`You're about to send ${onchainAmount} on-chain which should take around 10 minutes`}</span> <span>{`You're about to send ${onchainAmount} on-chain which should take around 10 minutes`}</span>
) )
case 'ln': } else if (isLn) {
return ( return (
<span>{`You're about to send ${calculateAmount(invoiceAmount)} over the Lightning Network which will be instant`}</span> <span>{`You're about to send ${calculateAmount(invoiceAmount)} over the Lightning Network which will be instant`}</span>
) )
default: } else {
return null return null
} }
})()} })()}
</div> </div>
<aside className={styles.paymentIcon}> <aside className={styles.paymentIcon}>
{(() => { {(() => {
switch(paymentType) { if (isOnchain) {
case 'onchain':
return ( return (
<i> <i>
<span>on-chain</span> <span>on-chain</span>
<FaChain /> <FaChain />
</i> </i>
) )
case 'ln': } else if (isLn) {
return ( return (
<i> <i>
<span>lightning network</span> <span>lightning network</span>
<FaBolt /> <FaBolt />
</i> </i>
) )
default: } else {
return null return null
} }
})()} })()}
{
}
</aside> </aside>
<section className={styles.input}> <section className={styles.input}>
<input <input
type='text' type='text'
placeholder='Payment request or bitcoin address' placeholder='Payment request or bitcoin address'
value={payment_request} value={payment_request}
onChange={event => paymentRequestOnChange(event.target.value)} onChange={event => setPaymentRequest(event.target.value)}
id='paymentRequest' id='paymentRequest'
/> />
</section> </section>
@ -138,7 +132,9 @@ Pay.propTypes = {
payInvoice: PropTypes.func.isRequired, payInvoice: PropTypes.func.isRequired,
currency: PropTypes.string.isRequired, currency: PropTypes.string.isRequired,
crypto: PropTypes.string.isRequired, crypto: PropTypes.string.isRequired,
close: PropTypes.func.isRequired close: PropTypes.func.isRequired,
isOnchain: PropTypes.bool.isRequired,
isLn: PropTypes.bool.isRequired
} }
export default Pay export default Pay

3
app/routes/app/components/components/Form/components/Pay/Pay.scss

@ -15,7 +15,7 @@
justify-content: center; justify-content: center;
min-height: 120px; min-height: 120px;
margin-bottom: 20px; margin-bottom: 20px;
transition: all 0.25s; min-height: 175px;
&.ln { &.ln {
opacity: 0.75; opacity: 0.75;
@ -57,7 +57,6 @@
width: 100%; width: 100%;
padding: 40px 0; padding: 40px 0;
cursor: pointer; cursor: pointer;
transition: all 0.25s;
.info { .info {
margin-bottom: 10px; margin-bottom: 10px;

7
app/routes/app/containers/AppContainer.js

@ -13,7 +13,8 @@ import {
setOnchainAmount, setOnchainAmount,
setMessage, setMessage,
setPubkey, setPubkey,
setPaymentRequest setPaymentRequest,
formSelectors
} from '../../../reducers/form' } from '../../../reducers/form'
const mapDispatchToProps = { const mapDispatchToProps = {
@ -41,7 +42,9 @@ const mapStateToProps = state => ({
form: state.form, form: state.form,
invoice: state.invoice, invoice: state.invoice,
currentTicker: tickerSelectors.currentTicker(state) currentTicker: tickerSelectors.currentTicker(state),
isOnchain: formSelectors.isOnchain(state),
isLn: formSelectors.isLn(state)
}) })
export default connect(mapStateToProps, mapDispatchToProps)(App) export default connect(mapStateToProps, mapDispatchToProps)(App)

Loading…
Cancel
Save