diff --git a/packages/app-council/src/Overview/index.tsx b/packages/app-council/src/Overview/index.tsx index 529ffbe90bb9..c734e0799011 100644 --- a/packages/app-council/src/Overview/index.tsx +++ b/packages/app-council/src/Overview/index.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { useLocation } from 'react-router-dom'; import { registry } from '@polkadot/react-api'; import { Button } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { createType } from '@polkadot/types'; import Candidates from './Candidates'; @@ -33,9 +33,9 @@ const NULL_INFO: DerivedElectionsInfo = { export default function Overview ({ className }: Props): React.ReactElement { const { api } = useApi(); - const bestNumber = useStream(api.derive.chain.bestNumber, []); - const _electionsInfo = useStream(api.derive.elections.info, []); - const allVotes = useStream>(api.query.electionsPhragmen?.votesOf, [], { + const bestNumber = useCall(api.derive.chain.bestNumber, []); + const _electionsInfo = useCall(api.derive.elections.info, []); + const allVotes = useCall>(api.query.electionsPhragmen?.votesOf, [], { transform: ([voters, casted]: [AccountId[], AccountId[][]]): Record => voters.reduce((result: Record, voter, index): Record => { casted[index].forEach((candidate): void => { diff --git a/packages/app-council/src/index.tsx b/packages/app-council/src/index.tsx index ae872532a8f8..241f75c0ff55 100644 --- a/packages/app-council/src/index.tsx +++ b/packages/app-council/src/index.tsx @@ -10,7 +10,7 @@ import { Route, Switch } from 'react-router'; import { useLocation } from 'react-router-dom'; import styled from 'styled-components'; import { Tabs } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import Overview from './Overview'; import Motions from './Motions'; @@ -23,7 +23,7 @@ interface Props extends AppProps, BareProps, I18nProps {} function App ({ basePath, className, t }: Props): React.ReactElement { const { api } = useApi(); const { pathname } = useLocation(); - const motions = useStream(api.query.council.proposals, []); + const motions = useCall(api.query.council.proposals, []); return (
diff --git a/packages/app-council/src/useCounter.ts b/packages/app-council/src/useCounter.ts index 5b6ac544aa81..52bd8e0add77 100644 --- a/packages/app-council/src/useCounter.ts +++ b/packages/app-council/src/useCounter.ts @@ -5,11 +5,11 @@ import { Hash } from '@polkadot/types/interfaces'; import { useState, useEffect } from 'react'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; export default function useCounter (): number { const { api, isApiReady } = useApi(); - const motions = useStream(isApiReady ? api.query.council?.proposals : undefined, []); + const motions = useCall(isApiReady ? api.query.council?.proposals : undefined, []); const [counter, setCounter] = useState(0); useEffect((): void => { diff --git a/packages/app-democracy/src/Overview/DispatchEntry.tsx b/packages/app-democracy/src/Overview/DispatchEntry.tsx index 254e4393c6f7..56dbb945651b 100644 --- a/packages/app-democracy/src/Overview/DispatchEntry.tsx +++ b/packages/app-democracy/src/Overview/DispatchEntry.tsx @@ -7,7 +7,7 @@ import { AccountId, Balance, BlockNumber, Hash, Proposal, ReferendumIndex } from import { ITuple } from '@polkadot/types/types'; import React, { useEffect, useState } from 'react'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { Bytes, Option } from '@polkadot/types'; import { formatNumber } from '@polkadot/util'; @@ -22,7 +22,7 @@ interface Props extends I18nProps { function DispatchEntry ({ blockNumber, hash, referendumIndex, t }: Props): React.ReactElement { const { api } = useApi(); - const preimage = useStream> + const preimage = useCall> >(api.query.democracy.preimages, [hash]); const [proposal, setProposal] = useState(); diff --git a/packages/app-democracy/src/Overview/DispatchQueue.tsx b/packages/app-democracy/src/Overview/DispatchQueue.tsx index 8147ea579e08..160a1ea6c5f8 100644 --- a/packages/app-democracy/src/Overview/DispatchQueue.tsx +++ b/packages/app-democracy/src/Overview/DispatchQueue.tsx @@ -8,7 +8,7 @@ import { ITuple } from '@polkadot/types/types'; import React, { useState } from 'react'; import { Table } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { Option, StorageKey, Vec } from '@polkadot/types'; import { u8aToHex } from '@polkadot/util'; @@ -18,7 +18,7 @@ import DispatchBlock from './DispatchBlock'; function DispatchQueue ({ className, t }: Props): React.ReactElement | null { const { api } = useApi(); const [keyPrefix] = useState(u8aToHex(api.query.democracy.dispatchQueue.creator.iterKey)); - const queued = useStream<[StorageKey, Option>>> + const queued = useCall<[StorageKey, Option>>> ][]>(api.query.democracy.dispatchQueue.entries as any, []); if (!queued?.length) { diff --git a/packages/app-democracy/src/Overview/Externals.tsx b/packages/app-democracy/src/Overview/Externals.tsx index 7aaaab6b2ecf..92b580016e25 100644 --- a/packages/app-democracy/src/Overview/Externals.tsx +++ b/packages/app-democracy/src/Overview/Externals.tsx @@ -8,7 +8,7 @@ import { I18nProps as Props } from '@polkadot/react-components/types'; import React, { useEffect, useState } from 'react'; import { AddressSmall, Table } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { FormatBalance } from '@polkadot/react-query'; import { Bytes, Option } from '@polkadot/types'; @@ -17,10 +17,10 @@ import ProposalCell from './ProposalCell'; function Externals ({ className, t }: Props): React.ReactElement | null { const { api } = useApi(); - const external = useStream>>(api.query.democracy.nextExternal, []); + const external = useCall>>(api.query.democracy.nextExternal, []); const [hash, setHash] = useState(null); const [expanded, setExpanded] = useState<{ at: BlockNumber; balance: Balance; proposer: AccountId; proposal: Proposal } | null>(null); - const preimage = useStream>>(api.query.democracy.preimages, [hash]); + const preimage = useCall>>(api.query.democracy.preimages, [hash]); useEffect((): void => { setHash( diff --git a/packages/app-democracy/src/Overview/Proposals.tsx b/packages/app-democracy/src/Overview/Proposals.tsx index b075c98d838d..075cc88dda01 100644 --- a/packages/app-democracy/src/Overview/Proposals.tsx +++ b/packages/app-democracy/src/Overview/Proposals.tsx @@ -7,14 +7,14 @@ import { I18nProps as Props } from '@polkadot/react-components/types'; import React from 'react'; import { Table } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import ProposalDisplay from './Proposal'; import translate from '../translate'; function Proposals ({ className, t }: Props): React.ReactElement { const { api } = useApi(); - const proposals = useStream(api.derive.democracy.proposals, []); + const proposals = useCall(api.derive.democracy.proposals, []); return (
diff --git a/packages/app-democracy/src/Overview/Referendums.tsx b/packages/app-democracy/src/Overview/Referendums.tsx index d4fa953adba9..f07aa7658406 100644 --- a/packages/app-democracy/src/Overview/Referendums.tsx +++ b/packages/app-democracy/src/Overview/Referendums.tsx @@ -7,14 +7,14 @@ import { I18nProps as Props } from '@polkadot/react-components/types'; import React from 'react'; import { Table } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import Referendum from './Referendum'; import translate from '../translate'; function Referendums ({ className, t }: Props): React.ReactElement { const { api } = useApi(); - const referendums = useStream(api.derive.democracy.referendums, []); + const referendums = useCall(api.derive.democracy.referendums, []); return (
diff --git a/packages/app-democracy/src/Overview/Summary.tsx b/packages/app-democracy/src/Overview/Summary.tsx index 6667405fefb7..efb5d427893c 100644 --- a/packages/app-democracy/src/Overview/Summary.tsx +++ b/packages/app-democracy/src/Overview/Summary.tsx @@ -8,7 +8,7 @@ import { I18nProps } from '@polkadot/react-components/types'; import BN from 'bn.js'; import React from 'react'; import { SummaryBox, CardSummary } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { withCalls } from '@polkadot/react-api'; import { formatNumber } from '@polkadot/util'; @@ -23,7 +23,7 @@ interface Props extends I18nProps { function Summary (props: Props): React.ReactElement { const { api } = useApi(); - const activeProposals = useStream(api.derive.democracy.proposals, []); + const activeProposals = useCall(api.derive.democracy.proposals, []); const { chain_bestNumber, diff --git a/packages/app-democracy/src/useCounter.ts b/packages/app-democracy/src/useCounter.ts index 8e6684a55bf2..44fae8e70be8 100644 --- a/packages/app-democracy/src/useCounter.ts +++ b/packages/app-democracy/src/useCounter.ts @@ -3,12 +3,12 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { useState, useEffect } from 'react'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; export default function useCounter (): number { const { api, isApiReady } = useApi(); - const proposals = useStream(isApiReady ? api.derive.democracy.proposals : undefined, []); - const referenda = useStream(isApiReady ? api.derive.democracy.referendums : undefined, []); + const proposals = useCall(isApiReady ? api.derive.democracy.proposals : undefined, []); + const referenda = useCall(isApiReady ? api.derive.democracy.referendums : undefined, []); const [counter, setCounter] = useState(0); useEffect((): void => { diff --git a/packages/app-staking/src/Actions/index.tsx b/packages/app-staking/src/Actions/index.tsx index 069d98d3b72e..8d55d1a87c1d 100644 --- a/packages/app-staking/src/Actions/index.tsx +++ b/packages/app-staking/src/Actions/index.tsx @@ -10,7 +10,7 @@ import { AccountId, StakingLedger } from '@polkadot/types/interfaces'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { Button, CardGrid } from '@polkadot/react-components'; -import { useStream, useApi, useAccounts } from '@polkadot/react-hooks'; +import { useCall, useApi, useAccounts } from '@polkadot/react-hooks'; import { AccountName } from '@polkadot/react-query'; import { Option } from '@polkadot/types'; import createOption from '@polkadot/ui-keyring/options/item'; @@ -50,8 +50,8 @@ function getStashes (allAccounts: string[], queryBonded?: Option[], q function Actions ({ allStashes, className, isVisible, recentlyOnline, t }: Props): React.ReactElement { const { api } = useApi(); const { allAccounts } = useAccounts(); - const queryBonded = useStream[]>(api.query.staking.bonded.multi as any, [allAccounts]); - const queryLedger = useStream[]>(api.query.staking.ledger.multi as any, [allAccounts]); + const queryBonded = useCall[]>(api.query.staking.bonded.multi as any, [allAccounts]); + const queryLedger = useCall[]>(api.query.staking.ledger.multi as any, [allAccounts]); const [isNewStakeOpen, setIsNewStateOpen] = useState(false); const [foundStashes, setFoundStashes] = useState<[string, boolean][] | null>(null); const [stashOptions, setStashOptions] = useState([]); diff --git a/packages/app-staking/src/Overview/Address.tsx b/packages/app-staking/src/Overview/Address.tsx index edd5806e1dd8..d55ae9ee6624 100644 --- a/packages/app-staking/src/Overview/Address.tsx +++ b/packages/app-staking/src/Overview/Address.tsx @@ -11,7 +11,7 @@ import BN from 'bn.js'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { AddressMini, AddressSmall, Badge, Icon } from '@polkadot/react-components'; -import { useStream, useApi } from '@polkadot/react-hooks'; +import { useCall, useApi } from '@polkadot/react-hooks'; import { FormatBalance } from '@polkadot/react-query'; import { formatNumber } from '@polkadot/util'; @@ -51,7 +51,7 @@ interface StakingState { function Address ({ address, authorsMap, className, filter, hasQueries, isElected, isFavorite, lastAuthors, myAccounts, points, recentlyOnline, t, toggleFavorite, withNominations = true }: Props): React.ReactElement | null { const { api } = useApi(); // FIXME Any horrors, caused by derive type mismatches - const stakingInfo = useStream(api.derive.staking.info as any, [address]); + const stakingInfo = useCall(api.derive.staking.info as any, [address]); const [hasActivity, setHasActivity] = useState(true); const [{ commission, hasNominators, isNominatorMe, nominators, stashId, stakeOwn, stakeOther, validatorPayment }, setStakingState] = useState({ hasNominators: false, diff --git a/packages/app-staking/src/Targets/Summary.tsx b/packages/app-staking/src/Targets/Summary.tsx index bf1d38e72d6b..9b4b5ab33ecd 100644 --- a/packages/app-staking/src/Targets/Summary.tsx +++ b/packages/app-staking/src/Targets/Summary.tsx @@ -8,7 +8,7 @@ import { I18nProps } from '@polkadot/react-components/types'; import BN from 'bn.js'; import React, { useEffect, useState } from 'react'; import { SummaryBox, CardSummary } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { formatBalance } from '@polkadot/util'; import translate from '../translate'; @@ -25,7 +25,7 @@ interface StakeInfo { function Summary ({ lastReward, t, totalStaked }: Props): React.ReactElement { const { api } = useApi(); - const totalInsurance = useStream(api.query.balances.totalIssuance, []); + const totalInsurance = useCall(api.query.balances.totalIssuance, []); const [{ percentage, staked }, setStakeInfo] = useState({ percentage: '-', staked: null }); const [total, setTotal] = useState(null); diff --git a/packages/app-staking/src/Targets/index.tsx b/packages/app-staking/src/Targets/index.tsx index eecc352b9688..15f81d5a7576 100644 --- a/packages/app-staking/src/Targets/index.tsx +++ b/packages/app-staking/src/Targets/index.tsx @@ -9,11 +9,11 @@ import { SessionRewards } from '../types'; import { ValidatorInfo } from './types'; import BN from 'bn.js'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { registry } from '@polkadot/react-api'; import { InputBalance, Table } from '@polkadot/react-components'; -import { useAccounts, useApi, useDebounce, useFavorites, useStream } from '@polkadot/react-hooks'; +import { useAccounts, useApi, useDebounce, useFavorites, useCall } from '@polkadot/react-hooks'; import { createType } from '@polkadot/types'; import { STORE_FAVS_BASE } from '../constants'; @@ -150,14 +150,23 @@ function Targets ({ className, sessionRewards, t }: Props): React.ReactElement

(new BN(1000)); - const electedInfo = useStream(api.derive.staking.electedInfo, []); + const electedInfo = useCall(api.derive.staking.electedInfo, [], { isSingle: true }); const [favorites, toggleFavorite] = useFavorites(STORE_FAVS_BASE); const [lastReward, setLastReward] = useState(new BN(0)); - const lastBase = useRef(0); - const [baseInfo, setBaseInfo] = useState([]); + const [baseInfo, setBaseInfo] = useState(); const [{ validators, totalStaked }, setWorkable] = useState({ totalStaked: new BN(0), validators: [] }); const amount = useDebounce(_amount); + useEffect((): void => { + if (electedInfo) { + setBaseInfo( + electedInfo.info.map(({ accountId, stakers, validatorPrefs }) => ({ + accountId, stakers, validatorPrefs + })) + ); + } + }, [electedInfo]); + useEffect((): void => { if (sessionRewards && sessionRewards.length) { const lastRewardSession = sessionRewards.filter(({ reward }): boolean => reward.gtn(0)); @@ -171,19 +180,9 @@ function Targets ({ className, sessionRewards, t }: Props): React.ReactElement

{ - if (electedInfo && lastBase.current !== electedInfo.info.length) { - lastBase.current = electedInfo.info.length; - - setBaseInfo( - electedInfo.info.map(({ accountId, stakers, validatorPrefs }) => ({ - accountId, stakers, validatorPrefs - })) - ); + if (baseInfo) { + setWorkable(extractInfo(allAccounts, amount, baseInfo, favorites, lastReward)); } - }, [electedInfo]); - - useEffect((): void => { - setWorkable(extractInfo(allAccounts, amount, baseInfo, favorites, lastReward)); }, [allAccounts, amount, baseInfo, favorites, lastReward]); return ( diff --git a/packages/app-staking/src/index.tsx b/packages/app-staking/src/index.tsx index a3b7a42550fe..eec59caf4d51 100644 --- a/packages/app-staking/src/index.tsx +++ b/packages/app-staking/src/index.tsx @@ -13,7 +13,7 @@ import styled from 'styled-components'; import { Option } from '@polkadot/types'; import { HelpOverlay } from '@polkadot/react-components'; import Tabs from '@polkadot/react-components/Tabs'; -import { useStream, useAccounts, useApi } from '@polkadot/react-hooks'; +import { useCall, useAccounts, useApi } from '@polkadot/react-hooks'; import basicMd from './md/basic.md'; import Actions from './Actions'; @@ -45,12 +45,12 @@ function App ({ basePath, className, t }: Props): React.ReactElement { const { hasAccounts } = useAccounts(); const { pathname } = useLocation(); const [next, setNext] = useState([]); - const [allStashes, allControllers] = (useStream<[string[], string[]]>(api.derive.staking.controllers, [], { + const [allStashes, allControllers] = (useCall<[string[], string[]]>(api.derive.staking.controllers, [], { defaultValue: EMPTY_ALL, transform: transformStakingControllers }) as [string[], string[]]); - const recentlyOnline = useStream(api.derive.imOnline.receivedHeartbeats, []); - const stakingOverview = useStream(api.derive.staking.overview, []); + const recentlyOnline = useCall(api.derive.imOnline.receivedHeartbeats, []); + const stakingOverview = useCall(api.derive.staking.overview, []); const sessionRewards = useSessionRewards(MAX_SESSIONS); const hasQueries = hasAccounts && !!(api.query.imOnline?.authoredBlocks); const validators = stakingOverview?.validators; diff --git a/packages/app-staking/src/useBlockCounts.tsx b/packages/app-staking/src/useBlockCounts.tsx index 5e07362ce79b..273ff2d7b4cb 100644 --- a/packages/app-staking/src/useBlockCounts.tsx +++ b/packages/app-staking/src/useBlockCounts.tsx @@ -6,15 +6,15 @@ import { SessionIndex } from '@polkadot/types/interfaces'; import { SessionRewards } from './types'; import { useEffect, useState } from 'react'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { u32 } from '@polkadot/types'; export default function useBlockCounts (accountId: string, sessionRewards: SessionRewards[]): u32[] { const { api } = useApi(); const [counts, setCounts] = useState([]); const [historic, setHistoric] = useState([]); - const sessionIndex = useStream(api.query.session.currentIndex, []); - const current = useStream(api.query.imOnline?.authoredBlocks, [sessionIndex, accountId]); + const sessionIndex = useCall(api.query.session.currentIndex, []); + const current = useCall(api.query.imOnline?.authoredBlocks, [sessionIndex, accountId]); useEffect((): void => { if (api.query.imOnline?.authoredBlocks && sessionRewards && sessionRewards.length) { diff --git a/packages/app-sudo/src/index.tsx b/packages/app-sudo/src/index.tsx index 4b9ded33689d..167ecf4ac8e7 100644 --- a/packages/app-sudo/src/index.tsx +++ b/packages/app-sudo/src/index.tsx @@ -9,7 +9,7 @@ import { ComponentProps } from './types'; import React, { useEffect, useState } from 'react'; import { Route, Switch } from 'react-router'; import { Icon, Tabs } from '@polkadot/react-components'; -import { useStream, useAccounts, useApi } from '@polkadot/react-hooks'; +import { useCall, useAccounts, useApi } from '@polkadot/react-hooks'; import SetKey from './SetKey'; import Sudo from './Sudo'; @@ -21,7 +21,7 @@ interface Props extends AppProps, I18nProps { function App ({ basePath, t }: Props): React.ReactElement { const { api } = useApi(); - const sudoKey = useStream(api.query.sudo.key, [], { transform: (k): string => k.toString() }); + const sudoKey = useCall(api.query.sudo.key, [], { transform: (k): string => k.toString() }); const { allAccounts } = useAccounts(); const [isMine, setIsMine] = useState(false); diff --git a/packages/app-tech-comm/src/Overview/Summary.tsx b/packages/app-tech-comm/src/Overview/Summary.tsx index 66066ac762e9..499db8e9287e 100644 --- a/packages/app-tech-comm/src/Overview/Summary.tsx +++ b/packages/app-tech-comm/src/Overview/Summary.tsx @@ -8,7 +8,7 @@ import { ComponentProps } from '../types'; import React from 'react'; import { SummaryBox, CardSummary } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { u32 } from '@polkadot/types'; import { formatNumber } from '@polkadot/util'; @@ -18,7 +18,7 @@ interface Props extends ComponentProps, I18nProps {} function Summary ({ className, members, proposals, t }: Props): React.ReactElement { const { api } = useApi(); - const proposalCount = useStream(api.query.technicalCommittee.proposalCount, []); + const proposalCount = useCall(api.query.technicalCommittee.proposalCount, []); return ( diff --git a/packages/app-tech-comm/src/Proposals/Proposal.tsx b/packages/app-tech-comm/src/Proposals/Proposal.tsx index 827253f4a975..72b0789f57c0 100644 --- a/packages/app-tech-comm/src/Proposals/Proposal.tsx +++ b/packages/app-tech-comm/src/Proposals/Proposal.tsx @@ -7,7 +7,7 @@ import { I18nProps } from '@polkadot/react-components/types'; import React from 'react'; import { AddressMini } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import ProposalCell from '@polkadot/app-democracy/Overview/ProposalCell'; import { Option } from '@polkadot/types'; import { formatNumber } from '@polkadot/util'; @@ -21,8 +21,8 @@ interface Props extends I18nProps { function Proposal ({ className, hash, t }: Props): React.ReactElement | null { const { api } = useApi(); - const optProposal = useStream>(api.query.technicalCommittee.proposalOf, [hash]); - const votes = useStream>(api.query.technicalCommittee.voting, [hash]); + const optProposal = useCall>(api.query.technicalCommittee.proposalOf, [hash]); + const votes = useCall>(api.query.technicalCommittee.voting, [hash]); if (!optProposal?.isSome || !votes?.isSome) { return null; diff --git a/packages/app-tech-comm/src/index.tsx b/packages/app-tech-comm/src/index.tsx index 734cc2426dff..77ffb517865f 100644 --- a/packages/app-tech-comm/src/index.tsx +++ b/packages/app-tech-comm/src/index.tsx @@ -7,7 +7,7 @@ import { AppProps, BareProps, I18nProps } from '@polkadot/react-components/types import React from 'react'; import { Route, Switch } from 'react-router'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { Tabs } from '@polkadot/react-components'; import Overview from './Overview'; @@ -20,8 +20,8 @@ interface Props extends AppProps, BareProps, I18nProps {} function App ({ basePath, className, t }: Props): React.ReactElement { const { api } = useApi(); - const members = useStream(api.query.technicalCommittee.members, []); - const proposals = useStream(api.query.technicalCommittee.proposals, []); + const members = useCall(api.query.technicalCommittee.members, []); + const proposals = useCall(api.query.technicalCommittee.proposals, []); return (

diff --git a/packages/app-tech-comm/src/useCounter.ts b/packages/app-tech-comm/src/useCounter.ts index ef82d67a1622..60b76b8f6fb3 100644 --- a/packages/app-tech-comm/src/useCounter.ts +++ b/packages/app-tech-comm/src/useCounter.ts @@ -5,11 +5,11 @@ import { Hash } from '@polkadot/types/interfaces'; import { useState, useEffect } from 'react'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; export default function useCounter (): number { const { api, isApiReady } = useApi(); - const proposals = useStream(isApiReady ? api.query.technicalCommittee && api.query.technicalCommittee.proposals : undefined, []); + const proposals = useCall(isApiReady ? api.query.technicalCommittee && api.query.technicalCommittee.proposals : undefined, []); const [counter, setCounter] = useState(0); useEffect((): void => { diff --git a/packages/app-treasury/src/Overview/Proposal.tsx b/packages/app-treasury/src/Overview/Proposal.tsx index d21bad403fe0..54d595c10fbc 100644 --- a/packages/app-treasury/src/Overview/Proposal.tsx +++ b/packages/app-treasury/src/Overview/Proposal.tsx @@ -9,7 +9,7 @@ import BN from 'bn.js'; import React, { useEffect } from 'react'; import { Option } from '@polkadot/types'; import { AddressMini, AddressSmall } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { FormatBalance } from '@polkadot/react-query'; import { formatNumber } from '@polkadot/util'; @@ -24,7 +24,7 @@ interface Props extends I18nProps { function ProposalDisplay ({ className, onPopulate, proposalId, t }: Props): React.ReactElement | null { const { api } = useApi(); - const proposal = useStream(api.query.treasury.proposals, [proposalId], { + const proposal = useCall(api.query.treasury.proposals, [proposalId], { transform: (value: Option): TreasuryProposal | null => value.unwrapOr(null) }); diff --git a/packages/app-treasury/src/Overview/Summary.tsx b/packages/app-treasury/src/Overview/Summary.tsx index 7361d55119e7..51bd0b9eca9a 100644 --- a/packages/app-treasury/src/Overview/Summary.tsx +++ b/packages/app-treasury/src/Overview/Summary.tsx @@ -7,7 +7,7 @@ import { I18nProps } from '@polkadot/react-components/types'; import BN from 'bn.js'; import React from 'react'; import { SummaryBox, CardSummary } from '@polkadot/react-components'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import { formatBalance, formatNumber, stringToU8a } from '@polkadot/util'; import translate from '../translate'; @@ -21,8 +21,8 @@ interface Props extends I18nProps { function Summary ({ approvalCount, proposalCount, t }: Props): React.ReactElement { const { api } = useApi(); - const pot = useStream(api.query.treasury.pot, []); - const treasuryBalance = useStream(api.query.balances.freeBalance, [TREASURY_ACCOUNT]); + const pot = useCall(api.query.treasury.pot, []); + const treasuryBalance = useCall(api.query.balances.freeBalance, [TREASURY_ACCOUNT]); const value = treasuryBalance?.gtn(0) ? treasuryBalance.toString() diff --git a/packages/app-treasury/src/Overview/index.tsx b/packages/app-treasury/src/Overview/index.tsx index 396ef63d9d2d..29f755020e77 100644 --- a/packages/app-treasury/src/Overview/index.tsx +++ b/packages/app-treasury/src/Overview/index.tsx @@ -6,7 +6,7 @@ import { AppProps, BareProps, I18nProps } from '@polkadot/react-components/types import BN from 'bn.js'; import React, { useEffect, useState } from 'react'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; import Summary from './Summary'; import Proposals from './Proposals'; @@ -16,8 +16,8 @@ interface Props extends AppProps, BareProps, I18nProps {} export default function Overview ({ className }: Props): React.ReactElement { const { api } = useApi(); - const approvalIds = useStream(api.query.treasury.approvals, []); - const proposalCount = useStream(api.query.treasury.proposalCount, []); + const approvalIds = useCall(api.query.treasury.approvals, []); + const proposalCount = useCall(api.query.treasury.proposalCount, []); const [proposalIds, setProposalIds] = useState([]); useEffect((): void => { diff --git a/packages/apps/public/index.html b/packages/apps/public/index.html index f55907b6d7fc..f3991a767d25 100644 --- a/packages/apps/public/index.html +++ b/packages/apps/public/index.html @@ -2,7 +2,6 @@ - diff --git a/packages/apps/src/SideBar/index.tsx b/packages/apps/src/SideBar/index.tsx index 48eabbe86f15..c6c129c4a37b 100644 --- a/packages/apps/src/SideBar/index.tsx +++ b/packages/apps/src/SideBar/index.tsx @@ -13,7 +13,7 @@ import styled from 'styled-components'; import { Responsive } from 'semantic-ui-react'; import routing from '@polkadot/apps-routing'; import { Button, ChainImg, Icon, Menu, media } from '@polkadot/react-components'; -import { useStream, useApi } from '@polkadot/react-hooks'; +import { useCall, useApi } from '@polkadot/react-hooks'; import { classes } from '@polkadot/react-components/util'; import { BestNumber, Chain } from '@polkadot/react-query'; @@ -33,7 +33,7 @@ interface Props extends I18nProps { function SideBar ({ className, collapse, handleResize, isCollapsed, toggleMenu, menuOpen }: Props): React.ReactElement { const { api } = useApi(); - const runtimeVersion = useStream(api.rpc.state.subscribeRuntimeVersion, []); + const runtimeVersion = useCall(api.rpc.state.subscribeRuntimeVersion, []); const [modals, setModals] = useState>( routing.routes.reduce((result: Record, route): Record => { if (route && route.Modal) { diff --git a/packages/react-hooks/src/index.ts b/packages/react-hooks/src/index.ts index 5d9c5e2e6f95..c1b62f54bdde 100644 --- a/packages/react-hooks/src/index.ts +++ b/packages/react-hooks/src/index.ts @@ -2,12 +2,11 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -export { default as usePromise } from './track/usePromise'; -export { default as useStream } from './track/useStream'; export { default as useAccounts } from './useAccounts'; export { default as useAddresses } from './useAddresses'; export { default as useApi } from './useApi'; export { default as useCacheKey } from './useCacheKey'; +export { default as useCall } from './useCall'; export { default as useForm } from './useForm'; export { default as useDebounce } from './useDebounce'; export { default as useFavorites } from './useFavorites'; diff --git a/packages/react-hooks/src/track/types.ts b/packages/react-hooks/src/track/types.ts deleted file mode 100644 index caaa650be3a5..000000000000 --- a/packages/react-hooks/src/track/types.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017-2019 @polkadot/react-hooks authors & contributors -// This software may be modified and distributed under the terms -// of the Apache-2.0 license. See the LICENSE file for details. - -export type Param = any; - -export type Params = [] | [Param] | [Param, Param] | [Param, Param, Param]; - -export interface Options { - defaultValue?: T; - isDebug?: boolean; - paramMap?: (params: any) => Params; - transform?: (value: any) => T; -} diff --git a/packages/react-hooks/src/track/usePromise.tsx b/packages/react-hooks/src/track/usePromise.tsx deleted file mode 100644 index 31ed64e9e87b..000000000000 --- a/packages/react-hooks/src/track/usePromise.tsx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2017-2019 @polkadot/react-hooks 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 { Options, Param, Params } from './types'; - -import { useEffect, useRef, useState } from 'react'; - -import { extractParams, transformIdentity } from './util'; - -interface TrackFn { - (a: Param, b: Param, c: Param): Promise; - (a: Param, b: Param): Promise; - (a: Param): Promise; - (): Promise; -} - -// tracks a promise, typically an api.* call (query, query.at, rpc) that -// - returns a promise with the value -// FIXME The typings here need some serious TLC -export default function usePromise (fn: TrackFn | undefined, params: Params, { defaultValue, paramMap = transformIdentity, transform = transformIdentity }: Options = {}): T | undefined { - const [value, setValue] = useState(defaultValue); - const tracker = useRef<{ serialized: string | null }>({ serialized: null }); - - const _subscribe = (params: Params): void => { - setImmediate((): void => { - if (fn) { - // eslint-disable-next-line @typescript-eslint/ban-ts-ignore - // @ts-ignore We tried to get the typings right, close but no cigar... - fn(...params).then((value: any): void => setValue(transform(value))); - } - }); - }; - - // on changes, re-get - useEffect((): void => { - if (fn) { - const [serialized, mappedParams] = extractParams(fn, params, paramMap); - - if (mappedParams && serialized !== tracker.current.serialized) { - tracker.current.serialized = serialized; - - _subscribe(mappedParams); - } - } - }, [fn, params]); - - return value; -} diff --git a/packages/react-hooks/src/track/useStream.tsx b/packages/react-hooks/src/track/useStream.tsx deleted file mode 100644 index c80f289d4ec3..000000000000 --- a/packages/react-hooks/src/track/useStream.tsx +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2017-2019 @polkadot/react-hooks 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 { Codec } from '@polkadot/types/types'; -import { Options, Param, Params } from './types'; - -import { useEffect, useRef, useState } from 'react'; -import { isUndefined } from '@polkadot/util'; - -import { extractParams, transformIdentity } from './util'; - -interface TrackFnCallback { - (value: Codec): void; -} - -type TrackFnResult = Promise<() => void>; - -interface TrackFn { - (a: Param, b: Param, c: Param, cb: TrackFnCallback): TrackFnResult; - (a: Param, b: Param, cb: TrackFnCallback): TrackFnResult; - (a: Param, cb: TrackFnCallback): TrackFnResult; - (cb: TrackFnCallback): TrackFnResult; - meta?: { - type: { - isDoubleMap: boolean; - }; - }; -} - -// tracks a stream, typically an api.* call (derive, rpc, query) that -// - returns a promise with an unsubscribe function -// - has a callback to set the value -// FIXME The typings here need some serious TLC -export default function useStream (fn: TrackFn | undefined, params: Params, { defaultValue, isDebug, paramMap = transformIdentity, transform = transformIdentity }: Options = {}): T | undefined { - const [value, setValue] = useState(defaultValue); - const tracker = useRef<{ serialized: string | null; subscriber: TrackFnResult | null }>({ serialized: null, subscriber: null }); - - const _debug = (fn: () => any[]): void => { - isDebug && console.log(...fn()); - }; - const _unsubscribe = (): void => { - if (tracker.current.subscriber) { - _debug(() => ['unsubscribe', fn?.name]); - - tracker.current.subscriber.then((unsubFn): void => unsubFn()); - tracker.current.subscriber = null; - } - }; - const _subscribe = (params: Params): void => { - _debug(() => ['subscribe', fn?.name]); - - const validParams = params.filter((p): boolean => !isUndefined(p)); - - _unsubscribe(); - - setImmediate((): void => { - tracker.current.subscriber = fn && (!fn.meta || !fn.meta.type?.isDoubleMap || validParams.length === 2) - // eslint-disable-next-line @typescript-eslint/ban-ts-ignore - // @ts-ignore We tried to get the typings right, close but no cigar... - ? fn(...params, (value: any): void => { - _debug(() => ['setValue', JSON.stringify({ value })]); - setValue(transform(value)); - }) - : null; - }); - }; - - // initial effect, we need an unsubscription - useEffect((): () => void => { - return _unsubscribe; - }, []); - - // on changes, re-subscribe - useEffect((): void => { - if (fn) { - const [serialized, mappedParams] = extractParams(fn, params, paramMap); - - if (mappedParams && serialized !== tracker.current.serialized) { - _debug(() => ['_createSubscription', fn?.name, serialized]); - - tracker.current.serialized = serialized; - - _subscribe(mappedParams); - } - } - }, [fn, params]); - - return value; -} diff --git a/packages/react-hooks/src/types.ts b/packages/react-hooks/src/types.ts index 99ef9f82ab25..737d710c9c15 100644 --- a/packages/react-hooks/src/types.ts +++ b/packages/react-hooks/src/types.ts @@ -7,6 +7,17 @@ import { AccountId, Balance, BlockNumber, Call, Hash, SessionIndex } from '@polk import { IExtrinsic } from '@polkadot/types/types'; import { SubmittableExtrinsic } from '@polkadot/api/promise/types'; +export type CallParam = any; + +export type CallParams = [] | [CallParam] | [CallParam, CallParam] | [CallParam, CallParam, CallParam]; + +export interface CallOptions { + defaultValue?: T; + isSingle?: boolean; + paramMap?: (params: any) => CallParams; + transform?: (value: any) => T; +} + export type TxDef = [string, any[] | ConstructTxFn]; export type TxDefs = SubmittableExtrinsic | IExtrinsic | Call | TxDef | null; diff --git a/packages/react-hooks/src/useCall.tsx b/packages/react-hooks/src/useCall.tsx new file mode 100644 index 000000000000..b750aa9093a3 --- /dev/null +++ b/packages/react-hooks/src/useCall.tsx @@ -0,0 +1,104 @@ +// Copyright 2017-2019 @polkadot/react-hooks 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 { Codec } from '@polkadot/types/types'; +import { CallOptions, CallParam, CallParams } from './types'; + +import { useEffect, useRef, useState } from 'react'; +import { isUndefined } from '@polkadot/util'; + +import { extractParams, transformIdentity } from './util'; + +interface TrackFnCallback { + (value: Codec): void; +} + +type TrackFnResult = Promise<() => void>; + +interface TrackFn { + (a: CallParam, b: CallParam, c: CallParam, cb: TrackFnCallback): TrackFnResult; + (a: CallParam, b: CallParam, cb: TrackFnCallback): TrackFnResult; + (a: CallParam, cb: TrackFnCallback): TrackFnResult; + (cb: TrackFnCallback): TrackFnResult; + meta?: { + type: { + isDoubleMap: boolean; + }; + }; +} + +interface Tracker { + isActive: boolean; + count: number; + serialized: string | null; + subscriber: TrackFnResult | null; +} + +interface TrackerRef { + current: Tracker; +} + +// unsubscribe and remove from the tracker +function unsubscribe (tracker: TrackerRef): void { + if (tracker.current.subscriber) { + tracker.current.isActive = false; + tracker.current.subscriber.then((unsubFn): void => unsubFn()); + tracker.current.subscriber = null; + } +} + +// subscribe, tyring to play nice with the browser threads +function subscribe (tracker: TrackerRef, fn: TrackFn | undefined, params: CallParams, setValue: (value: T) => void, { isSingle, transform = transformIdentity }: CallOptions): void { + const validParams = params.filter((p): boolean => !isUndefined(p)); + + unsubscribe(tracker); + + setTimeout((): void => { + tracker.current.isActive = true; + tracker.current.count = 0; + tracker.current.subscriber = fn && (!fn.meta || !fn.meta.type?.isDoubleMap || validParams.length === 2) + // eslint-disable-next-line @typescript-eslint/ban-ts-ignore + // @ts-ignore We tried to get the typings right, close but no cigar... + ? fn(...params, (value: any): void => { + // when we don't have an active sub, or single-shot, ignore (we use the isActive flag here + // since .subscriber may not be set on immeditae callback) + if (tracker.current.isActive && (!isSingle || !tracker.current.count)) { + tracker.current.count++; + setValue(transform(value)); + } + }) + : null; + }, 0); +} + +// tracks a stream, typically an api.* call (derive, rpc, query) that +// - returns a promise with an unsubscribe function +// - has a callback to set the value +// FIXME The typings here need some serious TLC +export default function useCall (fn: TrackFn | undefined, params: CallParams, options: CallOptions = {}): T | undefined { + const [value, setValue] = useState(options.defaultValue); + const tracker = useRef({ isActive: false, count: 0, serialized: null, subscriber: null }); + + // initial effect, we need an unsubscription + useEffect((): () => void => { + return (): void => { + unsubscribe(tracker); + }; + }, []); + + // on changes, re-subscribe + useEffect((): void => { + if (fn) { + const [serialized, mappedParams] = extractParams(fn, params, options.paramMap || transformIdentity); + + if (mappedParams && serialized !== tracker.current.serialized) { + tracker.current.serialized = serialized; + + subscribe(tracker, fn, mappedParams, setValue, options); + } + } + }, [fn, params]); + + return value; +} diff --git a/packages/react-hooks/src/track/util.ts b/packages/react-hooks/src/util.ts similarity index 89% rename from packages/react-hooks/src/track/util.ts rename to packages/react-hooks/src/util.ts index ddc41dad2f98..dcf4c924c58e 100644 --- a/packages/react-hooks/src/track/util.ts +++ b/packages/react-hooks/src/util.ts @@ -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 { Params } from './types'; +import { CallParams } from './types'; import { isNull, isUndefined } from '@polkadot/util'; @@ -15,7 +15,7 @@ export function transformIdentity (value: any): any { } // extract the serialized and mapped params, all ready for use in our call -export function extractParams (fn: any, params: any[], paramMap: (params: any[]) => any): [string, Params | null] { +export function extractParams (fn: any, params: any[], paramMap: (params: any[]) => any): [string, CallParams | null] { return [ JSON.stringify({ f: fn?.name, p: params }), params.length === 0 || !params.some((param): boolean => isNull(param) || isUndefined(null)) diff --git a/packages/react-query/src/AccountIndex.tsx b/packages/react-query/src/AccountIndex.tsx index cc6baad3852a..598d9d3ee178 100644 --- a/packages/react-query/src/AccountIndex.tsx +++ b/packages/react-query/src/AccountIndex.tsx @@ -7,7 +7,7 @@ import { DeriveAccountInfo } from '@polkadot/api-derive/types'; import { BareProps } from '@polkadot/react-api/types'; import React, { useState, useEffect } from 'react'; -import { useApi, useStream } from '@polkadot/react-hooks'; +import { useApi, useCall } from '@polkadot/react-hooks'; interface Props extends BareProps { children?: React.ReactNode; @@ -16,9 +16,9 @@ interface Props extends BareProps { params?: string | AccountId | Address | null; } -export default function AccountIndexDisplay ({ children, className, defaultValue = '-', label = '', params, style }: Props): React.ReactElement { +export default function AccountIndexDisplay ({ children, className, defaultValue, label, params, style }: Props): React.ReactElement { const { api } = useApi(); - const info = useStream(api.derive.accounts.info as any, [params]); + const info = useCall(api.derive.accounts.info as any, [params]); const [accountIndex, setAccountIndex] = useState(null); useEffect((): void => { @@ -34,7 +34,7 @@ export default function AccountIndexDisplay ({ children, className, defaultValue className={className} style={style} > - {label}{accountIndex || defaultValue}{children} + {label || ''}{accountIndex || defaultValue || '-'}{children}
); } diff --git a/packages/react-query/src/AccountName.tsx b/packages/react-query/src/AccountName.tsx index 3b73a72ae536..89f63dcd4c47 100644 --- a/packages/react-query/src/AccountName.tsx +++ b/packages/react-query/src/AccountName.tsx @@ -8,7 +8,7 @@ import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces'; import React, { useState, useEffect } from 'react'; import { getAddressName } from '@polkadot/react-components/util'; -import { useStream, useApi } from '@polkadot/react-hooks'; +import { useCall, useApi } from '@polkadot/react-hooks'; interface Props extends BareProps { children?: React.ReactNode; @@ -43,9 +43,9 @@ function defaultOrAddr (defaultName = '', _address?: AccountId | AccountIndex | return extracted; } -export default function AccountName ({ children, className, defaultName, label = '', onClick, override, params, style, toggle, withShort }: Props): React.ReactElement { +export default function AccountName ({ children, className, defaultName, label, onClick, override, params, style, toggle, withShort }: Props): React.ReactElement { const { api } = useApi(); - const info = useStream(api.derive.accounts.info as any, [params]); + const info = useCall(api.derive.accounts.info as any, [params]); const [name, setName] = useState(defaultOrAddr(defaultName, params)); useEffect((): void => { @@ -71,7 +71,7 @@ export default function AccountName ({ children, className, defaultName, label = } style={style} > - {label}{override || name}{children} + {label || ''}{override || name}{children}
); } diff --git a/packages/react-query/src/BestFinalized.tsx b/packages/react-query/src/BestFinalized.tsx index 4aeb1341e09d..7d3741948e9c 100644 --- a/packages/react-query/src/BestFinalized.tsx +++ b/packages/react-query/src/BestFinalized.tsx @@ -16,13 +16,13 @@ interface Props extends BareProps, CallProps { chain_bestNumberFinalized?: BlockNumber; } -export function BestFinalized ({ children, className, label = '', style, chain_bestNumberFinalized }: Props): React.ReactElement { +export function BestFinalized ({ children, className, label, style, chain_bestNumberFinalized }: Props): React.ReactElement { return (
- {label}{ + {label || ''}{ chain_bestNumberFinalized ? formatNumber(chain_bestNumberFinalized) : '-' diff --git a/packages/react-query/src/BestNumber.tsx b/packages/react-query/src/BestNumber.tsx index 073cd704dd16..6818cf7b7297 100644 --- a/packages/react-query/src/BestNumber.tsx +++ b/packages/react-query/src/BestNumber.tsx @@ -16,13 +16,13 @@ interface Props extends BareProps, CallProps { chain_bestNumber?: BlockNumber; } -export function BestNumber ({ children, className, label = '', style, chain_bestNumber }: Props): React.ReactElement { +export function BestNumber ({ children, className, label, style, chain_bestNumber }: Props): React.ReactElement { return (
- {label}{ + {label || ''}{ chain_bestNumber ? formatNumber(chain_bestNumber) : '-' diff --git a/packages/react-query/src/Bonded.tsx b/packages/react-query/src/Bonded.tsx index e17ce2db23fb..1ee4eafd68a5 100644 --- a/packages/react-query/src/Bonded.tsx +++ b/packages/react-query/src/Bonded.tsx @@ -19,7 +19,7 @@ interface Props extends BareProps, CallProps { staking_ledger?: StakingLedger | null; } -export function BondedDisplay ({ children, className, label = '', staking_ledger }: Props): React.ReactElement { +export function BondedDisplay ({ children, className, label, staking_ledger }: Props): React.ReactElement { return ( { +export default function Chain ({ children, className, label, style }: Props): React.ReactElement { const { systemChain } = useApi(); return ( @@ -21,7 +21,7 @@ export default function Chain ({ children, className, label = '', style }: Props className={className} style={style} > - {label}{systemChain}{children} + {label || ''}{systemChain}{children}
); } diff --git a/packages/react-query/src/FormatBalance.tsx b/packages/react-query/src/FormatBalance.tsx index 1d5e124fc1a1..f2385668e70b 100644 --- a/packages/react-query/src/FormatBalance.tsx +++ b/packages/react-query/src/FormatBalance.tsx @@ -30,12 +30,12 @@ function format (value: Compact | BN | string, currency: string): React.Rea return <>{prefix}.{`000${postfix || ''}`.slice(-3)} {currency}; } -function FormatBalance ({ children, className, label = '', value }: Props): React.ReactElement { +function FormatBalance ({ children, className, label, value }: Props): React.ReactElement { const [currency] = useState(formatBalance.getDefaults().unit); return (
- {label}{ + {label || ''}{ value ? format(value, currency) : '-' diff --git a/packages/react-query/src/LockedVote.tsx b/packages/react-query/src/LockedVote.tsx index 70702e86afd2..2a514c034f68 100644 --- a/packages/react-query/src/LockedVote.tsx +++ b/packages/react-query/src/LockedVote.tsx @@ -18,7 +18,7 @@ interface Props extends BareProps, CallProps { electionsPhragmen_stakeOf?: BalanceOf; } -export function LockedVote ({ children, className, electionsPhragmen_stakeOf, label = '' }: Props): React.ReactElement { +export function LockedVote ({ children, className, electionsPhragmen_stakeOf, label }: Props): React.ReactElement { return ( { +export default function NodeName ({ children, className, label, style }: Props): React.ReactElement { const { systemName } = useApi(); return ( @@ -21,7 +21,7 @@ export default function NodeName ({ children, className, label = '', style }: Pr className={className} style={style} > - {label}{systemName}{children} + {label || ''}{systemName}{children}
); } diff --git a/packages/react-query/src/NodeVersion.tsx b/packages/react-query/src/NodeVersion.tsx index 9e11b7e9a5c4..af465d5245c0 100644 --- a/packages/react-query/src/NodeVersion.tsx +++ b/packages/react-query/src/NodeVersion.tsx @@ -13,7 +13,7 @@ interface Props extends BareProps { label?: React.ReactNode; } -export default function NodeVersion ({ children, className, label = '', style }: Props): React.ReactElement { +export default function NodeVersion ({ children, className, label, style }: Props): React.ReactElement { const { systemVersion } = useApi(); return ( @@ -21,7 +21,7 @@ export default function NodeVersion ({ children, className, label = '', style }: className={className} style={style} > - {label}{systemVersion}{children} + {label || ''}{systemVersion}{children}
); } diff --git a/packages/react-query/src/Nonce.tsx b/packages/react-query/src/Nonce.tsx index 624edae1ca73..feb35e36ce6e 100644 --- a/packages/react-query/src/Nonce.tsx +++ b/packages/react-query/src/Nonce.tsx @@ -18,10 +18,10 @@ interface Props extends BareProps, CallProps { params?: string | null; } -export function Nonce ({ accountNonce, children, className, label = '' }: Props): React.ReactElement { +export function Nonce ({ accountNonce, children, className, label }: Props): React.ReactElement { return (
- {label}{ + {label || ''}{ accountNonce ? formatNumber(accountNonce) : '0' diff --git a/packages/react-query/src/TimeNow.tsx b/packages/react-query/src/TimeNow.tsx index fdb0a33f3f36..3e2c51222a63 100644 --- a/packages/react-query/src/TimeNow.tsx +++ b/packages/react-query/src/TimeNow.tsx @@ -17,7 +17,7 @@ interface Props extends BareProps, CallProps { timestamp_now?: Moment; } -export function TimeNow ({ children, className, isSubstrateV2, label = '', style, timestamp_now }: Props): React.ReactElement { +export function TimeNow ({ children, className, isSubstrateV2, label, style, timestamp_now }: Props): React.ReactElement { const value = isSubstrateV2 || !timestamp_now ? timestamp_now : timestamp_now.muln(1000); // for 1.x, timestamps are in seconds @@ -27,7 +27,7 @@ export function TimeNow ({ children, className, isSubstrateV2, label = '', style className={className} style={style} > - {label} + {label || ''} {children}
diff --git a/packages/react-query/src/TimePeriod.tsx b/packages/react-query/src/TimePeriod.tsx index e4fae5c064f9..650b674d5f90 100644 --- a/packages/react-query/src/TimePeriod.tsx +++ b/packages/react-query/src/TimePeriod.tsx @@ -17,13 +17,13 @@ interface Props extends BareProps, CallProps { timestamp_minimumPeriod?: Moment; } -export function TimePeriod ({ babe_expectedBlockTime, children, className, label = '', style, timestamp_minimumPeriod }: Props): React.ReactElement { +export function TimePeriod ({ babe_expectedBlockTime, children, className, label, style, timestamp_minimumPeriod }: Props): React.ReactElement { return (
- {label}{ + {label || ''}{ babe_expectedBlockTime ? `${formatNumber(babe_expectedBlockTime.toNumber() / 1000)}s` : timestamp_minimumPeriod diff --git a/packages/react-query/src/TotalIssuance.tsx b/packages/react-query/src/TotalIssuance.tsx index f812398857f7..9cf3d20a9cc8 100644 --- a/packages/react-query/src/TotalIssuance.tsx +++ b/packages/react-query/src/TotalIssuance.tsx @@ -16,7 +16,7 @@ interface Props extends BareProps, CallProps { balances_totalIssuance?: Balance; } -export function TotalIssuance ({ children, className, label = '', style, balances_totalIssuance }: Props): React.ReactElement { +export function TotalIssuance ({ children, className, label, style, balances_totalIssuance }: Props): React.ReactElement { const value = balances_totalIssuance ? balances_totalIssuance.toString() : null; @@ -26,7 +26,7 @@ export function TotalIssuance ({ children, className, label = '', style, balance className={className} style={style} > - {label}{ + {label || ''}{ value ? `${formatBalance(value, false)}${formatBalance.calcSi(value).value}` : '-'