Progress on sending transactions

This commit is contained in:
6ea86b96 2017-04-23 12:55:47 +07:00 committed by Jeremy Kauffman
parent 1a8929f8d6
commit cf0fd96ed8
6 changed files with 155 additions and 19 deletions

View file

@ -1,5 +1,13 @@
import * as types from 'constants/action_types' import * as types from 'constants/action_types'
import lbry from 'lbry' import lbry from 'lbry'
import {
selectDraftTransaction,
selectDraftTransactionAmount,
selectBalance,
} from 'selectors/wallet'
import {
doOpenModal,
} from 'actions/app'
export function doUpdateBalance(balance) { export function doUpdateBalance(balance) {
return { return {
@ -59,7 +67,59 @@ export function doCheckAddressIsMine(address) {
} }
} }
export function doSendToAddress() { export function doSendDraftTransaction() {
return function(dispatch, getState) { return function(dispatch, getState) {
const state = getState()
const draftTx = selectDraftTransaction(state)
const balance = selectBalance(state)
const amount = selectDraftTransactionAmount(state)
if (balance - amount < 1) {
return dispatch(doOpenModal('insufficientBalance'))
}
dispatch({
type: types.SEND_TRANSACTION_STARTED,
})
const successCallback = (results) => {
if(results === true) {
dispatch({
type: types.SEND_TRANSACTION_COMPLETED,
})
dispatch(doOpenModal('transactionSuccessful'))
}
else {
dispatch({
type: types.SEND_TRANSACTION_FAILED,
data: { error: results }
})
dispatch(doOpenModal('transactionFailed'))
}
}
const errorCallback = (error) => {
dispatch({
type: types.SEND_TRANSACTION_FAILED,
data: { error: error.message }
})
dispatch(doOpenModal('transactionFailed'))
}
lbry.sendToAddress(draftTx.amount, draftTx.address, successCallback, errorCallback);
}
}
export function doSetDraftTransactionAmount(amount) {
return {
type: types.SET_DRAFT_TRANSACTION_AMOUNT,
data: { amount }
}
}
export function doSetDraftTransactionAddress(address) {
return {
type: types.SET_DRAFT_TRANSACTION_ADDRESS,
data: { address }
} }
} }

View file

@ -28,3 +28,8 @@ export const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'
export const UPDATE_BALANCE = 'UPDATE_BALANCE' export const UPDATE_BALANCE = 'UPDATE_BALANCE'
export const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED' export const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'
export const CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED' export const CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED'
export const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'
export const SET_DRAFT_TRANSACTION_ADDRESS = 'SET_DRAFT_TRANSACTION_ADDRESS'
export const SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED'
export const SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED'
export const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'

View file

@ -8,7 +8,9 @@ import {
import { import {
doGetNewAddress, doGetNewAddress,
doCheckAddressIsMine, doCheckAddressIsMine,
doSendToAddress, doSendDraftTransaction,
doSetDraftTransactionAmount,
doSetDraftTransactionAddress,
} from 'actions/wallet' } from 'actions/wallet'
import { import {
selectCurrentPage, selectCurrentPage,
@ -21,6 +23,8 @@ import {
selectIsFetchingTransactions, selectIsFetchingTransactions,
selectReceiveAddress, selectReceiveAddress,
selectGettingNewAddress, selectGettingNewAddress,
selectDraftTransactionAmount,
selectDraftTransactionAddress,
} from 'selectors/wallet' } from 'selectors/wallet'
import WalletPage from './view' import WalletPage from './view'
@ -33,17 +37,17 @@ const select = (state) => ({
receiveAddress: selectReceiveAddress(state), receiveAddress: selectReceiveAddress(state),
gettingNewAddress: selectGettingNewAddress(state), gettingNewAddress: selectGettingNewAddress(state),
modal: selectCurrentModal(state), modal: selectCurrentModal(state),
address: null, address: selectDraftTransactionAddress(state),
amount: 0.0, amount: selectDraftTransactionAmount(state),
}) })
const perform = (dispatch) => ({ const perform = (dispatch) => ({
closeModal: () => dispatch(doCloseModal()), closeModal: () => dispatch(doCloseModal()),
getNewAddress: () => dispatch(doGetNewAddress()), getNewAddress: () => dispatch(doGetNewAddress()),
checkAddressIsMine: (address) => dispatch(doCheckAddressIsMine(address)), checkAddressIsMine: (address) => dispatch(doCheckAddressIsMine(address)),
sendToAddress: () => dispatch(doSendToAddress()), sendToAddress: () => dispatch(doSendDraftTransaction()),
setAmount: () => console.log('set amount'), setAmount: (event) => dispatch(doSetDraftTransactionAmount(event.target.value)),
setAddress: () => console.log('set address'), setAddress: (event) => dispatch(doSetDraftTransactionAddress(event.target.value)),
}) })
export default connect(select, perform)(WalletPage) export default connect(select, perform)(WalletPage)

View file

@ -57,8 +57,6 @@ const SendToAddressSection = (props) => {
address, address,
} = props } = props
const results = null
return ( return (
<section className="card"> <section className="card">
<form onSubmit={sendToAddress}> <form onSubmit={sendToAddress}>
@ -66,26 +64,25 @@ const SendToAddressSection = (props) => {
<h3>Send Credits</h3> <h3>Send Credits</h3>
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow label="Amount" postfix="LBC" step="0.01" type="number" placeholder="1.23" size="10" onChange={setAmount} /> <FormRow label="Amount" postfix="LBC" step="0.01" type="number" placeholder="1.23" size="10" onChange={setAmount} value={amount} />
</div> </div>
<div className="card__content"> <div className="card__content">
<FormRow label="Recipient Address" placeholder="bbFxRyXXXXXXXXXXXZD8nE7XTLUxYnddTs" type="text" size="60" onChange={setAddress} /> <FormRow label="Recipient Address" placeholder="bbFxRyXXXXXXXXXXXZD8nE7XTLUxYnddTs" type="text" size="60" onChange={setAddress} value={address} />
</div> </div>
<div className="card__actions card__actions--form-submit"> <div className="card__actions card__actions--form-submit">
<Link button="primary" label="Send" onClick={sendToAddress} disabled={!(parseFloat(amount) > 0.0) || !address} /> <Link button="primary" label="Send" onClick={sendToAddress} disabled={!(parseFloat(amount) > 0.0) || !address} />
<input type='submit' className='hidden' /> <input type='submit' className='hidden' />
</div> </div>
{
results ?
<div className="card__content">
<h4>Results</h4>
{results}
</div> : ''
}
</form> </form>
{modal == 'insufficientBalance' && <Modal isOpen={true} contentLabel="Insufficient balance" onConfirmed={closeModal}> {modal == 'insufficientBalance' && <Modal isOpen={true} contentLabel="Insufficient balance" onConfirmed={closeModal}>
Insufficient balance: after this transaction you would have less than 1 LBC in your wallet. Insufficient balance: after this transaction you would have less than 1 LBC in your wallet.
</Modal>} </Modal>}
{modal == 'transactionSuccessful' && <Modal isOpen={true} contentLabel="Transaction successful" onConfirmed={closeModal}>
Your transaction was successfully placed in the queue.
</Modal>}
{modal == 'transactionFailed' && <Modal isOpen={true} contentLabel="Transaction failed" onConfirmed={closeModal}>
Something went wrong:
</Modal>}
</section> </section>
) )
} }

