diff --git a/packages/page-treasury/src/Overview/Tip.tsx b/packages/page-treasury/src/Overview/Tip.tsx index 3c6992188b..cbcd175f01 100644 --- a/packages/page-treasury/src/Overview/Tip.tsx +++ b/packages/page-treasury/src/Overview/Tip.tsx @@ -7,9 +7,8 @@ import { AccountId, Balance, BlockNumber, OpenTip, OpenTipTo225 } from '@polkado import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { AddressSmall, AddressMini, Expander, Icon, TxButton } from '@polkadot/react-components'; -import { useAccounts, useApi, useCall } from '@polkadot/react-hooks'; +import { useAccounts } from '@polkadot/react-hooks'; import { BlockToTime, FormatBalance } from '@polkadot/react-query'; -import { Option } from '@polkadot/types'; import { formatNumber, isBoolean } from '@polkadot/util'; import { useTranslation } from '../translate'; @@ -23,7 +22,7 @@ interface Props { hash: string; isMember: boolean; members: string[]; - setClosed: (hash: string, blockNumber: BlockNumber) => void; + tip: OpenTip | OpenTipTo225; } interface TipState { @@ -38,45 +37,34 @@ function isCurrentTip (tip: OpenTip | OpenTipTo225): tip is OpenTip { return isBoolean((tip as OpenTip).findersFee); } -function Tip ({ bestNumber, className = '', hash, isMember, members, setClosed }: Props): React.ReactElement | null { +function Tip ({ bestNumber, className = '', hash, isMember, members, tip }: Props): React.ReactElement | null { const { t } = useTranslation(); - const { api } = useApi(); const { allAccounts } = useAccounts(); const [{ closesAt, deposit, finder, isFinder, isTipper }, setTipState] = useState({ closesAt: null, deposit: null, finder: null, isFinder: false, isTipper: false }); - const tip = useCall(api.query.treasury.tips, [hash], { - transform: (optTip: Option) => optTip.unwrapOr(null) - }); useEffect((): void => { - if (tip) { - const closesAt = tip.closes.unwrapOr(null); - let finder: AccountId | null = null; - let deposit: Balance | null = null; + const closesAt = tip.closes.unwrapOr(null); + let finder: AccountId | null = null; + let deposit: Balance | null = null; - if (isCurrentTip(tip)) { - finder = tip.finder; - deposit = tip.deposit; - } else if (tip.finder.isSome) { - const finderInfo = tip.finder.unwrap(); + if (isCurrentTip(tip)) { + finder = tip.finder; + deposit = tip.deposit; + } else if (tip.finder.isSome) { + const finderInfo = tip.finder.unwrap(); - finder = finderInfo[0]; - deposit = finderInfo[1]; - } - - closesAt && setClosed(hash, closesAt); - setTipState({ - closesAt, - deposit, - finder, - isFinder: !!finder && allAccounts.includes(finder.toString()), - isTipper: tip.tips.some(([address]) => allAccounts.includes(address.toString())) - }); + finder = finderInfo[0]; + deposit = finderInfo[1]; } - }, [allAccounts, hash, setClosed, tip]); - if (!tip) { - return null; - } + setTipState({ + closesAt, + deposit, + finder, + isFinder: !!finder && allAccounts.includes(finder.toString()), + isTipper: tip.tips.some(([address]) => allAccounts.includes(address.toString())) + }); + }, [allAccounts, hash, tip]); const { reason, tips, who } = tip; diff --git a/packages/page-treasury/src/Overview/Tips.tsx b/packages/page-treasury/src/Overview/Tips.tsx index 6e959736ab..9151a15ce2 100644 --- a/packages/page-treasury/src/Overview/Tips.tsx +++ b/packages/page-treasury/src/Overview/Tips.tsx @@ -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 { BlockNumber } from '@polkadot/types/interfaces'; +import { BlockNumber, OpenTip, OpenTipTo225 } from '@polkadot/types/interfaces'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { Table } from '@polkadot/react-components'; import { useApi, useCall } from '@polkadot/react-hooks'; +import { Option } from '@polkadot/types'; import { BN_ZERO } from '@polkadot/util'; import { useTranslation } from '../translate'; @@ -19,27 +20,23 @@ interface Props { members: string[]; } +type Tip = [string, OpenTip | OpenTipTo225]; + function Tips ({ className = '', hashes, isMember, members }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); const bestNumber = useCall(api.derive.chain.bestNumber, []); - const [closed, setClosed] = useState>({}); - const [sorted, setSorted] = useState([]); + const [tips, setTips] = useState(); + const optTips = useCall[]>(hashes && api.query.treasury.tips.multi, [hashes]); useEffect((): void => { - hashes && setSorted( - hashes.sort((a, b) => (closed[a] || BN_ZERO).cmp(closed[b] || BN_ZERO)) + hashes && optTips && setTips( + optTips + .map((opt, index): [string, OpenTip | null] => [hashes[index], opt.unwrapOr(null)]) + .filter((val): val is [string, OpenTip] => !!val[1]) + .sort((a, b) => a[1].closes.unwrapOr(BN_ZERO).cmp(b[1].closes.unwrapOr(BN_ZERO))) ); - }, [closed, hashes]); - - const _setClosed = useCallback( - (hash: string, blockNumber: BlockNumber) => - setClosed((closed) => ({ - ...closed, - [hash]: blockNumber - })), - [] - ); + }, [hashes, optTips]); const header = useMemo(() => [ [t('tips'), 'start'], @@ -54,17 +51,17 @@ function Tips ({ className = '', hashes, isMember, members }: Props): React.Reac return ( ('No open tips')} + empty={tips && t('No open tips')} header={header} > - {sorted.length !== 0 && sorted.map((hash): React.ReactNode => ( + {tips?.map(([hash, tip]): React.ReactNode => ( ))}
diff --git a/packages/page-treasury/src/Overview/index.tsx b/packages/page-treasury/src/Overview/index.tsx index 2af5e94df8..a5fa9fe45e 100644 --- a/packages/page-treasury/src/Overview/index.tsx +++ b/packages/page-treasury/src/Overview/index.tsx @@ -21,18 +21,18 @@ function Overview ({ className }: Props): React.ReactElement { const { isMember, members } = useMembers(); const mountedRef = useIsMountedRef(); - const [hashTrigger, triggerHashes] = useIncrement(); - const [hashes, setHashes] = useState(null); + const [tipHashTrigger, triggerTipHashes] = useIncrement(); + const [tipHashes, setTipHashes] = useState(null); useEffect((): void => { - if (hashTrigger && mountedRef.current) { + if (tipHashTrigger && mountedRef.current) { api.query.treasury.tips.keys().then((keys) => - mountedRef.current && setHashes( + mountedRef.current && setTipHashes( keys.map((key) => key.args[0].toHex()) ) ).catch(console.error); } - }, [api, hashTrigger, mountedRef]); + }, [api, tipHashTrigger, mountedRef]); return (
@@ -44,7 +44,7 @@ function Overview ({ className }: Props): React.ReactElement { { proposals={info?.approvals} />