Bump API (dispatchQueue derive) (#2467)

* Bump API (dispatchQueue derive)

* with democracy.nextExternal
This commit is contained in:
Jaco Greeff 2020-03-27 21:26:23 +01:00 committed by GitHub
parent dd04cc9d98
commit b4d0ff93a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 233 additions and 330 deletions

View File

@ -8,10 +8,10 @@
"packages/*"
],
"resolutions": {
"@polkadot/api": "^1.9.0-beta.16",
"@polkadot/api-contract": "^1.9.0-beta.16",
"@polkadot/api": "^1.9.0-beta.18",
"@polkadot/api-contract": "^1.9.0-beta.18",
"@polkadot/keyring": "^2.7.0-beta.8",
"@polkadot/types": "^1.9.0-beta.16",
"@polkadot/types": "^1.9.0-beta.18",
"@polkadot/util": "^2.7.0-beta.8",
"@polkadot/util-crypto": "^2.7.0-beta.8",
"babel-core": "^7.0.0-bridge.0",

View File

@ -12,6 +12,6 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.9.2",
"@polkadot/api-contract": "^1.9.0-beta.16"
"@polkadot/api-contract": "^1.9.0-beta.18"
}
}

View File

@ -40,7 +40,7 @@ function Motion ({ className, isMember, members, motion: { hash, proposal, votes
<td className='number top'><h1>{formatNumber(index)}</h1></td>
<ProposalCell
className='top'
proposalHash={hash}
imageHash={hash}
proposal={proposal}
/>
<td className='number top'>

View File

@ -1,71 +0,0 @@
// Copyright 2017-2020 @polkadot/app-democracy 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 { BlockNumber, Hash, ReferendumIndex } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import React, { useEffect, useState } from 'react';
import { registry } from '@polkadot/react-api';
import { Option, StorageKey, Vec, createType } from '@polkadot/types';
import { hexToU8a } from '@polkadot/util';
import DispatchEntry from './DispatchEntry';
interface Props {
entries: Option<Vec<Option<ITuple<[Hash, ReferendumIndex]>>>>;
keyPrefix: string;
storageKey: StorageKey;
}
interface Entry {
blockNumber?: BlockNumber;
hash: Hash;
referendumIndex: ReferendumIndex;
}
function DispatchBlock ({ entries, keyPrefix, storageKey }: Props): React.ReactElement<Props> | null {
const [blockNumber, setBlockNumber] = useState<BlockNumber | undefined>();
const [expanded, setExpanded] = useState<Entry[]>([]);
useEffect((): void => {
keyPrefix && storageKey && setBlockNumber(
createType(registry, 'BlockNumber', hexToU8a(
`0x${storageKey.toHex().replace(keyPrefix, '').substr(16)}`)
)
);
}, [keyPrefix, storageKey]);
useEffect((): void => {
setExpanded(
entries?.isSome
? entries
.unwrap()
.map((entry): [Hash, ReferendumIndex] | null => entry.unwrapOr(null))
.filter((entry): boolean => !!entry)
.map(([hash, referendumIndex]: any): Entry => ({
blockNumber, hash, referendumIndex
}))
: []
);
}, [blockNumber, entries]);
if (!expanded.length) {
return null;
}
return (
<>
{expanded.map(({ blockNumber, hash, referendumIndex }): React.ReactNode => (
<DispatchEntry
blockNumber={blockNumber}
hash={hash}
key={referendumIndex.toString()}
referendumIndex={referendumIndex}
/>
))}
</>
);
}
export default React.memo(DispatchBlock);

View File

@ -2,15 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash, Proposal, ReferendumIndex } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveDispatch } from '@polkadot/api-derive/types';
import { BlockNumber } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import React, { useEffect, useState } from 'react';
import React from 'react';
import { LinkExternal } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';
import { BlockToTime } from '@polkadot/react-query';
import { Bytes, Option } from '@polkadot/types';
import { formatNumber } from '@polkadot/util';
import { useTranslation } from '../translate';
@ -18,48 +17,39 @@ import ProposalCell from './ProposalCell';
import PreImageButton from './PreImageButton';
interface Props {
blockNumber?: BlockNumber;
hash: Hash;
referendumIndex: ReferendumIndex;
value: DeriveDispatch;
}
function DispatchEntry ({ blockNumber, hash, referendumIndex }: Props): React.ReactElement<Props> {
function DispatchEntry ({ value: { at, image, imageHash, index } }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []) || new BN(0);
const preimage = useCall<Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>
>(api.query.democracy.preimages, [hash]);
const [proposal, setProposal] = useState<Proposal | undefined>();
useEffect((): void => {
preimage?.isSome && setProposal(api.createType('Proposal', preimage.unwrap()[0].toU8a(true)));
}, [api, preimage]);
return (
<tr>
<td className='number top'><h1>{formatNumber(referendumIndex)}</h1></td>
<td className='number top'><h1>{formatNumber(index)}</h1></td>
<td className='number together top'>
{blockNumber && (
{bestNumber && (
<>
<label>{t('enact')}</label>
<BlockToTime blocks={blockNumber.sub(bestNumber)} />
#{formatNumber(blockNumber)}
<BlockToTime blocks={at.sub(bestNumber)} />
#{formatNumber(at)}
</>
)}
</td>
<ProposalCell
proposalHash={hash}
proposal={proposal}
imageHash={imageHash}
proposal={image?.proposal}
/>
<td className='together number top'>
{!proposal && (
{!image?.proposal && (
<PreImageButton
hash={hash}
imageHash={imageHash}
isImminent
/>
)}
<LinkExternal
data={referendumIndex}
data={index}
type='referendum'
/>
</td>

View File

@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { BlockNumber, Hash, ReferendumIndex } from '@polkadot/types/interfaces';
import { DeriveDispatch } from '@polkadot/api-derive/types';
import React from 'react';
import { Spinner, Table } from '@polkadot/react-components';
@ -18,11 +18,7 @@ interface Props {
function DispatchQueue ({ className }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const queued = useCall<[BlockNumber, Hash, ReferendumIndex][]>(api.query.democracy.dispatchQueue, []);
if (!queued?.length) {
return null;
}
const queued = useCall<DeriveDispatch[]>(api.derive.democracy.dispatchQueue as any, []);
return (
<div className={className}>
@ -32,18 +28,16 @@ function DispatchQueue ({ className }: Props): React.ReactElement<Props> | null
? (
<Table>
<Table.Body>
{queued.map(([blockNumber, hash, referendumIndex]): React.ReactNode => (
{queued.map((entry): React.ReactNode => (
<DispatchEntry
blockNumber={blockNumber}
hash={hash}
key={referendumIndex.toString()}
referendumIndex={referendumIndex}
key={entry.index.toString()}
value={entry}
/>
))}
</Table.Body>
</Table>
)
: t('nothing queued to be executed')
: t('nothing queued for execution')
: <Spinner />
}
</div>

View File

@ -0,0 +1,62 @@
// Copyright 2017-2020 @polkadot/app-democracy 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 { DeriveProposalExternal } from '@polkadot/api-derive/types';
import React from 'react';
import { AddressSmall, Button } from '@polkadot/react-components';
import { FormatBalance } from '@polkadot/react-query';
import { useTranslation } from '../translate';
import PreImageButton from './PreImageButton';
import ProposalCell from './ProposalCell';
import Fasttrack from './Fasttrack';
interface Props {
className?: string;
value: DeriveProposalExternal;
}
function External ({ className, value: { image, imageHash, threshold } }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
return (
<tr className={className}>
<td className='top'>
{image && <AddressSmall value={image.proposer} />}
</td>
<td className='number together top'>
{image && <FormatBalance label={<label>{t('locked')}</label>} value={image.balance} />}
</td>
<ProposalCell
className='top'
imageHash={imageHash}
proposal={image?.proposal}
/>
<td className='together number top'>
<Button.Group>
{!image?.proposal && (
<PreImageButton
imageHash={imageHash}
withoutOr
/>
)}
{threshold && (
<>
{!image?.proposal && (
<Button.Or />
)}
<Fasttrack
imageHash={imageHash}
threshold={threshold}
/>
</>
)}
</Button.Group>
</td>
</tr>
);
}
export default React.memo(External);

View File

@ -2,19 +2,14 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Hash, Proposal, VoteThreshold } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveProposalExternal } from '@polkadot/api-derive/types';
import React, { useEffect, useState } from 'react';
import { AddressSmall, Table, Button } from '@polkadot/react-components';
import React from 'react';
import { Spinner } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';
import { FormatBalance } from '@polkadot/react-query';
import { Bytes, Option } from '@polkadot/types';
import { useTranslation } from '../translate';
import PreImageButton from './PreImageButton';
import ProposalCell from './ProposalCell';
import Fasttrack from './Fasttrack';
import External from './External';
interface Props {
className?: string;
@ -23,79 +18,17 @@ interface Props {
function Externals ({ className }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const external = useCall<Option<ITuple<[Hash, VoteThreshold]>>>(api.query.democracy.nextExternal, []);
const [[hash, threshold], setInfo] = useState<[Hash | null, VoteThreshold | null]>([null, null]);
const [expanded, setExpanded] = useState<{ at: BlockNumber; balance: Balance; proposer: AccountId; proposal: Proposal } | null>(null);
const preimage = useCall<Option<ITuple<[Bytes, AccountId, Balance, BlockNumber]>>>(api.query.democracy.preimages, [hash]);
useEffect((): void => {
setInfo(
external
? external.unwrapOr([null, null])
: [null, null]
);
}, [external]);
useEffect((): void => {
if (preimage?.isSome) {
const preImage = preimage.unwrap();
setExpanded({
at: preImage[3],
balance: preImage[2],
proposer: preImage[1],
proposal: api.createType('Proposal', preImage[0].toU8a(true))
});
} else {
setExpanded(null);
}
}, [api, preimage]);
if (!hash) {
return null;
}
const external = useCall<DeriveProposalExternal | null>(api.derive.democracy.nextExternal, []);
return (
<div className={`proposalSection ${className}`}>
<h1>{t('externals')}</h1>
<Table>
<Table.Body>
<tr className={className}>
<td className='top'>
{expanded && <AddressSmall value={expanded.proposer} />}
</td>
<td className='number together top'>
{expanded && <FormatBalance label={<label>{t('locked')}</label>} value={expanded.balance} />}
</td>
<ProposalCell
className='top'
proposalHash={hash}
proposal={expanded?.proposal}
/>
<td className='together number top'>
<Button.Group>
{!expanded?.proposal && (
<PreImageButton
hash={hash}
withoutOr
/>
)}
{hash && threshold && (
<>
{!expanded?.proposal && (
<Button.Or />
)}
<Fasttrack
hash={hash}
threshold={threshold}
/>
</>
)}
</Button.Group>
</td>
</tr>
</Table.Body>
</Table>
<h1>{t('external')}</h1>
{!external
? external === null
? t('No external proposal')
: <Spinner />
: <External value={external} />
}
</div>
);
}

View File

@ -13,7 +13,7 @@ import { useApi, useMembers, useToggle } from '@polkadot/react-hooks';
import { useTranslation } from '../translate';
interface Props {
hash: Hash;
imageHash: Hash;
threshold: VoteThreshold;
}
@ -21,7 +21,7 @@ const ONE_MIN = (1 * 60) / 6;
const DEF_DELAY = new BN(ONE_MIN);
const DEF_VOTING = new BN(ONE_MIN * 60 * 3);
function Fasttrack ({ hash, threshold }: Props): React.ReactElement<Props> | null {
function Fasttrack ({ imageHash, threshold }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const { isMember, members } = useMembers('technicalCommittee');
@ -43,10 +43,10 @@ function Fasttrack ({ hash, threshold }: Props): React.ReactElement<Props> | nul
useEffect((): void => {
setProposal(
() => delayBlocks?.gtn(0) && votingBlocks?.gtn(0)
? api.tx.democracy.fastTrack(hash, votingBlocks, delayBlocks)
? api.tx.democracy.fastTrack(imageHash, votingBlocks, delayBlocks)
: null
);
}, [api, delayBlocks, hash, votingBlocks]);
}, [api, delayBlocks, imageHash, votingBlocks]);
return (
<>
@ -67,8 +67,8 @@ function Fasttrack ({ hash, threshold }: Props): React.ReactElement<Props> | nul
<Input
help={t('The external proposal to send to the technical committee')}
isDisabled
label={t('external hash')}
value={hash}
label={t('preimage hash')}
value={imageHash}
/>
<InputNumber
autoFocus

View File

@ -17,13 +17,13 @@ import { useTranslation } from '../translate';
interface Props {
className?: string;
isImminent?: boolean;
matchHash?: Hash;
imageHash?: Hash;
onClose: () => void;
}
const ZERO_HASH = blake2AsHex('');
function PreImage ({ className, isImminent: propsIsImminent, matchHash, onClose }: Props): React.ReactElement<Props> {
function PreImage ({ className, isImminent: propsIsImminent, imageHash, onClose }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { apiDefaultTxSudo } = useApi();
const [accountId, setAccountId] = useState<string | null>(null);
@ -37,8 +37,8 @@ function PreImage ({ className, isImminent: propsIsImminent, matchHash, onClose
setHash({ encodedProposal, encodedHash: blake2AsHex(encodedProposal) });
}, [proposal]);
const isMatched = matchHash
? matchHash.eq(encodedHash)
const isMatched = imageHash
? imageHash.eq(encodedHash)
: true;
return (

View File

@ -12,12 +12,12 @@ import { useTranslation } from '../translate';
import PreImage from './PreImage';
interface Props {
hash: Hash;
imageHash: Hash;
isImminent?: boolean;
withoutOr?: boolean;
}
function PreImageButton ({ hash, isImminent, withoutOr }: Props): React.ReactElement<Props> | null {
function PreImageButton ({ imageHash, isImminent, withoutOr }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const [isPreimageOpen, togglePreimage] = useToggle();
@ -32,7 +32,7 @@ function PreImageButton ({ hash, isImminent, withoutOr }: Props): React.ReactEle
{isPreimageOpen && (
<PreImage
isImminent={isImminent}
matchHash={hash}
imageHash={imageHash}
onClose={togglePreimage}
/>
)}

View File

@ -20,7 +20,7 @@ interface Props {
value: DeriveProposal;
}
function Proposal ({ className, value: { balance, hash, index, proposal, proposer, seconds } }: Props): React.ReactElement<Props> {
function Proposal ({ className, value: { balance, index, image, imageHash, proposer, seconds } }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const seconding = seconds.filter((_address, index): boolean => index !== 0);
@ -35,8 +35,8 @@ function Proposal ({ className, value: { balance, hash, index, proposal, propose
</td>
<ProposalCell
className='top'
proposalHash={hash}
proposal={proposal}
imageHash={imageHash}
proposal={image?.proposal}
/>
<td className='top padtop'>
{seconding.length !== 0 && (
@ -57,11 +57,11 @@ function Proposal ({ className, value: { balance, hash, index, proposal, propose
<Button.Group>
<Seconding
depositors={seconds || []}
image={image}
proposalId={index}
proposal={proposal}
/>
{!proposal && (
<PreImageButton hash={hash} />
{!image?.proposal && (
<PreImageButton imageHash={imageHash} />
)}
</Button.Group>
<LinkExternal

View File

@ -12,18 +12,18 @@ import { useTranslation } from '../translate';
interface Props {
className?: string;
imageHash: Hash | string;
proposal?: Proposal | null;
proposalHash: Hash | string;
}
function ProposalCell ({ className, proposal, proposalHash }: Props): React.ReactElement<Props> {
function ProposalCell ({ className, imageHash, proposal }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
if (!proposal) {
return (
<td className={`${className} all top`}>
<label>{t('preimage hash')}</label>
{proposalHash.toString()}
{imageHash.toString()}
</td>
);
}

View File

@ -22,30 +22,29 @@ interface Props {
value: DeriveReferendumExt;
}
function Referendum ({ className, value }: Props): React.ReactElement<Props> | null {
function Referendum ({ className, value: { allAye, allNay, image, imageHash, index, status, isPassing, voteCountAye, voteCountNay, votedAye, votedNay } }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
const threshold = useMemo(
() => value.status.threshold.type.toString().replace('majority', ' majority '),
[value]
() => status.threshold.type.toString().replace('majority', ' majority '),
[status]
);
if (!bestNumber || value.status.end.sub(bestNumber).lten(0)) {
if (!bestNumber || status.end.sub(bestNumber).lten(0)) {
return null;
}
const enactBlock = value.status.end.add(value.status.delay);
const remainBlock = value.status.end.sub(bestNumber).subn(1);
const { allAye, allNay, isPassing, voteCountAye, voteCountNay, votedAye, votedNay } = value;
const enactBlock = status.end.add(status.delay);
const remainBlock = status.end.sub(bestNumber).subn(1);
return (
<tr className={className}>
<td className='number top'><h1>{formatNumber(value.index)}</h1></td>
<td className='number top'><h1>{formatNumber(index)}</h1></td>
<ProposalCell
className='top'
proposalHash={value.hash}
proposal={value.proposal}
imageHash={imageHash}
proposal={image?.proposal}
/>
<td className='number together top'>
<label>{t('remaining')}</label>
@ -91,15 +90,15 @@ function Referendum ({ className, value }: Props): React.ReactElement<Props> | n
<td className='number together top'>
<Button.Group>
<Voting
proposal={value.proposal}
referendumId={value.index}
proposal={image?.proposal}
referendumId={index}
/>
{!value.proposal && (
<PreImageButton hash={value.hash} />
{!image?.proposal && (
<PreImageButton imageHash={imageHash} />
)}
</Button.Group>
<LinkExternal
data={value.index}
data={index}
type='referendum'
/>
</td>

View File

@ -2,7 +2,8 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Proposal } from '@polkadot/types/interfaces';
import { DeriveProposalImage } from '@polkadot/api-derive/types';
import { AccountId } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import React, { useState } from 'react';
@ -14,11 +15,11 @@ import { useTranslation } from '../translate';
interface Props {
className?: string;
depositors: AccountId[];
proposal?: Proposal;
image?: DeriveProposalImage;
proposalId: BN | number;
}
function Seconding ({ depositors, proposal, proposalId }: Props): React.ReactElement<Props> | null {
function Seconding ({ depositors, image, proposalId }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { hasAccounts } = useAccounts();
const [accountId, setAccountId] = useState<string | null>(null);
@ -40,7 +41,7 @@ function Seconding ({ depositors, proposal, proposalId }: Props): React.ReactEle
<Modal.Content>
<ProposedAction
idNumber={proposalId}
proposal={proposal}
proposal={image?.proposal}
/>
<InputAddress
help={t('Select the account you wish to second with. This will lock your funds until the proposal is either approved or rejected')}

View File

@ -49,8 +49,8 @@ function Overview ({ className }: Props): React.ReactElement {
)}
<Referendums />
<Proposals />
<Externals />
<DispatchQueue />
<Externals />
</div>
);
}

View File

@ -16,15 +16,15 @@ import Voting from './Voting';
interface Props {
className?: string;
hash: string;
imageHash: string;
prime?: AccountId | null;
}
function Proposal ({ className, hash, prime }: Props): React.ReactElement<Props> | null {
function Proposal ({ className, imageHash, prime }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const optProposal = useCall<Option<ProposalType>>(api.query.technicalCommittee.proposalOf, [hash]);
const votes = useCall<Option<Votes>>(api.query.technicalCommittee.voting, [hash]);
const optProposal = useCall<Option<ProposalType>>(api.query.technicalCommittee.proposalOf, [imageHash]);
const votes = useCall<Option<Votes>>(api.query.technicalCommittee.voting, [imageHash]);
if (!optProposal?.isSome || !votes?.isSome) {
return null;
@ -38,7 +38,7 @@ function Proposal ({ className, hash, prime }: Props): React.ReactElement<Props>
<td className='number top'><h1>{formatNumber(index)}</h1></td>
<ProposalCell
className='top'
proposalHash={hash}
imageHash={imageHash}
proposal={proposal}
/>
<td className='number top'>
@ -67,7 +67,7 @@ function Proposal ({ className, hash, prime }: Props): React.ReactElement<Props>
</td>
<td className='number top together'>
<Voting
hash={hash}
hash={imageHash}
prime={prime}
proposalId={index}
/>

View File

@ -6,7 +6,7 @@ import { Hash } from '@polkadot/types/interfaces';
import { ComponentProps as Props } from '../types';
import React from 'react';
import { Table, Button } from '@polkadot/react-components';
import { Button, Spinner, Table } from '@polkadot/react-components';
import { useTranslation } from '../translate';
import Proposal from './Proposal';
@ -23,21 +23,23 @@ function Proposals ({ className, isMember, members, prime, proposals }: Props):
members={members}
/>
</Button.Group>
{proposals?.length
? (
<Table>
<Table.Body>
{proposals?.map((hash: Hash): React.ReactNode => (
<Proposal
hash={hash.toHex()}
key={hash.toHex()}
prime={prime}
/>
))}
</Table.Body>
</Table>
)
: t('No committee proposals')
{proposals
? proposals.length
? (
<Table>
<Table.Body>
{proposals?.map((hash: Hash): React.ReactNode => (
<Proposal
imageHash={hash.toHex()}
key={hash.toHex()}
prime={prime}
/>
))}
</Table.Body>
</Table>
)
: t('No committee proposals')
: <Spinner />
}
</div>
);

View File

@ -31,7 +31,7 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.9.2",
"@polkadot/api": "^1.9.0-beta.16",
"@polkadot/api": "^1.9.0-beta.18",
"@polkadot/extension-dapp": "^0.24.0-beta.0",
"rxjs-compat": "^6.5.4"
}

View File

@ -12,7 +12,7 @@ import styled from 'styled-components';
import { classes } from './util';
const rootElement = typeof document === 'undefined'
? null // This hack is required for server side renreding
? null // This hack is required for server side rendering
: document.getElementById('tooltips');
interface Props extends BareProps {
@ -30,24 +30,19 @@ interface Props extends BareProps {
}
function Tooltip ({ className, effect = 'solid', offset, place = 'top', text, trigger }: Props): React.ReactElement<Props> | null {
const defaultTooltipContainer = typeof document === 'undefined'
? {} as HTMLElement // This hack is required for server side renreding
: document.createElement('div');
const [tooltipContainer] = useState(defaultTooltipContainer);
const [tooltipContainer] = useState(
typeof document === 'undefined'
? {} as HTMLElement // This hack is required for server side rendering
: document.createElement('div')
);
useEffect((): () => void => {
if (rootElement !== null) {
rootElement.appendChild(tooltipContainer);
}
rootElement && rootElement.appendChild(tooltipContainer);
return (): void => {
if (rootElement !== null) {
rootElement.removeChild(tooltipContainer);
}
rootElement && rootElement.removeChild(tooltipContainer);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [tooltipContainer]);
return ReactDOM.createPortal(
<ReactTooltip

View File

@ -13,12 +13,12 @@ interface UseAccounts {
}
export default function useAccounts (): UseAccounts {
const mounted = useIsMountedRef();
const mountedRef = useIsMountedRef();
const [state, setState] = useState<UseAccounts>({ allAccounts: [], hasAccounts: false });
useEffect((): () => void => {
const subscription = accountObservable.subject.subscribe((accounts): void => {
if (mounted.current) {
if (mountedRef.current) {
const allAccounts = accounts ? Object.keys(accounts) : [];
const hasAccounts = allAccounts.length !== 0;

View File

@ -13,12 +13,12 @@ interface UseAccounts {
}
export default function useAccounts (): UseAccounts {
const mounted = useIsMountedRef();
const mountedRef = useIsMountedRef();
const [state, setState] = useState<UseAccounts>({ allAddresses: [], hasAddresses: false });
useEffect((): () => void => {
const subscription = addressObservable.subject.subscribe((addresses): void => {
if (mounted.current) {
if (mountedRef.current) {
const allAddresses = addresses ? Object.keys(addresses) : [];
const hasAddresses = allAddresses.length !== 0;

View File

@ -2,8 +2,6 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Codec } from '@polkadot/types/types';
import React, { useEffect, useState } from 'react';
import { useApi } from '@polkadot/react-hooks';
import { EventRecord } from '@polkadot/types/interfaces';
@ -33,18 +31,18 @@ function EventsBase ({ children }: Props): React.ReactElement<Props> {
// TODO We should really unsub - but since this should just be used once,
// atm I'm rather typing this than doing it the way it is supposed to be
api.isReady.then((): void => {
const prevEventHash = '';
let events: Events = [];
let prevEventHash = '';
api.query.system.events((records: EventRecord[] & Codec): void => {
api.query.system.events((records): void => {
const newEvents = records
.filter(({ event }): boolean => event.section !== 'system')
.map((record, index): KeyedEvent => ({ key: `${Date.now()}-${index}`, record }));
const newEventHash = xxhashAsHex(stringToU8a(JSON.stringify(newEvents)));
if (newEventHash !== prevEventHash) {
events = [...newEvents, ...events].slice(0, MAX_EVENTS);
setState(events);
prevEventHash = newEventHash;
setState((events) => [...newEvents, ...events].slice(0, MAX_EVENTS));
}
});
});

View File

@ -2836,56 +2836,56 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/api-contract@npm:^1.9.0-beta.16":
version: 1.9.0-beta.16
resolution: "@polkadot/api-contract@npm:1.9.0-beta.16"
"@polkadot/api-contract@npm:^1.9.0-beta.18":
version: 1.9.0-beta.18
resolution: "@polkadot/api-contract@npm:1.9.0-beta.18"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/api": 1.9.0-beta.16
"@polkadot/rpc-core": 1.9.0-beta.16
"@polkadot/types": 1.9.0-beta.16
"@polkadot/api": 1.9.0-beta.18
"@polkadot/rpc-core": 1.9.0-beta.18
"@polkadot/types": 1.9.0-beta.18
"@polkadot/util": ^2.7.0-beta.8
bn.js: ^5.1.1
rxjs: ^6.5.4
checksum: 2/cc696c9ff873960519c7957fa20badece865f1ced3fb344427b2276ca50f1e739b94daa6ff09f94a8f2790c4058d0d9a8264dbc11098ebf71e51f8c6eb0d14ed
checksum: 2/fd13019310c6cbaf97bd13d5ab7168991cede9a645311c2f90abb39110e1f4f5e299e98630519f241f84822d55fa7427409961dd257e94dd68f05f0168819b36
languageName: node
linkType: hard
"@polkadot/api-derive@npm:1.9.0-beta.16":
version: 1.9.0-beta.16
resolution: "@polkadot/api-derive@npm:1.9.0-beta.16"
"@polkadot/api-derive@npm:1.9.0-beta.18":
version: 1.9.0-beta.18
resolution: "@polkadot/api-derive@npm:1.9.0-beta.18"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/api": 1.9.0-beta.16
"@polkadot/rpc-core": 1.9.0-beta.16
"@polkadot/rpc-provider": 1.9.0-beta.16
"@polkadot/types": 1.9.0-beta.16
"@polkadot/api": 1.9.0-beta.18
"@polkadot/rpc-core": 1.9.0-beta.18
"@polkadot/rpc-provider": 1.9.0-beta.18
"@polkadot/types": 1.9.0-beta.18
"@polkadot/util": ^2.7.0-beta.8
"@polkadot/util-crypto": ^2.7.0-beta.8
bn.js: ^5.1.1
memoizee: ^0.4.14
rxjs: ^6.5.4
checksum: 2/993cf50b7fd6fb5882287e00d20d496f4c8cc8cb054f9fbca44992ea471bfb92b7463f8794dec2590aef8578e63c62f1f491fc42683793176f62db539e80edeb
checksum: 2/fa132b727b4367c9ad237f1ba7384740ae9a6e140aca32684c2738cb7dd9492d82735998c55da34dd518844bc4d87d3c0a611f0a501e0ae8257aa9bff0542ec5
languageName: node
linkType: hard
"@polkadot/api@npm:^1.9.0-beta.16":
version: 1.9.0-beta.16
resolution: "@polkadot/api@npm:1.9.0-beta.16"
"@polkadot/api@npm:^1.9.0-beta.18":
version: 1.9.0-beta.18
resolution: "@polkadot/api@npm:1.9.0-beta.18"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/api-derive": 1.9.0-beta.16
"@polkadot/api-derive": 1.9.0-beta.18
"@polkadot/keyring": ^2.7.0-beta.8
"@polkadot/metadata": 1.9.0-beta.16
"@polkadot/rpc-core": 1.9.0-beta.16
"@polkadot/rpc-provider": 1.9.0-beta.16
"@polkadot/types": 1.9.0-beta.16
"@polkadot/metadata": 1.9.0-beta.18
"@polkadot/rpc-core": 1.9.0-beta.18
"@polkadot/rpc-provider": 1.9.0-beta.18
"@polkadot/types": 1.9.0-beta.18
"@polkadot/util": ^2.7.0-beta.8
"@polkadot/util-crypto": ^2.7.0-beta.8
bn.js: ^5.1.1
eventemitter3: ^4.0.0
rxjs: ^6.5.4
checksum: 2/b5f3ac2f8b06017ca4c5e8c4bf20a62d05ae4e8e6ab4b88a9969fefa2a9eb616b77a71ef971ade855f55649f961357d13c30106a147f50db9e066411f57ca9ef
checksum: 2/30fdb5b77de613942eea947d2b1461ff819bb5f95145b546828a38efcd58795afb090b13bdeee35257bacfb763f356131793aa83f83aff9c31ac14f2f0dfdfe5
languageName: node
linkType: hard
@ -2926,7 +2926,7 @@ __metadata:
resolution: "@polkadot/app-contracts@workspace:packages/page-contracts"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/api-contract": ^1.9.0-beta.16
"@polkadot/api-contract": ^1.9.0-beta.18
languageName: unknown
linkType: soft
@ -3250,16 +3250,16 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/metadata@npm:1.9.0-beta.16":
version: 1.9.0-beta.16
resolution: "@polkadot/metadata@npm:1.9.0-beta.16"
"@polkadot/metadata@npm:1.9.0-beta.18":
version: 1.9.0-beta.18
resolution: "@polkadot/metadata@npm:1.9.0-beta.18"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/types": 1.9.0-beta.16
"@polkadot/types": 1.9.0-beta.18
"@polkadot/util": ^2.7.0-beta.8
"@polkadot/util-crypto": ^2.7.0-beta.8
bn.js: ^5.1.1
checksum: 2/f22e564a1f686744e53332e3f72e14e61624bca8d6f7d42c0a2c6e51cc613001cec03fb967cd58ea66097f0b9d2027f3645a5c64442726def75e16a946a50969
checksum: 2/134de6a920e88b896da748a860b970e55c106ee6785ae5f71a73c8a69de35f6a34840529149dcf0ed196f662dc454ae53109ef1c3a0226144e449a07b87d80ee
languageName: node
linkType: hard
@ -3268,7 +3268,7 @@ __metadata:
resolution: "@polkadot/react-api@workspace:packages/react-api"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/api": ^1.9.0-beta.16
"@polkadot/api": ^1.9.0-beta.18
"@polkadot/extension-dapp": ^0.24.0-beta.0
rxjs-compat: ^6.5.4
languageName: unknown
@ -3385,35 +3385,35 @@ __metadata:
languageName: unknown
linkType: soft
"@polkadot/rpc-core@npm:1.9.0-beta.16":
version: 1.9.0-beta.16
resolution: "@polkadot/rpc-core@npm:1.9.0-beta.16"
"@polkadot/rpc-core@npm:1.9.0-beta.18":
version: 1.9.0-beta.18
resolution: "@polkadot/rpc-core@npm:1.9.0-beta.18"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/metadata": 1.9.0-beta.16
"@polkadot/rpc-provider": 1.9.0-beta.16
"@polkadot/types": 1.9.0-beta.16
"@polkadot/metadata": 1.9.0-beta.18
"@polkadot/rpc-provider": 1.9.0-beta.18
"@polkadot/types": 1.9.0-beta.18
"@polkadot/util": ^2.7.0-beta.8
memoizee: ^0.4.14
rxjs: ^6.5.4
checksum: 2/caba2f0e5c7bcea77e090e7474e6f5a13ea3ea170cdf624b42944cf05b409f661fb9b9154e5eb60c1f235fc8fa16641643073077e1ee336b035e6277bfcbd4c2
checksum: 2/950388dd9bb321d9ffa51a0b1b6a5dd9465372e84878f15473ab327393564487acff1b759732117a60f2a5b9fe19238aa343cc06f559f0e2c95229d3d724b7ab
languageName: node
linkType: hard
"@polkadot/rpc-provider@npm:1.9.0-beta.16":
version: 1.9.0-beta.16
resolution: "@polkadot/rpc-provider@npm:1.9.0-beta.16"
"@polkadot/rpc-provider@npm:1.9.0-beta.18":
version: 1.9.0-beta.18
resolution: "@polkadot/rpc-provider@npm:1.9.0-beta.18"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/metadata": 1.9.0-beta.16
"@polkadot/types": 1.9.0-beta.16
"@polkadot/metadata": 1.9.0-beta.18
"@polkadot/types": 1.9.0-beta.18
"@polkadot/util": ^2.7.0-beta.8
"@polkadot/util-crypto": ^2.7.0-beta.8
bn.js: ^5.1.1
eventemitter3: ^4.0.0
isomorphic-fetch: ^2.2.1
websocket: ^1.0.31
checksum: 2/b0236848e3801cf433c34ca0c7e68166eff2060a7708c15de3385522e6d044d3e5a1cc364a966af4c0f54b7319dd83fc14b4b696e4b1d8aa7cc2bcdcc2d07f83
checksum: 2/f49729515d67650aa661395a76f69f7fc744ee569357c4b208b9bfd5f69fe57c7362e69d9aa285eaa9add12d8770af1ea2160010a8751aa23b6b3c6e8b59ac15
languageName: node
linkType: hard
@ -3426,19 +3426,19 @@ __metadata:
languageName: node
linkType: hard
"@polkadot/types@npm:^1.9.0-beta.16":
version: 1.9.0-beta.16
resolution: "@polkadot/types@npm:1.9.0-beta.16"
"@polkadot/types@npm:^1.9.0-beta.18":
version: 1.9.0-beta.18
resolution: "@polkadot/types@npm:1.9.0-beta.18"
dependencies:
"@babel/runtime": ^7.9.2
"@polkadot/metadata": 1.9.0-beta.16
"@polkadot/metadata": 1.9.0-beta.18
"@polkadot/util": ^2.7.0-beta.8
"@polkadot/util-crypto": ^2.7.0-beta.8
"@types/bn.js": ^4.11.6
bn.js: ^5.1.1
memoizee: ^0.4.14
rxjs: ^6.5.4
checksum: 2/d21269b1917450448a3cc3ff6ac176b7e56b07dbcff2c3de7be84102d81e9ba93cfe6ff7709e59f0b67cb7659a622f0bb5b28965695f338016f9c8bd6ef9c5ca
checksum: 2/5774694b7f1bdcc0203a4a8e127a9a5d1b3d53d279cdc361f114b844ede77af3d4b337eb11469345d76fee65ed4465b05587fc0b48404286daca60cd17dbc80b
languageName: node
linkType: hard