From cf0fd96ed8a9b649a87571aa64f8e803bdb41504 Mon Sep 17 00:00:00 2001 From: 6ea86b96 <6ea86b96@gmail.com> Date: Sun, 23 Apr 2017 12:55:47 +0700 Subject: [PATCH] Progress on sending transactions --- ui/js/actions/wallet.js | 62 ++++++++++++++++++++++++++++++++- ui/js/constants/action_types.js | 5 +++ ui/js/page/wallet/index.js | 16 +++++---- ui/js/page/wallet/view.jsx | 21 +++++------ ui/js/reducers/wallet.js | 55 +++++++++++++++++++++++++++++ ui/js/selectors/wallet.js | 15 ++++++++ 6 files changed, 155 insertions(+), 19 deletions(-) diff --git a/ui/js/actions/wallet.js b/ui/js/actions/wallet.js index f28ddcbdc..79b22d8d6 100644 --- a/ui/js/actions/wallet.js +++ b/ui/js/actions/wallet.js @@ -1,5 +1,13 @@ import * as types from 'constants/action_types' import lbry from 'lbry' +import { + selectDraftTransaction, + selectDraftTransactionAmount, + selectBalance, +} from 'selectors/wallet' +import { + doOpenModal, +} from 'actions/app' export function doUpdateBalance(balance) { return { @@ -59,7 +67,59 @@ export function doCheckAddressIsMine(address) { } } -export function doSendToAddress() { +export function doSendDraftTransaction() { 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 } } } diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index cafea5c7d..a17303b86 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -28,3 +28,8 @@ export const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED' export const UPDATE_BALANCE = 'UPDATE_BALANCE' 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 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' diff --git a/ui/js/page/wallet/index.js b/ui/js/page/wallet/index.js index 03d6fc48b..ac9095938 100644 --- a/ui/js/page/wallet/index.js +++ b/ui/js/page/wallet/index.js @@ -8,7 +8,9 @@ import { import { doGetNewAddress, doCheckAddressIsMine, - doSendToAddress, + doSendDraftTransaction, + doSetDraftTransactionAmount, + doSetDraftTransactionAddress, } from 'actions/wallet' import { selectCurrentPage, @@ -21,6 +23,8 @@ import { selectIsFetchingTransactions, selectReceiveAddress, selectGettingNewAddress, + selectDraftTransactionAmount, + selectDraftTransactionAddress, } from 'selectors/wallet' import WalletPage from './view' @@ -33,17 +37,17 @@ const select = (state) => ({ receiveAddress: selectReceiveAddress(state), gettingNewAddress: selectGettingNewAddress(state), modal: selectCurrentModal(state), - address: null, - amount: 0.0, + address: selectDraftTransactionAddress(state), + amount: selectDraftTransactionAmount(state), }) const perform = (dispatch) => ({ closeModal: () => dispatch(doCloseModal()), getNewAddress: () => dispatch(doGetNewAddress()), checkAddressIsMine: (address) => dispatch(doCheckAddressIsMine(address)), - sendToAddress: () => dispatch(doSendToAddress()), - setAmount: () => console.log('set amount'), - setAddress: () => console.log('set address'), + sendToAddress: () => dispatch(doSendDraftTransaction()), + setAmount: (event) => dispatch(doSetDraftTransactionAmount(event.target.value)), + setAddress: (event) => dispatch(doSetDraftTransactionAddress(event.target.value)), }) export default connect(select, perform)(WalletPage) diff --git a/ui/js/page/wallet/view.jsx b/ui/js/page/wallet/view.jsx index c4b1c4acb..e1c458f68 100644 --- a/ui/js/page/wallet/view.jsx +++ b/ui/js/page/wallet/view.jsx @@ -33,7 +33,7 @@ class AddressSection extends React.Component {
- +
@@ -57,8 +57,6 @@ const SendToAddressSection = (props) => { address, } = props - const results = null - return (
@@ -66,26 +64,25 @@ const SendToAddressSection = (props) => {

Send Credits

- +
- +
0.0) || !address} />
- { - results ? -
-

Results

- {results} -
: '' - } {modal == 'insufficientBalance' && Insufficient balance: after this transaction you would have less than 1 LBC in your wallet. } + {modal == 'transactionSuccessful' && + Your transaction was successfully placed in the queue. + } + {modal == 'transactionFailed' && + Something went wrong: + } ) } diff --git a/ui/js/reducers/wallet.js b/ui/js/reducers/wallet.js index 4b4f46db1..02cfe2485 100644 --- a/ui/js/reducers/wallet.js +++ b/ui/js/reducers/wallet.js @@ -2,12 +2,18 @@ import * as types from 'constants/action_types' const reducers = {} const address = sessionStorage.getItem('receiveAddress') +const buildDraftTransaction = () => ({ + amount: undefined, + address: undefined +}) + const defaultState = { balance: 0, transactions: [], fetchingTransactions: false, receiveAddress: address, gettingNewAddress: false, + draftTransaction: buildDraftTransaction() } 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) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/ui/js/selectors/wallet.js b/ui/js/selectors/wallet.js index f0f9d1254..5b8dc96a9 100644 --- a/ui/js/selectors/wallet.js +++ b/ui/js/selectors/wallet.js @@ -92,3 +92,18 @@ export const shouldCheckAddressIsMine = createSelector( 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 +)