Custom DPaths, Improvements, and Fix SingularDTV (#1351)
* Add dpath to select option display * Re-enable custom path * Make it a submittable form to behave better with HW wallets * Adjust styles * Widen regex to allow for SingularDTV dpath
This commit is contained in:
parent
f42b81ac8a
commit
7521337bda
|
@ -7,19 +7,42 @@
|
||||||
|
|
||||||
&-label {
|
&-label {
|
||||||
font-size: $font-size-medium;
|
font-size: $font-size-medium;
|
||||||
margin-right: 16px;
|
margin-right: $space-md;
|
||||||
line-height: $input-height-base;
|
line-height: $input-height-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-select {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
small {
|
||||||
|
padding-left: 5px;
|
||||||
|
opacity: 0.5;
|
||||||
|
font-size: 11px;
|
||||||
|
@include mono;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-custom {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: $space-md;
|
||||||
|
|
||||||
|
.input-group-input {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-submit {
|
||||||
|
margin-left: $space-md;
|
||||||
|
padding-left: $space;
|
||||||
|
padding-right: $space;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
.form-control {
|
.form-control {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: auto;
|
width: auto;
|
||||||
margin: 0 0 0 10px;
|
margin: 0 0 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Select {
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-addresses {
|
&-addresses {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import Select, { Option } from 'react-select';
|
||||||
|
import translate from 'translations';
|
||||||
import {
|
import {
|
||||||
DeterministicWalletData,
|
DeterministicWalletData,
|
||||||
getDeterministicWallets,
|
getDeterministicWallets,
|
||||||
|
@ -9,14 +13,11 @@ import {
|
||||||
import Modal, { IButton } from 'components/ui/Modal';
|
import Modal, { IButton } from 'components/ui/Modal';
|
||||||
import { AppState } from 'reducers';
|
import { AppState } from 'reducers';
|
||||||
import { isValidPath } from 'libs/validators';
|
import { isValidPath } from 'libs/validators';
|
||||||
import React from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { getNetworkConfig } from 'selectors/config';
|
import { getNetworkConfig } from 'selectors/config';
|
||||||
import { getTokens, MergedToken } from 'selectors/wallet';
|
import { getTokens, MergedToken } from 'selectors/wallet';
|
||||||
import { UnitDisplay, Input } from 'components/ui';
|
import { UnitDisplay, Input } from 'components/ui';
|
||||||
import './DeterministicWalletsModal.scss';
|
|
||||||
import { StaticNetworkConfig } from 'types/network';
|
import { StaticNetworkConfig } from 'types/network';
|
||||||
import Select from 'react-select';
|
import './DeterministicWalletsModal.scss';
|
||||||
|
|
||||||
const WALLETS_PER_PAGE = 5;
|
const WALLETS_PER_PAGE = 5;
|
||||||
|
|
||||||
|
@ -125,23 +126,36 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
||||||
onSubmit={this.handleSubmitCustomPath}
|
onSubmit={this.handleSubmitCustomPath}
|
||||||
>
|
>
|
||||||
<span className="DWModal-path-label">Addresses </span>
|
<span className="DWModal-path-label">Addresses </span>
|
||||||
|
<div className="DWModal-path-select">
|
||||||
<Select
|
<Select
|
||||||
name="fieldDPath"
|
name="fieldDPath"
|
||||||
className=""
|
className=""
|
||||||
value={this.state.currentLabel || this.findDPath('value', dPath).value}
|
value={this.state.currentLabel || this.findDPath('value', dPath).value}
|
||||||
onChange={this.handleChangePath}
|
onChange={this.handleChangePath}
|
||||||
options={dPaths}
|
options={dPaths.concat([customDPath])}
|
||||||
|
optionRenderer={this.renderDPathOption}
|
||||||
|
valueRenderer={this.renderDPathOption}
|
||||||
clearable={false}
|
clearable={false}
|
||||||
searchable={false}
|
searchable={false}
|
||||||
/>
|
/>
|
||||||
{/* TODO/Hack - Custom Paths are temporarily disabled. `false` is used for smallest diff */}
|
</div>
|
||||||
{false && (
|
{this.state.currentLabel === customDPath.label && (
|
||||||
|
<React.Fragment>
|
||||||
|
<div className="DWModal-path-custom">
|
||||||
<Input
|
<Input
|
||||||
className={isValidPath(customPath) ? '' : 'invalid'}
|
className={customPath ? (isValidPath(customPath) ? 'valid' : 'invalid') : ''}
|
||||||
value={customPath}
|
value={customPath}
|
||||||
placeholder="m/44'/60'/0'/0"
|
placeholder="m/44'/60'/0'/0"
|
||||||
onChange={this.handleChangeCustomPath}
|
onChange={this.handleChangeCustomPath}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="DWModal-path-submit btn btn-success"
|
||||||
|
disabled={!isValidPath(customPath)}
|
||||||
|
>
|
||||||
|
<i className="fa fa-check" />
|
||||||
|
</button>
|
||||||
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -215,7 +229,7 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
||||||
const { value: dPathLabel } = newPath;
|
const { value: dPathLabel } = newPath;
|
||||||
const { value } = this.findDPath('value', dPathLabel);
|
const { value } = this.findDPath('value', dPathLabel);
|
||||||
|
|
||||||
if (value === 'custom') {
|
if (value === customDPath.value) {
|
||||||
this.setState({ isCustomPath: true, currentLabel: dPathLabel });
|
this.setState({ isCustomPath: true, currentLabel: dPathLabel });
|
||||||
} else {
|
} else {
|
||||||
this.setState({ isCustomPath: false, currentLabel: dPathLabel });
|
this.setState({ isCustomPath: false, currentLabel: dPathLabel });
|
||||||
|
@ -228,11 +242,12 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private handleSubmitCustomPath = (ev: React.FormEvent<HTMLFormElement>) => {
|
private handleSubmitCustomPath = (ev: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
const { customPath, currentLabel } = this.state;
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
if (!isValidPath(this.state.customPath)) {
|
|
||||||
return;
|
if (currentLabel === customDPath.label && isValidPath(customPath)) {
|
||||||
|
this.props.onPathChange(customPath);
|
||||||
}
|
}
|
||||||
this.props.onPathChange(this.state.customPath);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private handleChangeToken = (ev: React.FormEvent<HTMLSelectElement>) => {
|
private handleChangeToken = (ev: React.FormEvent<HTMLSelectElement>) => {
|
||||||
|
@ -257,6 +272,18 @@ class DeterministicWalletsModalClass extends React.PureComponent<Props, State> {
|
||||||
this.setState({ page: Math.max(this.state.page - 1, 0) }, this.getAddresses);
|
this.setState({ page: Math.max(this.state.page - 1, 0) }, this.getAddresses);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private renderDPathOption(option: Option) {
|
||||||
|
if (option.value === customDPath.value) {
|
||||||
|
return translate('ADD_Radio_5_PathCustom');
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{option.label} {option.value && <small>({option.value.toString().replace(' ', '')})</small>}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private renderWalletRow(wallet: DeterministicWalletData) {
|
private renderWalletRow(wallet: DeterministicWalletData) {
|
||||||
const { desiredToken, network } = this.props;
|
const { desiredToken, network } = this.props;
|
||||||
const { selectedAddress } = this.state;
|
const { selectedAddress } = this.state;
|
||||||
|
|
|
@ -68,5 +68,5 @@ export const EXTRA_PATHS = [ETH_SINGULAR];
|
||||||
|
|
||||||
// whitespace strings are evaluated the same way as nospace strings, except they allow optional spaces between each portion of the string
|
// whitespace strings are evaluated the same way as nospace strings, except they allow optional spaces between each portion of the string
|
||||||
// ie. "m / 44' / 0' / 0'" is valid, "m / 4 4' / 0' / 0'" is invalid
|
// ie. "m / 44' / 0' / 0'" is valid, "m / 4 4' / 0' / 0'" is invalid
|
||||||
export const dPathRegex = /m\/44'\/[0-9]+\'\/[0-9]+(\'+$|\'+(\/[0-1]+$))/;
|
export const dPathRegex = /m\/(44|0)'\/[0-9]+\'\/[0-9]+(\'+$|\'+(\/[0-1]+$))/;
|
||||||
// export const whitespaceDPathRegex = /m\s*\/\s*44'\s*\/\s*[0-9]+\'\s*\/\s*[0-9]+(\'+$|\'+\s*(\/\s*[0-1]+$))/;
|
// export const whitespaceDPathRegex = /m\s*\/\s*44'\s*\/\s*[0-9]+\'\s*\/\s*[0-9]+(\'+$|\'+\s*(\/\s*[0-1]+$))/;
|
||||||
|
|
Loading…
Reference in New Issue