From 420343224d952ddacb882e24abac66bbfd7996a7 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 28 Oct 2019 20:48:53 +0100 Subject: [PATCH] Lookup nicknames (#1793) --- packages/app-council/src/Overview/Vote.tsx | 2 - packages/app-staking/src/Actions/Accounts.tsx | 4 +- packages/react-components/src/AddressMini.tsx | 48 +++++----------- packages/react-components/src/AddressRow.tsx | 27 +++++---- .../src/InputAddress/index.tsx | 12 ++-- .../src/util/getAddressName.ts | 14 ++--- packages/react-query/src/AccountName.tsx | 57 +++++++++++++++++++ packages/react-query/src/Balance.tsx | 2 +- packages/react-query/src/Bonded.tsx | 2 +- packages/react-query/src/LockedVote.tsx | 2 +- packages/react-query/src/index.ts | 1 + 11 files changed, 101 insertions(+), 70 deletions(-) create mode 100644 packages/react-query/src/AccountName.tsx diff --git a/packages/app-council/src/Overview/Vote.tsx b/packages/app-council/src/Overview/Vote.tsx index 143c4229ae..57dbbbaf78 100644 --- a/packages/app-council/src/Overview/Vote.tsx +++ b/packages/app-council/src/Overview/Vote.tsx @@ -165,8 +165,6 @@ class Vote extends TxModal { ? members.map((accountId): [AccountId, boolean] => [accountId, true]).concat(_candidates) : _candidates; - console.log('content', votes); - return ( <> {api.tx.electionsPhragmen && ( diff --git a/packages/app-staking/src/Actions/Accounts.tsx b/packages/app-staking/src/Actions/Accounts.tsx index 88d0a3c537..1112008fdc 100644 --- a/packages/app-staking/src/Actions/Accounts.tsx +++ b/packages/app-staking/src/Actions/Accounts.tsx @@ -12,8 +12,8 @@ import { withCalls, withMulti } from '@polkadot/react-api/with'; import React, { useState } from 'react'; import styled from 'styled-components'; import { Button, CardGrid } from '@polkadot/react-components'; +import { AccountName } from '@polkadot/react-query'; import createOption from '@polkadot/ui-keyring/options/item'; -import { getAddressName } from '@polkadot/react-components/util'; import Account from './Account'; import StartStaking from './NewStake'; @@ -43,7 +43,7 @@ function Accounts ({ allAccounts, allStashes, className, myControllers, recently const [isNewStakeOpen, setIsNewStateOpen] = useState(false); const myStashes = getMyStashes(myControllers, allAccounts); const stashOptions = allStashes.map((stashId): KeyringSectionOption => - createOption(stashId, getAddressName(stashId, 'account') as string) + createOption(stashId, () as any) ); const isEmpty = !isNewStakeOpen && (!myStashes || myStashes.length === 0); diff --git a/packages/react-components/src/AddressMini.tsx b/packages/react-components/src/AddressMini.tsx index b807c963de..baef767cec 100644 --- a/packages/react-components/src/AddressMini.tsx +++ b/packages/react-components/src/AddressMini.tsx @@ -8,9 +8,10 @@ import { BareProps } from './types'; import BN from 'bn.js'; import React from 'react'; import styled from 'styled-components'; +import { AccountName } from '@polkadot/react-query'; import { KeyringItemType } from '@polkadot/ui-keyring/types'; -import { classes, getAddressName, toShortAddress } from './util'; +import { classes } from './util'; import BalanceDisplay from './Balance'; import BondedDisplay from './Bonded'; import IdentityIcon from './IdentityIcon'; @@ -31,26 +32,8 @@ interface Props extends BareProps { withLockedVote?: boolean; } -function renderAddressOrName ({ isShort = true, withAddress = true, type }: Props, address: string): React.ReactNode { - if (!withAddress) { - return null; - } - - const name = getAddressName(address, type); - - return ( -
{ - name || ( - isShort - ? toShortAddress(address) - : address - ) - }
- ); -} - function AddressMini (props: Props): React.ReactElement | null { - const { balance, bonded, children, className, iconInfo, isPadded = true, style, value, withBalance = false, withBonded = false, withLockedVote = false } = props; + const { balance, bonded, children, className, iconInfo, isPadded = true, style, value, withAddress = true, withBalance = false, withBonded = false, withLockedVote = false } = props; if (!value) { return null; @@ -64,7 +47,11 @@ function AddressMini (props: Props): React.ReactElement | null { style={style} >
- {renderAddressOrName(props, address)} + {withAddress && ( +
+ +
+ )} {children}
@@ -116,19 +103,12 @@ export default styled(AddressMini)` } .ui--AddressMini-address { - &.withAddr, - &.withName { - font-family: monospace; - max-width: 9rem; - min-width: 9em; - overflow: hidden; - text-align: right; - text-overflow: ellipsis; - } - - &.withName { - text-transform: uppercase; - } + font-family: monospace; + max-width: 9rem; + min-width: 9em; + overflow: hidden; + text-align: right; + text-overflow: ellipsis; } .ui--AddressMini-balances { diff --git a/packages/react-components/src/AddressRow.tsx b/packages/react-components/src/AddressRow.tsx index 8d55dd3a06..68eeecac42 100644 --- a/packages/react-components/src/AddressRow.tsx +++ b/packages/react-components/src/AddressRow.tsx @@ -3,19 +3,17 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +import { DeriveAccountInfo } from '@polkadot/api-derive/types'; import { ApiProps } from '@polkadot/react-api/types'; import { I18nProps } from '@polkadot/react-components/types'; -import { AccountId, AccountIndex, Address, Balance } from '@polkadot/types/interfaces'; -import { Codec } from '@polkadot/types/types'; +import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces'; import BN from 'bn.js'; import React from 'react'; import styled from 'styled-components'; import { withCalls, withMulti } from '@polkadot/react-api'; import BaseIdentityIcon from '@polkadot/react-identicon'; -import { Bytes, Option } from '@polkadot/types'; import keyring from '@polkadot/ui-keyring'; -import { u8aToString } from '@polkadot/util'; import AddressInfo, { BalanceActiveType, ValidatorPrefsType } from './AddressInfo'; import { classes, getAddressName, getAddressTags, toShortAddress } from './util'; @@ -29,7 +27,7 @@ export interface Props extends I18nProps, RowProps { isContract?: boolean; isValid?: boolean; label?: string; - nicks_nameOf?: Option<[Bytes, Balance] & Codec>; + accounts_info?: DeriveAccountInfo; noDefaultNameOpacity?: boolean; value: AccountId | AccountIndex | Address | string | null; withAddressOrName?: boolean; @@ -51,17 +49,18 @@ class AddressRow extends Row { this.state = this.createState(); } - public static getDerivedStateFromProps ({ accounts_idAndIndex = [], defaultName, nicks_nameOf, noDefaultNameOpacity, type, value }: Props, prevState: State): State | null { + public static getDerivedStateFromProps ({ accounts_idAndIndex = [], accounts_info, defaultName, isEditable, noDefaultNameOpacity, type, value }: Props, prevState: State): State | null { const [_accountId] = accounts_idAndIndex; const accountId = _accountId || value; const address = accountId ? accountId.toString() : DEFAULT_ADDR; - const nickName = nicks_nameOf && nicks_nameOf.isSome - ? u8aToString(nicks_nameOf.unwrap()[0]) - : undefined; - const nameHolder = defaultName || ''; - const name = nickName || getAddressName(address, type, false, noDefaultNameOpacity ? nameHolder : {nameHolder}) || ''; + const [, isDefault, nameInner] = accounts_info && accounts_info.nickname + ? [true, false, accounts_info.nickname] + : getAddressName(address, type, defaultName || ''); + const name = isDefault && !noDefaultNameOpacity && !isEditable + ?
{nameInner}
+ : nameInner; const tags = getAddressTags(address, type); const state: Partial = { tags }; let hasChanged = false; @@ -114,13 +113,13 @@ class AddressRow extends Row { const address = accountId ? accountId.toString() : DEFAULT_ADDR; - const name = getAddressName(address, type, false, defaultName || '') || ''; + const [, , name] = getAddressName(address, type, defaultName || ''); const tags = getAddressTags(address, type); return { ...this.state, address, - name: name as string, + name, tags }; } @@ -297,6 +296,6 @@ export default withMulti( translate, withCalls( ['derive.accounts.idAndIndex', { paramName: 'value' }], - ['query.nicks.nameOf', { paramName: 'value' }] + ['derive.accounts.info', { paramName: 'value' }] ) ); diff --git a/packages/react-components/src/InputAddress/index.tsx b/packages/react-components/src/InputAddress/index.tsx index 6aa9e9d8e5..4e182e3b1e 100644 --- a/packages/react-components/src/InputAddress/index.tsx +++ b/packages/react-components/src/InputAddress/index.tsx @@ -10,12 +10,13 @@ import React from 'react'; import store from 'store'; import styled from 'styled-components'; import { withMulti, withObservable } from '@polkadot/react-api'; +import { AccountName } from '@polkadot/react-query'; import keyring from '@polkadot/ui-keyring'; import keyringOption from '@polkadot/ui-keyring/options'; import createKeyringItem from '@polkadot/ui-keyring/options/item'; import { isUndefined } from '@polkadot/util'; -import { classes, getAddressName } from '../util'; +import { classes } from '../util'; import addressToAddress from '../util/toAddress'; import Dropdown from '../Dropdown'; import createHeader from './createHeader'; @@ -198,13 +199,8 @@ class InputAddress extends React.PureComponent { ); } - private renderLabel = ({ value }: KeyringSectionOption): React.ReactNode => { - if (!value) { - return undefined; - } - - return getAddressName(value, null, true); - } + private renderLabel = ({ value }: KeyringSectionOption): React.ReactNode => + ; private getLastOptionValue (): KeyringSectionOption | undefined { const { optionsAll, type = DEFAULT_TYPE } = this.props; diff --git a/packages/react-components/src/util/getAddressName.ts b/packages/react-components/src/util/getAddressName.ts index fdc0c8c4b0..cdf5306441 100644 --- a/packages/react-components/src/util/getAddressName.ts +++ b/packages/react-components/src/util/getAddressName.ts @@ -4,16 +4,16 @@ import { KeyringItemType } from '@polkadot/ui-keyring/types'; -import React from 'react'; - import getAddressMeta from './getAddressMeta'; import toShortAddress from './toShortAddress'; -export default function getAddressName (address: string, type: KeyringItemType | null = null, withShort?: boolean, defaultName?: React.ReactNode): React.ReactNode | string | undefined { +// isName, isDefault, name +export default function getAddressName (address: string, type: KeyringItemType | null = null, defaultName?: string): [boolean, boolean, string] { const meta = getAddressMeta(address, type); - const name = meta.name || defaultName; - return !name && withShort - ? toShortAddress(address) - : name; + return meta.name + ? [false, false, meta.name] + : defaultName + ? [false, true, defaultName] + : [true, false, toShortAddress(address)]; } diff --git a/packages/react-query/src/AccountName.tsx b/packages/react-query/src/AccountName.tsx new file mode 100644 index 0000000000..5c4f575575 --- /dev/null +++ b/packages/react-query/src/AccountName.tsx @@ -0,0 +1,57 @@ +// Copyright 2017-2019 @polkadot/react-query authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { DeriveAccountInfo } from '@polkadot/api-derive/types'; +import { BareProps, CallProps } from '@polkadot/react-api/types'; +import { AccountId, AccountIndex } from '@polkadot/types/interfaces'; + +import React, { useState, useEffect } from 'react'; +import { withCalls } from '@polkadot/react-api'; +import { getAddressName, toShortAddress } from '@polkadot/react-components/util'; + +interface Props extends BareProps, CallProps { + children?: React.ReactNode; + defaultName?: React.ReactNode; + idAndIndex?: [AccountId?, AccountIndex?]; + info?: DeriveAccountInfo; + label?: React.ReactNode; + params?: string | null; + withShort?: boolean; +} + +export function AccountName ({ children, className, defaultName, idAndIndex, info, label = '', params, style }: Props): React.ReactElement { + const [name, setName] = useState(defaultName || ''); + + useEffect((): void => { + const [accountId, accountIndex] = idAndIndex || []; + + if (info && info.nickname) { + setName(info.nickname.toUpperCase()); + } else if (accountId) { + const [isAddress, , extracted] = getAddressName(accountId.toString()); + + setName( + isAddress + ? (accountIndex && accountIndex.toString()) || extracted + : extracted.toUpperCase() + ); + } else { + setName(defaultName || toShortAddress(params)); + } + }, [idAndIndex, info]); + + return ( +
+ {label}{name}{children} +
+ ); +} + +export default withCalls( + ['derive.accounts.idAndIndex', { paramName: 'params', propName: 'idAndIndex' }], + ['derive.accounts.info', { paramName: 'params', propName: 'info' }] +)(AccountName); diff --git a/packages/react-query/src/Balance.tsx b/packages/react-query/src/Balance.tsx index a61965a6bb..9cec68e7f2 100644 --- a/packages/react-query/src/Balance.tsx +++ b/packages/react-query/src/Balance.tsx @@ -25,7 +25,7 @@ export function BalanceDisplay ({ children, className, label = '', balances_all {label}{ balances_all ? formatBalance(balances_all.freeBalance) - : '0' + : '-' }{children}
); diff --git a/packages/react-query/src/Bonded.tsx b/packages/react-query/src/Bonded.tsx index 81e9cc5f55..09d55ef587 100644 --- a/packages/react-query/src/Bonded.tsx +++ b/packages/react-query/src/Bonded.tsx @@ -24,7 +24,7 @@ export function BondedDisplay ({ children, className, label = '', staking_ledger {label}{ staking_ledger ? formatBalance(staking_ledger.active) - : '0' + : '-' }{children} ); diff --git a/packages/react-query/src/LockedVote.tsx b/packages/react-query/src/LockedVote.tsx index aa7f83d8c3..b2770d2027 100644 --- a/packages/react-query/src/LockedVote.tsx +++ b/packages/react-query/src/LockedVote.tsx @@ -24,7 +24,7 @@ export function LockedVote ({ children, className, electionsPhragmen_stakeOf, la {label}{ electionsPhragmen_stakeOf ? formatBalance(electionsPhragmen_stakeOf) - : '0' + : '-' }{children} ); diff --git a/packages/react-query/src/index.ts b/packages/react-query/src/index.ts index ac2a614825..5a4e07f703 100644 --- a/packages/react-query/src/index.ts +++ b/packages/react-query/src/index.ts @@ -3,6 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. export { default as AccountIndex } from './AccountIndex'; +export { default as AccountName } from './AccountName'; export { default as Available } from './Available'; export { default as Balance } from './Balance'; export { default as Bonded } from './Bonded';