From 6be800d7137ed6a13d9164321c532fe683a25cd5 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Sun, 8 Dec 2019 19:26:57 +0100 Subject: [PATCH] Fix refresh on council proposals --- .../app-treasury/src/Overview/Proposals.tsx | 37 +++-------------- .../app-treasury/src/Overview/Summary.tsx | 28 +++++-------- packages/app-treasury/src/Overview/index.tsx | 40 +++++++++++++++---- packages/react-hooks/src/track/types.ts | 1 + packages/react-hooks/src/track/useStream.tsx | 30 ++++++++++---- 5 files changed, 70 insertions(+), 66 deletions(-) diff --git a/packages/app-treasury/src/Overview/Proposals.tsx b/packages/app-treasury/src/Overview/Proposals.tsx index 358edc297d54..88a0e2f00e85 100644 --- a/packages/app-treasury/src/Overview/Proposals.tsx +++ b/packages/app-treasury/src/Overview/Proposals.tsx @@ -3,45 +3,24 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { ProposalIndex } from '@polkadot/types/interfaces'; import { I18nProps } from '@polkadot/react-components/types'; import BN from 'bn.js'; -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; -import { useApi, useStream } from '@polkadot/react-hooks'; import { Table } from '@polkadot/react-components'; import Proposal from './Proposal'; import translate from '../translate'; interface Props extends I18nProps { + ids?: BN[]; isApprovals?: boolean; } -function ProposalsBase ({ className, isApprovals, t }: Props): React.ReactElement { - const { api } = useApi(); - const approvalIds = useStream(api.query.treasury.approvals, []); - const proposalCount = useStream(api.query.treasury.proposalCount, []); +function ProposalsBase ({ className, ids, isApprovals, t }: Props): React.ReactElement { const history = useHistory(); const [isEmpty, setIsEmpty] = useState(true); - const [proposalIndices, setProposalIndices] = useState([]); - - useEffect((): void => { - let proposalIndices: BN[] = []; - - if (isApprovals) { - proposalIndices = approvalIds || []; - } else if (proposalCount && approvalIds) { - for (let i = 0; i < proposalCount.toNumber(); i++) { - if (!approvalIds.find((index): boolean => index.eqn(i))) { - proposalIndices.push(new BN(i)); - } - } - } - - setProposalIndices(proposalIndices); - }, [isApprovals, proposalCount, approvalIds]); const _onRespond = (): void => { history.push('/council/motions'); @@ -58,7 +37,7 @@ function ProposalsBase ({ className, isApprovals, t }: Props): React.ReactElemen )} - {proposalIndices.map((proposalId): React.ReactNode => ( + {ids?.map((proposalId): React.ReactNode => ( { - return ; -} +export default translate(ProposalsBase); diff --git a/packages/app-treasury/src/Overview/Summary.tsx b/packages/app-treasury/src/Overview/Summary.tsx index 392dfa30f8f2..7361d55119e7 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 { withCalls } from '@polkadot/react-api'; +import { useApi, useStream } from '@polkadot/react-hooks'; import { formatBalance, formatNumber, stringToU8a } from '@polkadot/util'; import translate from '../translate'; @@ -15,13 +15,15 @@ import translate from '../translate'; const TREASURY_ACCOUNT = stringToU8a('modlpy/trsry'.padEnd(32, '\0')); interface Props extends I18nProps { - treasuryBalance?: BN; - approvals?: BN[]; - proposalCount?: BN; - pot?: BN; + approvalCount?: number; + proposalCount?: number; } -function Summary ({ treasuryBalance, approvals, proposalCount, pot, t }: Props): React.ReactElement { +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 value = treasuryBalance?.gtn(0) ? treasuryBalance.toString() : pot?.gtn(0) @@ -35,7 +37,7 @@ function Summary ({ treasuryBalance, approvals, proposalCount, pot, t }: Props): {formatNumber(proposalCount)} - {formatNumber(approvals?.length)} + {formatNumber(approvalCount)}
@@ -49,14 +51,4 @@ function Summary ({ treasuryBalance, approvals, proposalCount, pot, t }: Props): ); } -export default translate( - withCalls( - ['query.balances.freeBalance', { - params: [TREASURY_ACCOUNT], - propName: 'treasuryBalance' - }], - ['query.treasury.approvals', { propName: 'approvals' }], - ['query.treasury.proposalCount', { propName: 'proposalCount' }], - ['query.treasury.pot', { propName: 'pot' }] - )(Summary) -); +export default translate(Summary); diff --git a/packages/app-treasury/src/Overview/index.tsx b/packages/app-treasury/src/Overview/index.tsx index 7b2e194f338d..396ef63d9d2d 100644 --- a/packages/app-treasury/src/Overview/index.tsx +++ b/packages/app-treasury/src/Overview/index.tsx @@ -4,21 +4,45 @@ import { AppProps, BareProps, I18nProps } from '@polkadot/react-components/types'; -import React from 'react'; +import BN from 'bn.js'; +import React, { useEffect, useState } from 'react'; +import { useApi, useStream } from '@polkadot/react-hooks'; import Summary from './Summary'; -import Proposals, { Approvals } from './Proposals'; +import Proposals from './Proposals'; import Propose from './Propose'; interface Props extends AppProps, BareProps, I18nProps {} -export default function Overview (): React.ReactElement { +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 [proposalIds, setProposalIds] = useState([]); + + useEffect((): void => { + if (approvalIds && proposalCount) { + const proposalIds: BN[] = []; + + for (let i = 0; i < proposalCount.toNumber(); i++) { + if (!approvalIds.find((index): boolean => index.eqn(i))) { + proposalIds.push(new BN(i)); + } + } + + setProposalIds(proposalIds); + } + }, [approvalIds, proposalCount]); + return ( - <> - +
+ - - - + + +
); } diff --git a/packages/react-hooks/src/track/types.ts b/packages/react-hooks/src/track/types.ts index c2f3ea21ca4b..caaa650be3a5 100644 --- a/packages/react-hooks/src/track/types.ts +++ b/packages/react-hooks/src/track/types.ts @@ -8,6 +8,7 @@ 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/useStream.tsx b/packages/react-hooks/src/track/useStream.tsx index de299dcd2904..c80f289d4ec3 100644 --- a/packages/react-hooks/src/track/useStream.tsx +++ b/packages/react-hooks/src/track/useStream.tsx @@ -8,7 +8,7 @@ import { Options, Param, Params } from './types'; import { useEffect, useRef, useState } from 'react'; import { isUndefined } from '@polkadot/util'; -import { dummyPromise, extractParams, transformIdentity } from './util'; +import { extractParams, transformIdentity } from './util'; interface TrackFnCallback { (value: Codec): void; @@ -32,15 +32,24 @@ interface TrackFn { // - 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, paramMap = transformIdentity, transform = transformIdentity }: Options = {}): T | undefined { +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 }>({ serialized: null, subscriber: dummyPromise }); + 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 => { - tracker.current.subscriber.then((fn): void => fn()); - tracker.current.subscriber = dummyPromise; + 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(); @@ -49,15 +58,18 @@ export default function useStream (fn: TrackFn | undefined, params: Params, 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 => setValue(transform(value))) - : dummyPromise; + ? fn(...params, (value: any): void => { + _debug(() => ['setValue', JSON.stringify({ value })]); + setValue(transform(value)); + }) + : null; }); }; // initial effect, we need an unsubscription useEffect((): () => void => { return _unsubscribe; - }, [fn, params]); + }, []); // on changes, re-subscribe useEffect((): void => { @@ -65,6 +77,8 @@ export default function useStream (fn: TrackFn | undefined, params: Params, const [serialized, mappedParams] = extractParams(fn, params, paramMap); if (mappedParams && serialized !== tracker.current.serialized) { + _debug(() => ['_createSubscription', fn?.name, serialized]); + tracker.current.serialized = serialized; _subscribe(mappedParams);