mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-01-10 02:55:41 +00:00
[FEATURE] Time/block selector
This commit is contained in:
parent
49fa54ba0b
commit
09b1062db1
@ -13,7 +13,8 @@ import {
|
||||
SetGasPriceFieldAction,
|
||||
SetTimeBountyFieldAction,
|
||||
SetWindowStartFieldAction,
|
||||
SetScheduleTimestampFieldAction
|
||||
SetScheduleTimestampFieldAction,
|
||||
SetScheduleTypeAction
|
||||
} from '../actionTypes';
|
||||
import { TypeKeys } from 'actions/transaction/constants';
|
||||
|
||||
@ -107,6 +108,12 @@ const setScheduleTimestampField = (
|
||||
payload
|
||||
});
|
||||
|
||||
type TSetScheduleType = typeof setScheduleType;
|
||||
const setScheduleType = (payload: SetScheduleTypeAction['payload']): SetScheduleTypeAction => ({
|
||||
type: TypeKeys.SCHEDULE_TYPE_SET,
|
||||
payload
|
||||
});
|
||||
|
||||
type TReset = typeof reset;
|
||||
const reset = (payload: ResetAction['payload'] = { include: {}, exclude: {} }): ResetAction => ({
|
||||
type: TypeKeys.RESET,
|
||||
@ -128,6 +135,7 @@ export {
|
||||
TSetWindowStartField,
|
||||
TSetTimeBountyField,
|
||||
TSetScheduleTimestampField,
|
||||
TSetScheduleType,
|
||||
TReset,
|
||||
inputGasLimit,
|
||||
inputGasPrice,
|
||||
@ -143,5 +151,6 @@ export {
|
||||
setGasPriceField,
|
||||
setWindowStartField,
|
||||
setScheduleTimestampField,
|
||||
setScheduleType,
|
||||
reset
|
||||
};
|
||||
|
@ -7,4 +7,5 @@ export * from './current';
|
||||
export * from './timeBounty';
|
||||
export * from './windowStart';
|
||||
export * from './scheduleTimestamp';
|
||||
export * from './scheduleType';
|
||||
export * from './sendEverything';
|
||||
|
10
common/actions/transaction/actionCreators/scheduleType.ts
Normal file
10
common/actions/transaction/actionCreators/scheduleType.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { SetCurrentScheduleTypeAction } from '../actionTypes/scheduleType';
|
||||
import { TypeKeys } from '../';
|
||||
|
||||
export type TSetCurrentScheduleType = typeof setCurrentScheduleType;
|
||||
export const setCurrentScheduleType = (
|
||||
payload: SetCurrentScheduleTypeAction['payload']
|
||||
): SetCurrentScheduleTypeAction => ({
|
||||
type: TypeKeys.CURRENT_SCHEDULE_TYPE,
|
||||
payload
|
||||
});
|
@ -107,6 +107,14 @@ interface SetScheduleTimestampFieldAction {
|
||||
};
|
||||
}
|
||||
|
||||
interface SetScheduleTypeAction {
|
||||
type: TypeKeys.SCHEDULE_TYPE_SET;
|
||||
payload: {
|
||||
raw: string;
|
||||
value: string | null;
|
||||
};
|
||||
}
|
||||
|
||||
type InputFieldAction = InputNonceAction | InputGasLimitAction | InputDataAction;
|
||||
|
||||
type FieldAction =
|
||||
@ -118,7 +126,8 @@ type FieldAction =
|
||||
| SetGasPriceFieldAction
|
||||
| SetTimeBountyFieldAction
|
||||
| SetWindowStartFieldAction
|
||||
| SetScheduleTimestampFieldAction;
|
||||
| SetScheduleTimestampFieldAction
|
||||
| SetScheduleTypeAction;
|
||||
|
||||
export {
|
||||
InputGasLimitAction,
|
||||
@ -138,5 +147,6 @@ export {
|
||||
SetGasPriceFieldAction,
|
||||
SetTimeBountyFieldAction,
|
||||
SetWindowStartFieldAction,
|
||||
SetScheduleTimestampFieldAction
|
||||
SetScheduleTimestampFieldAction,
|
||||
SetScheduleTypeAction
|
||||
};
|
||||
|
12
common/actions/transaction/actionTypes/scheduleType.ts
Normal file
12
common/actions/transaction/actionTypes/scheduleType.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { TypeKeys } from '../constants';
|
||||
|
||||
/* user input */
|
||||
|
||||
interface SetCurrentScheduleTypeAction {
|
||||
type: TypeKeys.CURRENT_SCHEDULE_TYPE;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
type CurrentAction = SetCurrentScheduleTypeAction;
|
||||
|
||||
export { SetCurrentScheduleTypeAction, CurrentAction };
|
@ -28,6 +28,7 @@ export enum TypeKeys {
|
||||
CURRENT_TIME_BOUNTY_SET = 'CURRENT_TIME_BOUNTY_SET',
|
||||
CURRENT_WINDOW_START_SET = 'CURRENT_WINDOW_START_SET',
|
||||
CURRENT_SCHEDULE_TIMESTAMP_SET = 'CURRENT_SCHEDULE_TIMESTAMP_SET',
|
||||
CURRENT_SCHEDULE_TYPE = 'CURRENT_SCHEDULE_TYPE',
|
||||
|
||||
DATA_FIELD_INPUT = 'DATA_FIELD_INPUT',
|
||||
GAS_LIMIT_INPUT = 'GAS_LIMIT_INPUT',
|
||||
@ -47,6 +48,7 @@ export enum TypeKeys {
|
||||
WINDOW_START_FIELD_SET = 'WINDOW_START_FIELD_SET',
|
||||
SCHEDULE_TIMESTAMP_FIELD_SET = 'SCHEDULE_TIMESTAMP_FIELD_SET',
|
||||
SCHEDULE_TIMEZONE_SET = 'SCHEDULE_TIMEZONE_SET',
|
||||
SCHEDULE_TYPE_SET = 'SCHEDULE_TYPE_SET',
|
||||
|
||||
TOKEN_TO_META_SET = 'TOKEN_TO_META_SET',
|
||||
UNIT_META_SET = 'UNIT_META_SET',
|
||||
|
71
common/components/ScheduleType/ScheduleType.tsx
Normal file
71
common/components/ScheduleType/ScheduleType.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import React, { Component } from 'react';
|
||||
import { setScheduleType, TSetScheduleType } from 'actions/transaction';
|
||||
import { connect } from 'react-redux';
|
||||
import translate from 'translations';
|
||||
import { getCurrentScheduleType, ICurrentScheduleType } from 'selectors/transaction';
|
||||
import { AppState } from 'reducers';
|
||||
|
||||
interface DispatchProps {
|
||||
setScheduleType: TSetScheduleType;
|
||||
}
|
||||
|
||||
interface StateProps {
|
||||
currentScheduleType: ICurrentScheduleType;
|
||||
}
|
||||
|
||||
type Props = DispatchProps & StateProps;
|
||||
|
||||
class ScheduleTypeClass extends Component<Props> {
|
||||
public render() {
|
||||
const { currentScheduleType } = this.props;
|
||||
|
||||
return (
|
||||
<div className="input-group-wrapper">
|
||||
<label className="input-group">
|
||||
<div className="row">
|
||||
<div className="col-xs-6">
|
||||
<div className="radio">
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="scheduleType"
|
||||
value="time"
|
||||
onChange={this.handleOnChange}
|
||||
checked={currentScheduleType.value === 'time'}
|
||||
/>
|
||||
{translate('SCHEDULE_type_time')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-xs-6">
|
||||
<div className="radio">
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
name="scheduleType"
|
||||
value="block"
|
||||
onChange={this.handleOnChange}
|
||||
checked={currentScheduleType.value === 'block'}
|
||||
/>
|
||||
{translate('SCHEDULE_type_block')}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private handleOnChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = ev.currentTarget.value;
|
||||
this.props.setScheduleType({ raw: value, value });
|
||||
};
|
||||
}
|
||||
|
||||
export const ScheduleType = connect(
|
||||
(state: AppState) => ({
|
||||
currentScheduleType: getCurrentScheduleType(state)
|
||||
}),
|
||||
{ setScheduleType }
|
||||
)(ScheduleTypeClass);
|
1
common/components/ScheduleType/index.ts
Normal file
1
common/components/ScheduleType/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './ScheduleType';
|
@ -10,6 +10,7 @@ export * from './SendButton';
|
||||
export * from './SigningStatus';
|
||||
export * from './ScheduleTimestampField';
|
||||
export * from './ScheduleTimezoneDropDown';
|
||||
export * from './ScheduleType';
|
||||
export * from '../containers/Tabs/ScheduleTransaction/components';
|
||||
export { default as NonceField } from './NonceField';
|
||||
export { default as Header } from './Header';
|
||||
|
@ -15,7 +15,8 @@ export const EAC_SCHEDULING_CONFIG = {
|
||||
TIME_BOUNTY_DEFAULT: TIME_BOUNTY_MIN,
|
||||
TIME_BOUNTY_MAX: toWei('900', Units.ether.length - 1), // 900 ETH
|
||||
WINDOW_SIZE_IN_BLOCKS: 90,
|
||||
SCHEDULE_TIMESTAMP_FORMAT: 'YYYY-MM-DD HH:mm:ss'
|
||||
SCHEDULE_TIMESTAMP_FORMAT: 'YYYY-MM-DD HH:mm:ss',
|
||||
DEFAULT_SCHEDULING_METHOD: 'time'
|
||||
};
|
||||
|
||||
export const EAC_ADDRESSES = {
|
||||
|
@ -26,6 +26,10 @@ const INITIAL_STATE: State = {
|
||||
timeBounty: {
|
||||
raw: fromWei(EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT, 'ether'),
|
||||
value: EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT
|
||||
},
|
||||
scheduleType: {
|
||||
raw: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD,
|
||||
value: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD
|
||||
}
|
||||
};
|
||||
|
||||
@ -82,6 +86,8 @@ export const fields = (
|
||||
return updateField('windowStart')(state, action);
|
||||
case TK.SCHEDULE_TIMESTAMP_FIELD_SET:
|
||||
return updateField('scheduleTimestamp')(state, action);
|
||||
case TK.SCHEDULE_TYPE_SET:
|
||||
return updateField('scheduleType')(state, action);
|
||||
case TK.TOKEN_TO_ETHER_SWAP:
|
||||
return tokenToEther(state, action);
|
||||
case TK.ETHER_TO_TOKEN_SWAP:
|
||||
|
@ -4,7 +4,8 @@ import {
|
||||
SetNonceFieldAction,
|
||||
SetGasLimitFieldAction,
|
||||
SetWindowStartFieldAction,
|
||||
SetScheduleTimestampFieldAction
|
||||
SetScheduleTimestampFieldAction,
|
||||
SetScheduleTypeAction
|
||||
} from 'actions/transaction';
|
||||
import { Wei } from 'libs/units';
|
||||
|
||||
@ -18,4 +19,5 @@ export interface State {
|
||||
timeBounty: { raw: string; value: Wei };
|
||||
windowStart: SetWindowStartFieldAction['payload'];
|
||||
scheduleTimestamp: SetScheduleTimestampFieldAction['payload'];
|
||||
scheduleType: SetScheduleTypeAction['payload'];
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ const getNonce = (state: AppState) => getFields(state).nonce;
|
||||
const getTimeBounty = (state: AppState) => getFields(state).timeBounty;
|
||||
const getWindowStart = (state: AppState) => getFields(state).windowStart;
|
||||
const getScheduleTimestamp = (state: AppState) => getFields(state).scheduleTimestamp;
|
||||
const getScheduleType = (state: AppState) => getFields(state).scheduleType;
|
||||
|
||||
const getDataExists = (state: AppState) => {
|
||||
const { value } = getData(state);
|
||||
@ -41,5 +42,6 @@ export {
|
||||
getValidGasCost,
|
||||
getTimeBounty,
|
||||
getWindowStart,
|
||||
getScheduleTimestamp
|
||||
getScheduleTimestamp,
|
||||
getScheduleType
|
||||
};
|
||||
|
@ -7,4 +7,5 @@ export * from './current';
|
||||
export * from './windowStart';
|
||||
export * from './timeBounty';
|
||||
export * from './scheduleTimestamp';
|
||||
export * from './scheduleType';
|
||||
export * from './network';
|
||||
|
11
common/selectors/transaction/scheduleType.ts
Normal file
11
common/selectors/transaction/scheduleType.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { AppState } from 'reducers';
|
||||
import { getScheduleType } from './fields';
|
||||
|
||||
interface ICurrentScheduleType {
|
||||
raw: string;
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
const getCurrentScheduleType = (state: AppState): ICurrentScheduleType => getScheduleType(state);
|
||||
|
||||
export { getCurrentScheduleType, ICurrentScheduleType };
|
@ -1,6 +1,13 @@
|
||||
import { AppState } from 'reducers';
|
||||
import { getCurrentTo, getCurrentValue } from './current';
|
||||
import { getFields, getData, getWindowStart, getNonce, getTimeBounty } from './fields';
|
||||
import {
|
||||
getFields,
|
||||
getData,
|
||||
getWindowStart,
|
||||
getNonce,
|
||||
getTimeBounty,
|
||||
getScheduleType
|
||||
} from './fields';
|
||||
import { makeTransaction, IHexStrTransaction } from 'libs/transaction';
|
||||
import EthTx from 'ethereumjs-tx';
|
||||
import { getUnit } from 'selectors/transaction/meta';
|
||||
@ -66,6 +73,7 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
|
||||
const dataExists = getDataExists(state);
|
||||
const callData = getData(state);
|
||||
const validGasCost = getValidGasCost(state);
|
||||
const scheduleType = getScheduleType(state);
|
||||
const windowStart = getWindowStart(state);
|
||||
const gasLimit = getGasLimit(state);
|
||||
const nonce = getNonce(state);
|
||||
@ -98,7 +106,11 @@ const getSchedulingTransaction = (state: AppState): IGetTransaction => {
|
||||
);
|
||||
|
||||
const transactionOptions = {
|
||||
to: Address(EAC_ADDRESSES.KOVAN.blockScheduler),
|
||||
to: Address(
|
||||
scheduleType.value === 'time'
|
||||
? EAC_ADDRESSES.KOVAN.timestampScheduler
|
||||
: EAC_ADDRESSES.KOVAN.blockScheduler
|
||||
),
|
||||
data: transactionData,
|
||||
gasLimit: EAC_SCHEDULING_CONFIG.SCHEDULING_GAS_LIMIT,
|
||||
gasPrice: gasPrice.value,
|
||||
|
@ -18,7 +18,11 @@ describe('fields reducer', () => {
|
||||
value: EAC_SCHEDULING_CONFIG.TIME_BOUNTY_DEFAULT
|
||||
},
|
||||
windowStart: { raw: '', value: null },
|
||||
scheduleTimestamp: { raw: '', value: null }
|
||||
scheduleTimestamp: { raw: '', value: null },
|
||||
scheduleType: {
|
||||
raw: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD,
|
||||
value: EAC_SCHEDULING_CONFIG.DEFAULT_SCHEDULING_METHOD
|
||||
}
|
||||
};
|
||||
const testPayload = { raw: 'test', value: null };
|
||||
|
||||
|
@ -51,6 +51,10 @@ describe('fields selector', () => {
|
||||
scheduleTimestamp: {
|
||||
raw: '',
|
||||
value: null
|
||||
},
|
||||
scheduleType: {
|
||||
raw: 'time',
|
||||
value: 'time'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -55,6 +55,10 @@ describe('helpers selector', () => {
|
||||
scheduleTimestamp: {
|
||||
raw: '',
|
||||
value: null
|
||||
},
|
||||
scheduleType: {
|
||||
raw: 'time',
|
||||
value: 'time'
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -69,7 +73,8 @@ describe('helpers selector', () => {
|
||||
value: Wei('1000000000'),
|
||||
timeBounty: Wei('1500'),
|
||||
windowStart: null,
|
||||
scheduleTimestamp: null
|
||||
scheduleTimestamp: null,
|
||||
scheduleType: 'time'
|
||||
};
|
||||
expect(reduceToValues(state.transaction.fields)).toEqual(values);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user