From 75b24956e755094a824d1150d2b6b0755d23ebb5 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 24 Mar 2021 12:37:59 +0100 Subject: [PATCH] Tip hash hook (#4917) --- packages/page-treasury/src/Tips/Tip.tsx | 5 +-- packages/page-treasury/src/Tips/TipCreate.tsx | 4 +-- packages/page-treasury/src/Tips/Tips.tsx | 4 +-- packages/page-treasury/src/Tips/index.tsx | 9 ++---- packages/page-treasury/src/index.tsx | 32 ++++++++----------- packages/page-treasury/src/useTipHashes.ts | 30 +++++++++++++++++ 6 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 packages/page-treasury/src/useTipHashes.ts diff --git a/packages/page-treasury/src/Tips/Tip.tsx b/packages/page-treasury/src/Tips/Tip.tsx index 53620cd33e..3b28e22297 100644 --- a/packages/page-treasury/src/Tips/Tip.tsx +++ b/packages/page-treasury/src/Tips/Tip.tsx @@ -23,7 +23,6 @@ interface Props { hash: string; isMember: boolean; members: string[]; - onRefresh: () => void; onSelect: (hash: string, isSelected: boolean, value: BN) => void; onlyUntipped: boolean; tip: OpenTip | OpenTipTo225; @@ -77,7 +76,7 @@ function extractTipState (tip: OpenTip | OpenTipTo225, allAccounts: string[]): T }; } -function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members, onRefresh, onSelect, onlyUntipped, tip }: Props): React.ReactElement | null { +function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members, onSelect, onlyUntipped, tip }: Props): React.ReactElement | null { const { api } = useApi(); const { t } = useTranslation(); const { allAccounts } = useAccounts(); @@ -152,7 +151,6 @@ function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members, className='media--1400' icon='times' label={t('Cancel')} - onSuccess={onRefresh} params={[hash]} tx={(api.tx.tips || api.tx.treasury).retractTip} /> @@ -174,7 +172,6 @@ function Tip ({ bestNumber, className = '', defaultId, hash, isMember, members, accountId={councilId} icon='times' label={t('Close')} - onSuccess={onRefresh} params={[hash]} tx={(api.tx.tips || api.tx.treasury).closeTip} /> diff --git a/packages/page-treasury/src/Tips/TipCreate.tsx b/packages/page-treasury/src/Tips/TipCreate.tsx index f273c1b148..32a2cb6f7d 100644 --- a/packages/page-treasury/src/Tips/TipCreate.tsx +++ b/packages/page-treasury/src/Tips/TipCreate.tsx @@ -11,13 +11,12 @@ import { useTranslation } from '../translate'; interface Props { members: string[]; - refresh: () => void; } const MAX_REASON_LEN = 128; const MIN_REASON_LEN = 5; -function TipCreate ({ members, refresh }: Props): React.ReactElement { +function TipCreate ({ members }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); const [isOpen, toggleOpen] = useToggle(); @@ -90,7 +89,6 @@ function TipCreate ({ members, refresh }: Props): React.ReactElement { isDisabled={!accountId || (isMember && !hasValue) || !hasReason} label={t('Propose tip')} onStart={toggleOpen} - onSuccess={refresh} params={ isMember ? [reason, beneficiary, value] diff --git a/packages/page-treasury/src/Tips/Tips.tsx b/packages/page-treasury/src/Tips/Tips.tsx index 30e2df4ce3..8bc08a3204 100644 --- a/packages/page-treasury/src/Tips/Tips.tsx +++ b/packages/page-treasury/src/Tips/Tips.tsx @@ -20,7 +20,6 @@ interface Props { hashes?: string[] | null; isMember: boolean; members: string[]; - onRefresh: () => void; onSelectTip: (hash: string, isSelected: boolean, value: BN) => void, } @@ -49,7 +48,7 @@ function extractTips (tipsWithHashes?: [[string[]], Option[]], inHashes ); } -function Tips ({ className = '', defaultId, hashes, isMember, members, onRefresh, onSelectTip }: Props): React.ReactElement { +function Tips ({ className = '', defaultId, hashes, isMember, members, onSelectTip }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); const [onlyUntipped, setOnlyUntipped] = useState(false); @@ -95,7 +94,6 @@ function Tips ({ className = '', defaultId, hashes, isMember, members, onRefresh isMember={isMember} key={hash} members={members} - onRefresh={onRefresh} onSelect={onSelectTip} onlyUntipped={onlyUntipped} tip={tip} diff --git a/packages/page-treasury/src/Tips/index.tsx b/packages/page-treasury/src/Tips/index.tsx index c5e2592a5c..8355b56708 100644 --- a/packages/page-treasury/src/Tips/index.tsx +++ b/packages/page-treasury/src/Tips/index.tsx @@ -18,7 +18,6 @@ interface Props { hashes?: string[] | null; isMember: boolean; members: string[]; - trigger: () => void; } interface QuickTipsState { @@ -26,7 +25,7 @@ interface QuickTipsState { quickTx: SubmittableExtrinsic<'promise'> | null; } -function TipsEntry ({ className, hashes, isMember, members, trigger }: Props): React.ReactElement { +function TipsEntry ({ className, hashes, isMember, members }: Props): React.ReactElement { const { t } = useTranslation(); const { allAccounts } = useAccounts(); const { api } = useApi(); @@ -61,10 +60,7 @@ function TipsEntry ({ className, hashes, isMember, members, trigger }: Props): R return (
- +
diff --git a/packages/page-treasury/src/index.tsx b/packages/page-treasury/src/index.tsx index b2b0a2a79e..f532fd5ea3 100644 --- a/packages/page-treasury/src/index.tsx +++ b/packages/page-treasury/src/index.tsx @@ -1,16 +1,18 @@ // Copyright 2017-2021 @polkadot/app-treasury authors & contributors // SPDX-License-Identifier: Apache-2.0 -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useMemo } from 'react'; import { Route, Switch } from 'react-router'; import { HelpOverlay, Tabs } from '@polkadot/react-components'; -import { useApi, useIncrement, useIsMountedRef, useMembers } from '@polkadot/react-hooks'; +import { useApi, useMembers } from '@polkadot/react-hooks'; +import { isFunction } from '@polkadot/util'; import basicMd from './md/basic.md'; import Overview from './Overview'; import Tips from './Tips'; import { useTranslation } from './translate'; +import useTipHashes from './useTipHashes'; export { default as useCounter } from './useCounter'; @@ -18,23 +20,18 @@ interface Props { basePath: string; } +interface TabItem { + count?: number; + isRoot?: boolean; + name: string; + text: string; +} + function TreasuryApp ({ basePath }: Props): React.ReactElement { const { t } = useTranslation(); const { api } = useApi(); - const mountedRef = useIsMountedRef(); - const [tipHashTrigger, triggerTipHashes] = useIncrement(); const { isMember, members } = useMembers(); - const [tipHashes, setTipHashes] = useState(null); - - useEffect((): void => { - if (tipHashTrigger && mountedRef.current) { - (api.query.tips || api.query.treasury).tips.keys().then((keys) => - mountedRef.current && setTipHashes( - keys.map((key) => key.args[0].toHex()) - ) - ).catch(console.error); - } - }, [api, tipHashTrigger, mountedRef]); + const tipHashes = useTipHashes(); const items = useMemo(() => [ { @@ -42,12 +39,12 @@ function TreasuryApp ({ basePath }: Props): React.ReactElement { name: 'overview', text: t('Treasury overview') }, - { + isFunction((api.query.tips || api.query.treasury)?.tips) && { count: tipHashes?.length, name: 'tips', text: t('Tips') } - ], [t, tipHashes]); + ].filter((t: TabItem | false): t is TabItem => !!t), [api, t, tipHashes]); return (
@@ -62,7 +59,6 @@ function TreasuryApp ({ basePath }: Props): React.ReactElement { hashes={tipHashes} isMember={isMember} members={members} - trigger={triggerTipHashes} /> diff --git a/packages/page-treasury/src/useTipHashes.ts b/packages/page-treasury/src/useTipHashes.ts new file mode 100644 index 0000000000..a2ccc7c4f0 --- /dev/null +++ b/packages/page-treasury/src/useTipHashes.ts @@ -0,0 +1,30 @@ +// Copyright 2017-2021 @polkadot/app-treasury authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import { useEffect, useState } from 'react'; + +import { useApi, useEventTrigger } from '@polkadot/react-hooks'; + +export default function useTipHashes (): string[] | undefined { + const { api } = useApi(); + const trigger = useEventTrigger([api.events.tips?.NewTip, api.events.tips?.TipClosed, api.events.tips?.TipRetracted]); + const [state, setState] = useState(); + + useEffect((): void => { + // while we don't trigger on the previous-gen treasury tips, we can still query them + const query = (api.query.tips || api.query.treasury)?.tips; + + if (trigger && query) { + query + .keys() + .then((keys) => setState( + keys.map(({ args: [hash] }) => hash.toHex()) + )) + .catch(console.error); + } else { + setState([]); + } + }, [api, trigger]); + + return state; +}