Allow external address input (#34)
* Allow external address input * Remove hold-over debug log
This commit is contained in:
parent
9206cbf7fc
commit
e02b971998
@ -99,7 +99,7 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
createOptions (): KeyringOptions {
|
||||
return createOptions(this.props.keyring);
|
||||
return createOptions(false, this.props.keyring, true);
|
||||
}
|
||||
|
||||
createState (currentPair: KeyringPair): $Shape<State> {
|
||||
|
||||
@ -15,6 +15,7 @@ import translate from './translate';
|
||||
type Props = I18nProps & {
|
||||
defaultValue?: Uint8Array,
|
||||
isError?: boolean,
|
||||
isInput?: boolean,
|
||||
label: string,
|
||||
onChange: (publicKey: Uint8Array) => void
|
||||
};
|
||||
@ -35,7 +36,7 @@ class Account extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
render (): React$Node {
|
||||
const { className, defaultValue, label, style, t } = this.props;
|
||||
const { className, defaultValue, isError, isInput, label, style, t } = this.props;
|
||||
const { publicKey } = this.state;
|
||||
|
||||
return (
|
||||
@ -46,6 +47,8 @@ class Account extends React.PureComponent<Props, State> {
|
||||
<div className='large'>
|
||||
<InputAddress
|
||||
defaultValue={defaultValue}
|
||||
isError={isError}
|
||||
isInput={isInput}
|
||||
label={label}
|
||||
onChange={this.onChange}
|
||||
placeholder='0x...'
|
||||
|
||||
@ -25,6 +25,7 @@ export default function Account ({ className, defaultValue, index, isError, onCh
|
||||
className={className}
|
||||
defaultValue={defaultValue}
|
||||
isError={isError}
|
||||
isInput
|
||||
label={label}
|
||||
onChange={_onChange}
|
||||
style={style}
|
||||
|
||||
@ -7,3 +7,7 @@
|
||||
.ui--InputAddress > .text {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui--InputAddress input.search {
|
||||
margin-left: 3rem;
|
||||
}
|
||||
|
||||
@ -3,25 +3,21 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { KeyringPair } from '@polkadot/util-keyring/types';
|
||||
|
||||
import './PairDisplay.css';
|
||||
|
||||
import React from 'react';
|
||||
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
|
||||
|
||||
type Props = {
|
||||
address: string,
|
||||
className?: string,
|
||||
pair: KeyringPair,
|
||||
name: string,
|
||||
style?: {
|
||||
[string]: string
|
||||
}
|
||||
};
|
||||
|
||||
export default function PairDisplay ({ className, pair, style }: Props): React$Node {
|
||||
const address = pair.address();
|
||||
const { name } = pair.getMeta();
|
||||
|
||||
export default function PairDisplay ({ address, className, name, style }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['ui--InputyAddress-PairDisplay', className].join(' ')}
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { KeyringInstance } from '@polkadot/util-keyring/types';
|
||||
import type { BareProps } from '../types';
|
||||
import type { KeyringOptions } from './types';
|
||||
|
||||
@ -14,36 +13,64 @@ import addressDecode from '@polkadot/util-keyring/address/decode';
|
||||
import addressEncode from '@polkadot/util-keyring/address/encode';
|
||||
|
||||
import RxDropdown from '../RxDropdown';
|
||||
import createItem from './optionItem';
|
||||
import createOptions from './options';
|
||||
|
||||
type Props = BareProps & {
|
||||
defaultValue?: Uint8Array,
|
||||
isError?: boolean,
|
||||
keyring?: KeyringInstance,
|
||||
isInput?: boolean,
|
||||
label?: string,
|
||||
onChange: (value: Uint8Array) => void,
|
||||
options?: KeyringOptions
|
||||
options?: KeyringOptions,
|
||||
withInput?: boolean
|
||||
};
|
||||
|
||||
const transform = (value: string): Uint8Array =>
|
||||
addressDecode(value);
|
||||
|
||||
export default function InputAddress ({ className, defaultValue, isError, keyring, label, onChange, options, style }: Props): React$Node {
|
||||
const _options = options || createOptions(keyring);
|
||||
let _defaultValue;
|
||||
|
||||
if (defaultValue) {
|
||||
_defaultValue = addressEncode(defaultValue);
|
||||
const transform = (value: string): Uint8Array => {
|
||||
try {
|
||||
return addressDecode(value);
|
||||
} catch (error) {
|
||||
return new Uint8Array([]);
|
||||
}
|
||||
};
|
||||
|
||||
export default function InputAddress ({ className, defaultValue, isError, isInput = false, label, onChange, options, style }: Props): React$Node {
|
||||
const _options = options || createOptions(isInput);
|
||||
const onSearch = (filteredOptions: KeyringOptions, query: string): KeyringOptions => {
|
||||
const queryLower = query.toLowerCase();
|
||||
const matches = filteredOptions.filter((item) => {
|
||||
const { name, value } = item;
|
||||
const isManual = item['data-manual'] || false;
|
||||
const hasMatch = name.toLowerCase().indexOf(queryLower) !== -1 ||
|
||||
value.toLowerCase().indexOf(queryLower) !== -1;
|
||||
|
||||
return hasMatch && (isInput || !isManual);
|
||||
});
|
||||
|
||||
// see if we should add a new item, i.e. valid address found
|
||||
if (isInput && matches.length === 0) {
|
||||
const publicKey = transform(query);
|
||||
|
||||
if (publicKey.length === 32) {
|
||||
const newOption = createItem(query, `${query.slice(0, 16)}…`, true);
|
||||
|
||||
matches.push(newOption);
|
||||
_options.push(newOption);
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
};
|
||||
|
||||
return (
|
||||
<RxDropdown
|
||||
className={['ui--InputAddress', className].join(' ')}
|
||||
defaultValue={_defaultValue}
|
||||
defaultValue={defaultValue && addressEncode(defaultValue)}
|
||||
isError={isError}
|
||||
label={label}
|
||||
onChange={onChange}
|
||||
options={_options}
|
||||
search={onSearch}
|
||||
transform={transform}
|
||||
/>
|
||||
);
|
||||
|
||||
27
packages/ui-react-app/src/InputAddress/optionItem.js
Normal file
27
packages/ui-react-app/src/InputAddress/optionItem.js
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2018 Jaco Greeff
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { KeyringOption } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import PairDisplay from './PairDisplay';
|
||||
|
||||
export default function createItem (address: string, name?: string, isManual: boolean = false): KeyringOption {
|
||||
// flowlint-next-line sketchy-null-string:off
|
||||
name = name || address;
|
||||
|
||||
return {
|
||||
'data-manual': isManual,
|
||||
name,
|
||||
text: (
|
||||
<PairDisplay
|
||||
address={address}
|
||||
name={name}
|
||||
/>
|
||||
),
|
||||
value: address
|
||||
};
|
||||
}
|
||||
@ -6,18 +6,28 @@
|
||||
import type { KeyringInstance } from '@polkadot/util-keyring/types';
|
||||
import type { KeyringOptions } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import testKeyring from '../keyring';
|
||||
import PairDisplay from './PairDisplay';
|
||||
import createItem from './optionItem';
|
||||
|
||||
export default function createOptions (keyring?: KeyringInstance = testKeyring): KeyringOptions {
|
||||
return keyring
|
||||
.getPairs()
|
||||
.map((pair) => ({
|
||||
text: (
|
||||
<PairDisplay pair={pair} />
|
||||
),
|
||||
value: pair.address()
|
||||
}));
|
||||
const cached: { [string]: ?KeyringOptions } = {
|
||||
addresses: null,
|
||||
accounts: null
|
||||
};
|
||||
|
||||
export default function createOptions (isAddress?: boolean = false, keyring?: KeyringInstance = testKeyring, forceReload: boolean = false): KeyringOptions {
|
||||
const map = isAddress ? 'addresses' : 'accounts';
|
||||
|
||||
if (forceReload || !cached[map]) {
|
||||
cached[map] = keyring
|
||||
.getPairs()
|
||||
.map((pair) => {
|
||||
const address = pair.address();
|
||||
const { name } = pair.getMeta();
|
||||
|
||||
return createItem(address, name);
|
||||
});
|
||||
}
|
||||
|
||||
// $FlowFixMe we have checked and set just above
|
||||
return cached[map];
|
||||
}
|
||||
|
||||
@ -4,7 +4,9 @@
|
||||
// @flow
|
||||
|
||||
export type KeyringOption = {
|
||||
text: React$Node,
|
||||
'data-manual'?: boolean,
|
||||
name: string,
|
||||
text: React$Node | string,
|
||||
value: string
|
||||
};
|
||||
|
||||
|
||||
@ -26,8 +26,10 @@ export default function Account ({ index, isError, label, onChange, t, value: {
|
||||
>
|
||||
<InputAddress
|
||||
defaultValue={defaultValue}
|
||||
isError={isError}
|
||||
isInput
|
||||
onChange={_onChange}
|
||||
placeholder='0x...'
|
||||
placeholder='5...'
|
||||
/>
|
||||
</Base>
|
||||
);
|
||||
|
||||
@ -67,8 +67,6 @@ class Params extends React.PureComponent<Props, State> {
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log('Params', paramNames, params);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['ui--Params', 'ui--form', className].join(' ')}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user