Browse Source

fix(onchain): fix the UX for on-chain payments to be like the UX for LN payments

renovate/lint-staged-8.x
Jack Mallers 7 years ago
parent
commit
efc5cf0f02
  1. 19
      app/components/Wallet/Wallet.js
  2. 2
      app/main.dev.js
  3. 45
      app/reducers/transaction.js
  4. 2
      app/routes/activity/containers/ActivityContainer.js

19
app/components/Wallet/Wallet.js

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import { FaAngleDown } from 'react-icons/lib/fa' import { FaAngleDown } from 'react-icons/lib/fa'
import Isvg from 'react-inlinesvg' import Isvg from 'react-inlinesvg'
import { btc } from 'utils' import { btc, blockExplorer } from 'utils'
import Value from 'components/Value' import Value from 'components/Value'
import AnimatedCheckmark from 'components/AnimatedCheckmark' import AnimatedCheckmark from 'components/AnimatedCheckmark'
@ -22,7 +22,8 @@ const Wallet = ({
openPayForm, openPayForm,
openRequestForm, openRequestForm,
showPayLoadingScreen, showPayLoadingScreen,
showSuccessPayScreen showSuccessPayScreen,
successTransactionScreen
}) => { }) => {
const usdAmount = btc.satoshisToUsd((parseInt(balance.walletBalance, 10) + parseInt(balance.channelBalance, 10)), currentTicker.price_usd) const usdAmount = btc.satoshisToUsd((parseInt(balance.walletBalance, 10) + parseInt(balance.channelBalance, 10)), currentTicker.price_usd)
@ -73,7 +74,7 @@ const Wallet = ({
showPayLoadingScreen && showPayLoadingScreen &&
<span> <span>
<section className={`${styles.spinner} ${styles.icon}`} /> <section className={`${styles.spinner} ${styles.icon}`} />
<section>Sending your lightning payment...</section> <section>Sending your transaction...</section>
</span> </span>
} }
{ {
@ -83,6 +84,15 @@ const Wallet = ({
<section>Successfully sent payment</section> <section>Successfully sent payment</section>
</span> </span>
} }
{
successTransactionScreen.show &&
<span>
<section className={styles.icon}><AnimatedCheckmark /></section>
<section>
Successfully <button onClick={() => blockExplorer.showTransaction(successTransactionScreen.txid)}>sent</button> transaction
</section>
</span>
}
</div> </div>
</div> </div>
</div> </div>
@ -99,7 +109,8 @@ Wallet.propTypes = {
openRequestForm: PropTypes.func.isRequired, openRequestForm: PropTypes.func.isRequired,
openReceiveModal: PropTypes.func.isRequired, openReceiveModal: PropTypes.func.isRequired,
showPayLoadingScreen: PropTypes.bool.isRequired, showPayLoadingScreen: PropTypes.bool.isRequired,
showSuccessPayScreen: PropTypes.bool.isRequired showSuccessPayScreen: PropTypes.bool.isRequired,
successTransactionScreen: PropTypes.object.isRequired
} }
export default Wallet export default Wallet

2
app/main.dev.js

@ -164,7 +164,7 @@ const startLnd = (alias, autopilot) => {
'--bitcoin.active', '--bitcoin.active',
'--bitcoin.testnet', '--bitcoin.testnet',
'--bitcoin.node=neutrino', '--bitcoin.node=neutrino',
'--neutrino.connect=btcd0.lightning.computer:18333', '--neutrino.connect=188.166.148.62:18333',
'--neutrino.addpeer=btcd.jackmallers.com:18333', '--neutrino.addpeer=btcd.jackmallers.com:18333',
'--neutrino.addpeer=159.65.48.139:18333', '--neutrino.addpeer=159.65.48.139:18333',
'--neutrino.connect=127.0.0.1:18333', '--neutrino.connect=127.0.0.1:18333',

45
app/reducers/transaction.js

@ -5,7 +5,6 @@ import { newAddress } from './address'
import { fetchBalance } from './balance' import { fetchBalance } from './balance'
import { setFormType } from './form' import { setFormType } from './form'
import { resetPayForm } from './payform' import { resetPayForm } from './payform'
import { showModal } from './modal'
import { setError } from './error' import { setError } from './error'
// ------------------------------------ // ------------------------------------
@ -21,6 +20,9 @@ export const TRANSACTION_FAILED = 'TRANSACTION_FAILED'
export const ADD_TRANSACTION = 'ADD_TRANSACTION' export const ADD_TRANSACTION = 'ADD_TRANSACTION'
export const SHOW_SUCCESS_TRANSACTION_SCREEN = 'SHOW_SUCCESS_TRANSACTION_SCREEN'
export const HIDE_SUCCESS_TRANSACTION_SCREEN = 'HIDE_SUCCESS_TRANSACTION_SCREEN'
// ------------------------------------ // ------------------------------------
// Actions // Actions
// ------------------------------------ // ------------------------------------
@ -36,6 +38,19 @@ export function sendTransaction() {
} }
} }
export function showSuccessTransactionScreen(txid) {
return {
type: SHOW_SUCCESS_TRANSACTION_SCREEN,
txid
}
}
export function hideSuccessTransactionScreen() {
return {
type: HIDE_SUCCESS_TRANSACTION_SCREEN
}
}
// Send IPC event for payments // Send IPC event for payments
export const fetchTransactions = () => (dispatch) => { export const fetchTransactions = () => (dispatch) => {
dispatch(getTransactions()) dispatch(getTransactions())
@ -51,22 +66,27 @@ export const sendCoins = ({
// backend needs amount in satoshis no matter what currency we are using // backend needs amount in satoshis no matter what currency we are using
const amount = btc.convert(currency, 'sats', value) const amount = btc.convert(currency, 'sats', value)
// submit the transaction to LND
dispatch(sendTransaction()) dispatch(sendTransaction())
ipcRenderer.send('lnd', { msg: 'sendCoins', data: { amount, addr } }) ipcRenderer.send('lnd', { msg: 'sendCoins', data: { amount, addr } })
// Close the form modal once the payment was sent to LND
// we will do the loading/success UX on the main page
// so we aren't blocking the user
dispatch(setFormType(null))
} }
// Receive IPC event for successful payment // Receive IPC event for successful payment
// TODO: Add payment to state, not a total re-fetch // TODO: Add payment to state, not a total re-fetch
export const transactionSuccessful = (event, { amount, addr, txid }) => (dispatch) => { export const transactionSuccessful = (event, { txid }) => (dispatch) => {
// Get the new list of transactions (TODO dont do an entire new fetch) // Get the new list of transactions (TODO dont do an entire new fetch)
dispatch(fetchTransactions()) dispatch(fetchTransactions())
// Close the form modal once the payment was succesful
dispatch(setFormType(null))
// Show successful payment state // Show successful payment state
dispatch(showModal('SUCCESSFUL_SEND_COINS', { txid, amount, addr }))
// TODO: Add successful on-chain payment to payments list once payments list supports on-chain and LN
// dispatch({ type: PAYMENT_SUCCESSFULL, payment: { amount, addr, txid, pending: true } })
dispatch({ type: TRANSACTION_SUCCESSFULL }) dispatch({ type: TRANSACTION_SUCCESSFULL })
// Show successful tx state for 5 seconds
dispatch(showSuccessTransactionScreen(txid))
setTimeout(() => dispatch(hideSuccessTransactionScreen()), 5000)
// Fetch new balance // Fetch new balance
dispatch(fetchBalance()) dispatch(fetchBalance())
// Reset the payment form // Reset the payment form
@ -111,7 +131,10 @@ const ACTION_HANDLERS = {
...state, ...state,
transactions: [transaction, ...state.transactions] transactions: [transaction, ...state.transactions]
} }
) ),
[SHOW_SUCCESS_TRANSACTION_SCREEN]: (state, { txid }) => ({ ...state, successTransactionScreen: { show: true, txid } }),
[HIDE_SUCCESS_TRANSACTION_SCREEN]: state => ({ ...state, successTransactionScreen: { show: false, txid: '' } })
} }
// ------------------------------------ // ------------------------------------
@ -120,7 +143,11 @@ const ACTION_HANDLERS = {
const initialState = { const initialState = {
sendingTransaction: false, sendingTransaction: false,
transactionLoading: false, transactionLoading: false,
transactions: [] transactions: [],
successTransactionScreen: {
show: false,
txid: ''
}
} }
export default function transactionReducer(state = initialState, action) { export default function transactionReducer(state = initialState, action) {

2
app/routes/activity/containers/ActivityContainer.js

@ -53,6 +53,7 @@ const mapStateToProps = state => ({
info: state.info, info: state.info,
payment: state.payment, payment: state.payment,
transaction: state.transaction,
invoice: state.invoice, invoice: state.invoice,
invoices: invoiceSelectors.invoices(state), invoices: invoiceSelectors.invoices(state),
@ -79,6 +80,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
currentTicker: stateProps.currentTicker, currentTicker: stateProps.currentTicker,
showPayLoadingScreen: stateProps.showPayLoadingScreen, showPayLoadingScreen: stateProps.showPayLoadingScreen,
showSuccessPayScreen: stateProps.payment.showSuccessPayScreen, showSuccessPayScreen: stateProps.payment.showSuccessPayScreen,
successTransactionScreen: stateProps.transaction.successTransactionScreen,
setCurrency: dispatchProps.setCurrency, setCurrency: dispatchProps.setCurrency,
newAddress: dispatchProps.newAddress, newAddress: dispatchProps.newAddress,

Loading…
Cancel
Save