View file

@ -2,12 +2,18 @@ import * as types from 'constants/action_types'
const reducers = {} const reducers = {}
const address = sessionStorage.getItem('receiveAddress') const address = sessionStorage.getItem('receiveAddress')
const buildDraftTransaction = () => ({
amount: undefined,
address: undefined
})
const defaultState = { const defaultState = {
balance: 0, balance: 0,
transactions: [], transactions: [],
fetchingTransactions: false, fetchingTransactions: false,
receiveAddress: address, receiveAddress: address,
gettingNewAddress: false, gettingNewAddress: false,
draftTransaction: buildDraftTransaction()
} }
reducers[types.FETCH_TRANSACTIONS_STARTED] = function(state, action) { reducers[types.FETCH_TRANSACTIONS_STARTED] = function(state, action) {
@ -69,6 +75,55 @@ reducers[types.CHECK_ADDRESS_IS_MINE_COMPLETED] = function(state, action) {
}) })
} }
reducers[types.SET_DRAFT_TRANSACTION_AMOUNT] = function(state, action) {
const oldDraft = state.draftTransaction
const newDraft = Object.assign({}, oldDraft, {
amount: parseFloat(action.data.amount)
})
return Object.assign({}, state, {
draftTransaction: newDraft
})
}
reducers[types.SET_DRAFT_TRANSACTION_ADDRESS] = function(state, action) {
const oldDraft = state.draftTransaction
const newDraft = Object.assign({}, oldDraft, {
address: action.data.address
})
return Object.assign({}, state, {
draftTransaction: newDraft
})
}
reducers[types.SEND_TRANSACTION_STARTED] = function(state, action) {
const newDraftTransaction = Object.assign({}, state.draftTransaction, {
sending: true
})
return Object.assign({}, state, {
draftTransaction: newDraftTransaction
})
}
reducers[types.SEND_TRANSACTION_COMPLETED] = function(state, action) {
return Object.assign({}, state, {
draftTransaction: buildDraftTransaction()
})
}
reducers[types.SEND_TRANSACTION_FAILED] = function(state, action) {
const newDraftTransaction = Object.assign({}, state.draftTransaction, {
sending: false,
error: action.data.error
})
return Object.assign({}, state, {
draftTransaction: newDraftTransaction
})
}
export default function reducer(state = defaultState, action) { export default function reducer(state = defaultState, action) {
const handler = reducers[action.type]; const handler = reducers[action.type];
if (handler) return handler(state, action); if (handler) return handler(state, action);

View file

@ -92,3 +92,18 @@ export const shouldCheckAddressIsMine = createSelector(
return true return true
} }
) )
export const selectDraftTransaction = createSelector(
_selectState,
(state) => state.draftTransaction || buildDraftTransaction()
)
export const selectDraftTransactionAmount = createSelector(
selectDraftTransaction,
(draft) => draft.amount
)
export const selectDraftTransactionAddress = createSelector(
selectDraftTransaction,
(draft) => draft.address
)