add destination tag to Ripple send form

pull/320/head
Szymon Lesisz 5 years ago
parent ca160451fc
commit 33a9a28114

@ -244,6 +244,23 @@ export const onFeeChange = (fee: string): ThunkAction => (dispatch: Dispatch, ge
});
};
/*
* Called from UI on "advanced / destination tag" field change
*/
export const onDestinationTagChange = (destinationTag: string): ThunkAction => (dispatch: Dispatch, getState: GetState): void => {
const state: State = getState().sendFormRipple;
dispatch({
type: SEND.CHANGE,
networkType: 'ripple',
state: {
...state,
untouched: false,
touched: { ...state.touched, destinationTag: true },
destinationTag,
},
});
};
/*
* Called from UI from "send" button
*/
@ -279,6 +296,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge
payment: {
amount,
destination: currentState.address,
destinationTag: currentState.destinationTag.length ? parseInt(currentState.destinationTag, 10) : undefined,
},
},
});
@ -346,5 +364,6 @@ export default {
onFeeLevelChange,
updateFeeLevels,
onFeeChange,
onDestinationTagChange,
onSend,
};

@ -73,6 +73,7 @@ export const validation = (): PayloadAction<State> => (dispatch: Dispatch, getSt
state = dispatch(addressLabel(state));
state = dispatch(amountValidation(state));
state = dispatch(feeValidation(state));
state = dispatch(destinationTagValidation(state));
return state;
};
@ -229,6 +230,19 @@ export const feeValidation = ($state: State): PayloadAction<State> => (dispatch:
}
return state;
};
/*
* Destination Tag value validation
*/
export const destinationTagValidation = ($state: State): PayloadAction<State> => (): State => {
const state = { ...$state };
if (!state.touched.destinationTag) return state;
const { destinationTag } = state;
if (destinationTag.length > 0 && !destinationTag.match(ABS_RE)) {
state.errors.destinationTag = 'Destination tag must be an absolute number';
}
return state;
};
/*

@ -27,6 +27,7 @@ export type State = {
fee: string;
feeNeedsUpdate: boolean;
sequence: string;
destinationTag: string;
total: string;
errors: {[k: string]: string};
@ -56,6 +57,7 @@ export const initialState: State = {
fee: '0',
feeNeedsUpdate: false,
sequence: '0',
destinationTag: '',
total: '0',
errors: {},

@ -35,7 +35,7 @@ const AdvancedSettingsWrapper = styled.div`
border-top: 1px solid ${colors.DIVIDER};
`;
const GasInputRow = styled.div`
const InputRow = styled.div`
width: 100%;
display: flex;
@ -44,7 +44,7 @@ const GasInputRow = styled.div`
}
`;
const GasInput = styled(Input)`
const StyledInput = styled(Input)`
/* min-height: 85px; */
padding-bottom: 28px;
&:first-child {
@ -75,6 +75,17 @@ const getFeeInputState = (feeErrors: string, feeWarnings: string): string => {
return state;
};
const getDestinationTagInputState = (errors: string, warnings: string): string => {
let state = '';
if (warnings && !errors) {
state = 'warning';
}
if (errors) {
state = 'error';
}
return state;
};
const Left = styled.div`
display: flex;
align-items: center;
@ -91,15 +102,17 @@ const AdvancedForm = (props: Props) => {
warnings,
infos,
fee,
destinationTag,
} = props.sendForm;
const {
onFeeChange,
onDestinationTagChange,
} = props.sendFormActions;
return (
<AdvancedSettingsWrapper>
<GasInputRow>
<GasInput
<InputRow>
<StyledInput
state={getFeeInputState(errors.fee, warnings.fee)}
autoComplete="off"
autoCorrect="off"
@ -132,7 +145,43 @@ const AdvancedForm = (props: Props) => {
value={fee}
onChange={event => onFeeChange(event.target.value)}
/>
</GasInputRow>
</InputRow>
<InputRow>
<StyledInput
state={getDestinationTagInputState(errors.destinationTag, warnings.destinationTag)}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
spellCheck="false"
topLabel={(
<InputLabelWrapper>
<Left>
Destination tag
<Tooltip
content={(
<React.Fragment>
An arbitrary unsigned 32-bit integer that identifies a reason for payment or a non-Ripple account.
</React.Fragment>
)}
maxWidth={410}
readMoreLink="https://developers.ripple.com/rippleapi-reference.html#payment"
placement="top"
>
<Icon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={24}
/>
</Tooltip>
</Left>
</InputLabelWrapper>
)}
bottomText={errors.destinationTag || warnings.destinationTag || infos.destinationTag}
value={destinationTag}
onChange={event => onDestinationTagChange(event.target.value)}
/>
</InputRow>
<AdvancedSettingsSendButtonWrapper>
{ props.children }

Loading…
Cancel
Save