@@ -2,48 +2,62 @@ import React, { useCallback, useEffect } from 'react'
22import { IDropdownOption } from 'office-ui-fabric-react'
33
44import { AppActions , StateDispatch } from 'states/stateProvider/reducer'
5+ import { calculateCycles } from 'services/remote/wallets'
56
6- import { Message } from 'utils/const'
7+ import { Message , MAX_DECIMAL_DIGITS } from 'utils/const'
78import { verifyAddress , verifyAmountRange } from 'utils/validators'
9+ import { outputsToTotalCapacity } from 'utils/formatters'
810import { TransactionOutput } from '.'
911
10- const validateTransactionParams = ( { items, dispatch } : { items : TransactionOutput [ ] ; dispatch : StateDispatch } ) => {
12+ let cyclesTimer : ReturnType < typeof setTimeout >
13+
14+ const validateTransactionParams = ( { items, dispatch } : { items : TransactionOutput [ ] ; dispatch ?: StateDispatch } ) => {
1115 const errorAction = {
1216 type : AppActions . AddNotification ,
1317 payload : {
1418 type : 'warning' ,
1519 timestamp : Date . now ( ) ,
1620 content : Message . AtLeastOneAddressNeeded ,
21+ meta : { } ,
1722 } ,
1823 }
1924 if ( ! items . length || ! items [ 0 ] . address ) {
20- dispatch ( errorAction )
25+ if ( dispatch ) {
26+ dispatch ( errorAction )
27+ }
2128 return false
2229 }
2330 const invalid = items . some (
2431 ( item ) : boolean => {
25- if ( ! verifyAddress ( item . address ) ) {
32+ const isAddressValid = verifyAddress ( item . address )
33+ if ( typeof isAddressValid === 'string' ) {
2634 errorAction . payload . content = Message . InvalidAddress
35+ errorAction . payload . meta = { address : item . address }
2736 return true
2837 }
2938 if ( Number . isNaN ( + item . amount ) || + item . amount < 0 ) {
3039 errorAction . payload . content = Message . InvalidAmount
40+ errorAction . payload . meta = { amount : item . amount }
3141 return true
3242 }
33- if ( ! verifyAmountRange ( item . amount ) ) {
34- errorAction . payload . content = Message . AmountTooSmall
43+ const [ , decimal = '' ] = item . amount . split ( '.' )
44+ if ( decimal . length > MAX_DECIMAL_DIGITS ) {
45+ errorAction . payload . content = Message . DecimalExceed
46+ errorAction . payload . meta = { amount : item . amount }
3547 return true
3648 }
37- const [ , decimal = '' ] = item . amount . split ( '.' )
38- if ( decimal . length > 8 ) {
39- errorAction . payload . content = Message . InvalidAmount
49+ if ( ! verifyAmountRange ( item . amount ) ) {
50+ errorAction . payload . content = Message . AmountTooSmall
51+ errorAction . payload . meta = { amount : item . amount }
4052 return true
4153 }
4254 return false
4355 }
4456 )
4557 if ( invalid ) {
46- dispatch ( errorAction )
58+ if ( dispatch ) {
59+ dispatch ( errorAction )
60+ }
4761 return false
4862 }
4963 return true
@@ -84,6 +98,39 @@ const useRemoveTransactionOutput = (dispatch: StateDispatch) =>
8498 [ dispatch ]
8599 )
86100
101+ const useOnTransactionChange = ( walletID : string , items : TransactionOutput [ ] , dispatch : StateDispatch ) => {
102+ useEffect ( ( ) => {
103+ clearTimeout ( cyclesTimer )
104+ cyclesTimer = setTimeout ( ( ) => {
105+ if ( validateTransactionParams ( { items } ) ) {
106+ calculateCycles ( {
107+ walletID,
108+ capacities : outputsToTotalCapacity ( items ) ,
109+ } )
110+ . then ( response => {
111+ if ( response . status ) {
112+ if ( Number . isNaN ( + response . result ) ) {
113+ throw new Error ( 'Invalid Cycles' )
114+ }
115+ dispatch ( {
116+ type : AppActions . UpdateSendCycles ,
117+ payload : response . result ,
118+ } )
119+ } else {
120+ throw new Error ( 'Cycles Not Calculated' )
121+ }
122+ } )
123+ . catch ( ( ) => {
124+ dispatch ( {
125+ type : AppActions . UpdateSendCycles ,
126+ payload : '0' ,
127+ } )
128+ } )
129+ }
130+ } , 300 )
131+ } , [ walletID , items , dispatch ] )
132+ }
133+
87134const useOnSubmit = ( items : TransactionOutput [ ] , dispatch : StateDispatch ) =>
88135 useCallback (
89136 ( walletID : string = '' ) => ( ) => {
@@ -111,7 +158,14 @@ const useOnItemChange = (updateTransactionOutput: Function) =>
111158 value ?: string
112159 ) => {
113160 if ( undefined !== value ) {
114- updateTransactionOutput ( field ) ( idx ) ( value )
161+ if ( field === 'amount' ) {
162+ if ( Number . isNaN ( + value ) || / [ ^ \d . ] / . test ( value ) ) {
163+ return
164+ }
165+ updateTransactionOutput ( field ) ( idx ) ( value )
166+ } else {
167+ updateTransactionOutput ( field ) ( idx ) ( value )
168+ }
115169 }
116170 } ,
117171 [ updateTransactionOutput ]
@@ -131,9 +185,10 @@ const useUpdateTransactionPrice = (dispatch: StateDispatch) =>
131185 useCallback (
132186 ( _e : React . FormEvent < HTMLInputElement | HTMLTextAreaElement > , value ?: string ) => {
133187 if ( undefined !== value ) {
188+ const price = value . replace ( / [ ^ \d ] / g, '' )
134189 dispatch ( {
135190 type : AppActions . UpdateSendPrice ,
136- payload : value . trim ( ) ,
191+ payload : price ,
137192 } )
138193 }
139194 } ,
@@ -188,6 +243,7 @@ export const useInitialize = (
188243 } , [ address , dispatch , history , updateTransactionOutput ] )
189244
190245 return {
246+ useOnTransactionChange,
191247 updateTransactionOutput,
192248 onItemChange,
193249 onCapacityUnitChange,
0 commit comments