Slit Sidebar address Identity rendering (#2701)
This commit is contained in:
parent
abfa4a2745
commit
aa2074b20c
@ -6,7 +6,7 @@ import { RuntimeVersion } from '@polkadot/types/interfaces';
|
||||
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { ChainImg } from '@polkadot/react-components';
|
||||
import { ChainImg, Icon } from '@polkadot/react-components';
|
||||
import { useCall, useApi } from '@polkadot/react-hooks';
|
||||
import { BestNumber, Chain } from '@polkadot/react-query';
|
||||
|
||||
@ -36,6 +36,7 @@ function ChainInfo ({ className, onClick }: Props): React.ReactElement<Props> {
|
||||
)}
|
||||
<BestNumber label='#' />
|
||||
</div>
|
||||
<Icon name='dropdown' />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -43,26 +44,39 @@ function ChainInfo ({ className, onClick }: Props): React.ReactElement<Props> {
|
||||
|
||||
export default React.memo(styled(ChainInfo)`
|
||||
border-top: 0.5rem solid transparent;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
padding: 0.75rem 1rem;
|
||||
margin: 0 0 0.5rem -0.75rem;
|
||||
padding: 0.75rem;
|
||||
margin: 0 0 0.5rem -1rem;
|
||||
|
||||
.apps--SideBar-logo-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 10rem;
|
||||
width: 10.5rem;
|
||||
|
||||
img {
|
||||
flex: 0;
|
||||
height: 2.75rem;
|
||||
width: 2.75rem;
|
||||
}
|
||||
|
||||
.icon.dropdown,
|
||||
> div.info {
|
||||
color: white;
|
||||
opacity: 0.75;
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.icon.dropdown {
|
||||
flex: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> div.info {
|
||||
flex: 1;
|
||||
padding-right: 0.5rem;
|
||||
|
||||
> div.chain {
|
||||
font-size: 0.9rem;
|
||||
|
||||
182
packages/page-accounts/src/Sidebar/Identity.tsx
Normal file
182
packages/page-accounts/src/Sidebar/Identity.tsx
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2017-2020 @polkadot/app-accounts 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 { AddressIdentity } from '@polkadot/react-hooks/types';
|
||||
|
||||
import React from 'react';
|
||||
import { AddressMini, AvatarItem, Icon, IconLink, Tag } from '@polkadot/react-components';
|
||||
import { useApi, useRegistrars, useToggle } from '@polkadot/react-hooks';
|
||||
import { isHex } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import RegistrarJudgement from './RegistrarJudgement';
|
||||
|
||||
interface Props {
|
||||
address: string;
|
||||
identity?: AddressIdentity;
|
||||
}
|
||||
|
||||
function Identity ({ address, identity }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { isRegistrar, registrars } = useRegistrars();
|
||||
const [isJudgementOpen, toggleIsJudgementOpen] = useToggle();
|
||||
|
||||
if (!identity || !identity.isExistent || !api.query.identity?.identityOf) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='ui--AddressMenu-section ui--AddressMenu-identity'>
|
||||
<div className='ui--AddressMenu-sectionHeader'>
|
||||
<div>
|
||||
<Icon name='address card' />
|
||||
|
||||
{t('identity')}
|
||||
</div>
|
||||
<Tag
|
||||
color={
|
||||
identity.isGood
|
||||
? 'green'
|
||||
: identity.isBad
|
||||
? 'red'
|
||||
: 'yellow'
|
||||
}
|
||||
isTag={false}
|
||||
label={
|
||||
<>
|
||||
<b>{identity.judgements.length} </b>
|
||||
{
|
||||
identity.judgements.length
|
||||
? (identity.isGood
|
||||
? (identity.isKnownGood ? t('Known good') : t('Reasonable'))
|
||||
: (identity.isErroneous ? t('Erroneous') : t('Low quality'))
|
||||
)
|
||||
: t('No judgments')
|
||||
}
|
||||
</>
|
||||
}
|
||||
size='tiny'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<AvatarItem
|
||||
icon={
|
||||
// This won't work - images are IPFS hashes
|
||||
// identity.image
|
||||
// ? <img src={identity.image} />
|
||||
// : <i className='icon user ui--AddressMenu-identityIcon' />
|
||||
//
|
||||
<i className='icon user ui--AddressMenu-identityIcon' />
|
||||
}
|
||||
subtitle={identity.legal}
|
||||
title={identity.display}
|
||||
/>
|
||||
<div className='ui--AddressMenu-identityTable'>
|
||||
{identity.parent && (
|
||||
<div className='tr parent'>
|
||||
<div className='th'>{t('parent')}</div>
|
||||
<div className='td'>
|
||||
<AddressMini
|
||||
className='parent'
|
||||
isPadded={false}
|
||||
value={identity.parent}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.email && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('email')}</div>
|
||||
<div className='td'>
|
||||
{isHex(identity.email)
|
||||
? identity.email
|
||||
: (
|
||||
<a
|
||||
href={`mailto:${identity.email}`}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
{identity.email}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.web && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('website')}</div>
|
||||
<div className='td'>
|
||||
{isHex(identity.web)
|
||||
? identity.web
|
||||
: (
|
||||
<a
|
||||
href={(identity.web as string).replace(/^(https?:\/\/)?/g, 'https://')}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
{identity.web}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.twitter && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('twitter')}</div>
|
||||
<div className='td'>
|
||||
{isHex(identity.twitter)
|
||||
? identity.twitter
|
||||
: (
|
||||
<a
|
||||
href={`https://twitter.com/${identity.twitter}`}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
{identity.twitter}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.riot && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('riot')}</div>
|
||||
<div className='td'>
|
||||
{identity.riot}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{isRegistrar && (
|
||||
<div className='ui--AddressMenu-section'>
|
||||
<div className='ui--AddressMenu-actions'>
|
||||
<ul>
|
||||
<li>
|
||||
<IconLink
|
||||
icon='address card'
|
||||
label={t('Add identity judgment')}
|
||||
onClick={toggleIsJudgementOpen}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{isJudgementOpen && isRegistrar && (
|
||||
<RegistrarJudgement
|
||||
address={address}
|
||||
key='modal-judgement'
|
||||
registrars={registrars}
|
||||
toggleJudgement={toggleIsJudgementOpen}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Identity);
|
||||
@ -6,16 +6,14 @@ import { BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useAccountInfo, useApi, useRegistrars, useToggle } from '@polkadot/react-hooks';
|
||||
import { classes } from '@polkadot/react-components/util';
|
||||
import { useAccountInfo, useToggle } from '@polkadot/react-hooks';
|
||||
import { colorLink } from '@polkadot/react-components/styles/theme';
|
||||
import { AccountName, AddressMini, AvatarItem, Button, Icon, IconLink, IdentityIcon, Input, InputTags, LinkExternal, Tag } from '@polkadot/react-components';
|
||||
import { isHex } from '@polkadot/util';
|
||||
import { AccountName, Button, Icon, IdentityIcon, Input, InputTags, LinkExternal, Tag } from '@polkadot/react-components';
|
||||
|
||||
import Transfer from '../Accounts/modals/Transfer';
|
||||
import { useTranslation } from '../translate';
|
||||
import Flags from './Flags';
|
||||
import RegistrarJudgement from './RegistrarJudgement';
|
||||
import Identity from './Identity';
|
||||
|
||||
interface Props extends BareProps {
|
||||
address: string;
|
||||
@ -23,14 +21,15 @@ interface Props extends BareProps {
|
||||
onUpdateName: () => void;
|
||||
}
|
||||
|
||||
function Sidebar ({ address, className, onClose, onUpdateName, style }: Props): React.ReactElement<Props> {
|
||||
const TAG_OPTS = {
|
||||
autoFocus: true
|
||||
};
|
||||
|
||||
function Sidebar ({ address, className, onClose, onUpdateName }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { isRegistrar, registrars } = useRegistrars();
|
||||
const { flags, identity, isEditingName, isEditingTags, name, onForgetAddress, onSaveName, onSaveTags, setName, setTags, tags, toggleIsEditingName, toggleIsEditingTags } = useAccountInfo(address);
|
||||
const [isHoveringButton, toggleIsHoveringButton] = useToggle();
|
||||
const [isTransferOpen, toggleIsTransferOpen] = useToggle();
|
||||
const [isJudgementOpen, toggleIsJudgementOpen] = useToggle();
|
||||
|
||||
const _onForgetAddress = useCallback(
|
||||
(): void => {
|
||||
@ -48,317 +47,166 @@ function Sidebar ({ address, className, onClose, onUpdateName, style }: Props):
|
||||
[onSaveName, onUpdateName]
|
||||
);
|
||||
|
||||
const useIdentity = !!api.query.identity?.identityOf;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classes('ui--AddressMenu', className)}
|
||||
style={style}
|
||||
>
|
||||
<Button
|
||||
className='ui--AddressMenu-close'
|
||||
icon='close'
|
||||
isBasic
|
||||
isCircular
|
||||
onClick={onClose}
|
||||
<div className={className}>
|
||||
<Button
|
||||
className='ui--AddressMenu-close'
|
||||
icon='close'
|
||||
isBasic
|
||||
isCircular
|
||||
onClick={onClose}
|
||||
/>
|
||||
<div className='ui--AddressMenu-header'>
|
||||
<IdentityIcon
|
||||
size={80}
|
||||
value={address}
|
||||
/>
|
||||
<div className='ui--AddressMenu-header'>
|
||||
<IdentityIcon
|
||||
size={80}
|
||||
value={address.toString()}
|
||||
/>
|
||||
<div className='ui--AddressMenu-addr'>
|
||||
{address.toString()}
|
||||
</div>
|
||||
<AccountName
|
||||
onClick={(flags.isEditable && !isEditingName) ? toggleIsEditingName : undefined}
|
||||
override={
|
||||
isEditingName
|
||||
? (
|
||||
<Input
|
||||
autoFocus
|
||||
className='name--input'
|
||||
defaultValue={name}
|
||||
onBlur={(flags.isInContacts || flags.isOwned) ? _onUpdateName : undefined}
|
||||
onChange={setName}
|
||||
withLabel={false}
|
||||
/>
|
||||
)
|
||||
: flags.isEditable
|
||||
? (name.toUpperCase() || t('<unknown>'))
|
||||
: undefined
|
||||
}
|
||||
value={address}
|
||||
withSidebar={false}
|
||||
>
|
||||
{(!isEditingName && flags.isEditable) && (
|
||||
<Icon
|
||||
className='inline-icon'
|
||||
name='edit'
|
||||
/>
|
||||
)}
|
||||
</AccountName>
|
||||
<div className='ui--AddressMenu-tags'>
|
||||
{isEditingTags
|
||||
<div className='ui--AddressMenu-addr'>
|
||||
{address}
|
||||
</div>
|
||||
<AccountName
|
||||
onClick={(flags.isEditable && !isEditingName) ? toggleIsEditingName : undefined}
|
||||
override={
|
||||
isEditingName
|
||||
? (
|
||||
<InputTags
|
||||
defaultValue={tags}
|
||||
onBlur={onSaveTags}
|
||||
onChange={setTags}
|
||||
onClose={onSaveTags}
|
||||
openOnFocus
|
||||
searchInput={{ autoFocus: true }}
|
||||
value={tags}
|
||||
<Input
|
||||
autoFocus
|
||||
className='name--input'
|
||||
defaultValue={name}
|
||||
onBlur={(flags.isInContacts || flags.isOwned) ? _onUpdateName : undefined}
|
||||
onChange={setName}
|
||||
withLabel={false}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<div
|
||||
className='tags--toggle'
|
||||
onClick={toggleIsEditingTags}
|
||||
>
|
||||
{tags.length
|
||||
? tags.map((tag): React.ReactNode => (
|
||||
<Tag
|
||||
color='grey'
|
||||
key={tag}
|
||||
label={tag}
|
||||
size='tiny'
|
||||
/>
|
||||
))
|
||||
: <label>{t('no tags')}</label>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{(!isEditingTags && (flags.isInContacts || flags.isOwned)) && (
|
||||
<Icon
|
||||
className='inline-icon'
|
||||
name='edit'
|
||||
: flags.isEditable
|
||||
? (name.toUpperCase() || t('<unknown>'))
|
||||
: undefined
|
||||
}
|
||||
value={address}
|
||||
withSidebar={false}
|
||||
>
|
||||
{(!isEditingName && flags.isEditable) && (
|
||||
<Icon
|
||||
className='inline-icon'
|
||||
name='edit'
|
||||
/>
|
||||
)}
|
||||
</AccountName>
|
||||
<div className='ui--AddressMenu-tags'>
|
||||
{isEditingTags
|
||||
? (
|
||||
<InputTags
|
||||
defaultValue={tags}
|
||||
onBlur={onSaveTags}
|
||||
onChange={setTags}
|
||||
onClose={onSaveTags}
|
||||
openOnFocus
|
||||
searchInput={TAG_OPTS}
|
||||
value={tags}
|
||||
withLabel={false}
|
||||
/>
|
||||
)
|
||||
: (
|
||||
<div
|
||||
className='tags--toggle'
|
||||
onClick={toggleIsEditingTags}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<Flags flags={flags} />
|
||||
<div className='ui-AddressMenu--button'>
|
||||
<Button.Group>
|
||||
<Button
|
||||
icon='send'
|
||||
label={t('Deposit')}
|
||||
onClick={toggleIsTransferOpen}
|
||||
/>
|
||||
{flags.isOwned && (
|
||||
<Button
|
||||
className='basic'
|
||||
icon='check'
|
||||
isPrimary
|
||||
label={t('Owned')}
|
||||
onMouseEnter={toggleIsHoveringButton}
|
||||
onMouseLeave={toggleIsHoveringButton}
|
||||
size='tiny'
|
||||
/>
|
||||
)}
|
||||
{!flags.isOwned && !flags.isInContacts && (
|
||||
<Button
|
||||
icon='add'
|
||||
isPositive
|
||||
label={t('Save')}
|
||||
onClick={_onUpdateName}
|
||||
onMouseEnter={toggleIsHoveringButton}
|
||||
onMouseLeave={toggleIsHoveringButton}
|
||||
size='tiny'
|
||||
/>
|
||||
)}
|
||||
{!flags.isOwned && flags.isInContacts && (
|
||||
<Button
|
||||
className={`ui--AddressMenu-button icon ${isHoveringButton ? '' : 'basic'}`}
|
||||
isAnimated
|
||||
isNegative={isHoveringButton}
|
||||
isPositive={!isHoveringButton}
|
||||
onClick={_onForgetAddress}
|
||||
onMouseEnter={toggleIsHoveringButton}
|
||||
onMouseLeave={toggleIsHoveringButton}
|
||||
size='tiny'
|
||||
>
|
||||
<Button.Content visible>
|
||||
<Icon name='check' />
|
||||
|
||||
{t('Saved')}
|
||||
</Button.Content>
|
||||
<Button.Content hidden>
|
||||
<Icon name='ban' />
|
||||
|
||||
{t('Remove')}
|
||||
</Button.Content>
|
||||
</Button>
|
||||
)}
|
||||
</Button.Group>
|
||||
</div>
|
||||
</div>
|
||||
{useIdentity && identity?.isExistent && (
|
||||
<div className='ui--AddressMenu-section ui--AddressMenu-identity'>
|
||||
<div className='ui--AddressMenu-sectionHeader'>
|
||||
<div>
|
||||
<Icon name='address card' />
|
||||
|
||||
{t('identity')}
|
||||
>
|
||||
{tags.length
|
||||
? tags.map((tag): React.ReactNode => (
|
||||
<Tag
|
||||
color='grey'
|
||||
key={tag}
|
||||
label={tag}
|
||||
size='tiny'
|
||||
/>
|
||||
))
|
||||
: <label>{t('no tags')}</label>
|
||||
}
|
||||
</div>
|
||||
<Tag
|
||||
color={
|
||||
identity.isGood
|
||||
? 'green'
|
||||
: identity.isBad
|
||||
? 'red'
|
||||
: 'yellow'
|
||||
}
|
||||
isTag={false}
|
||||
label={
|
||||
<>
|
||||
<b>{identity.judgements.length} </b>
|
||||
{
|
||||
identity.judgements.length
|
||||
? (identity.isGood
|
||||
? (identity.isKnownGood ? t('Known good') : t('Reasonable'))
|
||||
: (identity.isErroneous ? t('Erroneous') : t('Low quality'))
|
||||
)
|
||||
: t('No judgments')
|
||||
}
|
||||
</>
|
||||
}
|
||||
)
|
||||
}
|
||||
{(!isEditingTags && (flags.isInContacts || flags.isOwned)) && (
|
||||
<Icon
|
||||
className='inline-icon'
|
||||
name='edit'
|
||||
onClick={toggleIsEditingTags}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<Flags flags={flags} />
|
||||
<div className='ui-AddressMenu--button'>
|
||||
<Button.Group>
|
||||
<Button
|
||||
icon='send'
|
||||
label={t('Deposit')}
|
||||
onClick={toggleIsTransferOpen}
|
||||
/>
|
||||
{flags.isOwned && (
|
||||
<Button
|
||||
className='basic'
|
||||
icon='check'
|
||||
isPrimary
|
||||
label={t('Owned')}
|
||||
onMouseEnter={toggleIsHoveringButton}
|
||||
onMouseLeave={toggleIsHoveringButton}
|
||||
size='tiny'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<AvatarItem
|
||||
icon={
|
||||
// This won't work - images are IPFS hashes
|
||||
// identity.image
|
||||
// ? <img src={identity.image} />
|
||||
// : <i className='icon user ui--AddressMenu-identityIcon' />
|
||||
//
|
||||
<i className='icon user ui--AddressMenu-identityIcon' />
|
||||
}
|
||||
subtitle={identity.legal}
|
||||
title={identity.display}
|
||||
)}
|
||||
{!flags.isOwned && !flags.isInContacts && (
|
||||
<Button
|
||||
icon='add'
|
||||
isPositive
|
||||
label={t('Save')}
|
||||
onClick={_onUpdateName}
|
||||
onMouseEnter={toggleIsHoveringButton}
|
||||
onMouseLeave={toggleIsHoveringButton}
|
||||
size='tiny'
|
||||
/>
|
||||
<div className='ui--AddressMenu-identityTable'>
|
||||
{identity.parent && (
|
||||
<div className='tr parent'>
|
||||
<div className='th'>{t('parent')}</div>
|
||||
<div className='td'>
|
||||
<AddressMini
|
||||
className='parent'
|
||||
isPadded={false}
|
||||
value={identity.parent}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.email && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('email')}</div>
|
||||
<div className='td'>
|
||||
{isHex(identity.email)
|
||||
? identity.email
|
||||
: (
|
||||
<a
|
||||
href={`mailto:${identity.email}`}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
{identity.email}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.web && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('website')}</div>
|
||||
<div className='td'>
|
||||
{isHex(identity.web)
|
||||
? identity.web
|
||||
: (
|
||||
<a
|
||||
href={(identity.web as string).replace(/^(https?:\/\/)?/g, 'https://')}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
{identity.web}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.twitter && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('twitter')}</div>
|
||||
<div className='td'>
|
||||
{isHex(identity.twitter)
|
||||
? identity.twitter
|
||||
: (
|
||||
<a
|
||||
href={`https://twitter.com/${identity.twitter}`}
|
||||
rel='noopener noreferrer'
|
||||
target='_blank'
|
||||
>
|
||||
{identity.twitter}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{identity.riot && (
|
||||
<div className='tr'>
|
||||
<div className='th'>{t('riot')}</div>
|
||||
<div className='td'>
|
||||
{identity.riot}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{address && identity?.isExistent && isRegistrar && (
|
||||
<div className='ui--AddressMenu-section'>
|
||||
<div className='ui--AddressMenu-actions'>
|
||||
<ul>
|
||||
<li>
|
||||
<IconLink
|
||||
icon='address card'
|
||||
label={t('Add identity judgment')}
|
||||
onClick={toggleIsJudgementOpen}
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className='ui--AddressMenu-section'>
|
||||
<LinkExternal
|
||||
data={address}
|
||||
type='address'
|
||||
/>
|
||||
)}
|
||||
{!flags.isOwned && flags.isInContacts && (
|
||||
<Button
|
||||
className={`ui--AddressMenu-button icon ${isHoveringButton ? '' : 'basic'}`}
|
||||
isAnimated
|
||||
isNegative={isHoveringButton}
|
||||
isPositive={!isHoveringButton}
|
||||
onClick={_onForgetAddress}
|
||||
onMouseEnter={toggleIsHoveringButton}
|
||||
onMouseLeave={toggleIsHoveringButton}
|
||||
size='tiny'
|
||||
>
|
||||
<Button.Content visible>
|
||||
<Icon name='check' />
|
||||
|
||||
{t('Saved')}
|
||||
</Button.Content>
|
||||
<Button.Content hidden>
|
||||
<Icon name='ban' />
|
||||
|
||||
{t('Remove')}
|
||||
</Button.Content>
|
||||
</Button>
|
||||
)}
|
||||
</Button.Group>
|
||||
{isTransferOpen && (
|
||||
<Transfer
|
||||
key='modal-transfer'
|
||||
onClose={toggleIsTransferOpen}
|
||||
recipientId={address}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{isTransferOpen && (
|
||||
<Transfer
|
||||
key='modal-transfer'
|
||||
onClose={toggleIsTransferOpen}
|
||||
recipientId={address}
|
||||
<Identity
|
||||
address={address}
|
||||
identity={identity}
|
||||
/>
|
||||
<div className='ui--AddressMenu-section'>
|
||||
<LinkExternal
|
||||
data={address}
|
||||
type='address'
|
||||
/>
|
||||
)}
|
||||
{(!!address && isJudgementOpen && isRegistrar && useIdentity) && (
|
||||
<RegistrarJudgement
|
||||
address={address}
|
||||
key='modal-judgement'
|
||||
registrars={registrars}
|
||||
toggleJudgement={toggleIsJudgementOpen}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -2,11 +2,12 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
||||
import { DeriveAccountFlags, DeriveAccountRegistration } from '@polkadot/api-derive/types';
|
||||
import { ConstructTxFn, StringOrNull, VoidFn } from '@polkadot/react-components/types';
|
||||
import { AccountId, Balance, BlockNumber, Call, Exposure, Hash, SessionIndex, StakingLedger, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { IExtrinsic } from '@polkadot/types/types';
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
||||
import { KeyringJson$Meta } from '@polkadot/ui-keyring/types';
|
||||
|
||||
export type CallParam = any;
|
||||
|
||||
@ -106,6 +107,7 @@ export interface UseAccountInfo {
|
||||
genesisHash: StringOrNull;
|
||||
identity?: AddressIdentity;
|
||||
isEditingName: boolean;
|
||||
meta?: KeyringJson$Meta;
|
||||
toggleIsEditingName: VoidFn;
|
||||
isEditingTags: boolean;
|
||||
toggleIsEditingTags: VoidFn;
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import { DeriveAccountFlags, DeriveAccountInfo } from '@polkadot/api-derive/types';
|
||||
import { StringOrNull } from '@polkadot/react-components/types';
|
||||
import { KeyringJson$Meta } from '@polkadot/ui-keyring/types';
|
||||
import { AddressFlags, AddressIdentity, UseAccountInfo } from './types';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
@ -42,6 +43,7 @@ export default function useAccountInfo (value: string): UseAccountInfo {
|
||||
const [genesisHash, setGenesisHash] = useState<StringOrNull>(null);
|
||||
const [identity, setIdentity] = useState<AddressIdentity | undefined>();
|
||||
const [flags, setFlags] = useState<AddressFlags>(IS_NONE);
|
||||
const [meta, setMeta] = useState<KeyringJson$Meta | undefined>();
|
||||
const [isEditingName, toggleIsEditingName] = useToggle();
|
||||
const [isEditingTags, toggleIsEditingTags] = useToggle();
|
||||
|
||||
@ -106,6 +108,7 @@ export default function useAccountInfo (value: string): UseAccountInfo {
|
||||
isMultisig: accountOrAddress?.meta.isMultisig || false,
|
||||
isOwned
|
||||
}));
|
||||
setMeta(accountOrAddress?.meta);
|
||||
setName(accountOrAddress?.meta.name || '');
|
||||
setSortedTags(accountOrAddress?.meta.tags ? accountOrAddress.meta.tags.sort() : []);
|
||||
}, [identity, isAccount, isAddress, value]);
|
||||
@ -199,6 +202,7 @@ export default function useAccountInfo (value: string): UseAccountInfo {
|
||||
identity,
|
||||
isEditingName,
|
||||
isEditingTags,
|
||||
meta,
|
||||
name,
|
||||
onForgetAddress,
|
||||
onSaveName,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user