mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-13 11:58:58 +00:00
add destination tag to Ripple send form
This commit is contained in:
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…
Reference in New Issue
Block a user