Show number of contributions (#4954)

* No contributions to past crowdloans

* Past status to completed

* Remove extra var

* Show number of contributions

* naming
This commit is contained in:
Jaco Greeff 2021-03-26 22:33:11 +01:00 committed by GitHub
parent 2de6112e2c
commit 1c44e010c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 5 deletions

View File

@ -3,6 +3,7 @@
import type BN from 'bn.js';
import type { Campaign } from '../types';
import type { Contributed } from './types';
import React, { useMemo } from 'react';
@ -17,11 +18,12 @@ import FundContribute from './FundContribute';
interface Props {
bestNumber?: BN;
className?: string;
contributed?: Contributed;
isOngoing?: boolean;
value: Campaign;
}
function Fund ({ bestNumber, className, isOngoing, value: { info: { cap, depositor, end, firstSlot, lastSlot, raised, retiring }, isCapped, isEnded, isRetired, isWinner, paraId, retireEnd } }: Props): React.ReactElement<Props> {
function Fund ({ bestNumber, className, contributed, isOngoing, value: { info: { cap, depositor, end, firstSlot, lastSlot, raised, retiring }, isCapped, isEnded, isRetired, isWinner, paraId, retireEnd } }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const { allAccounts } = useAccounts();
@ -106,6 +108,11 @@ function Fund ({ bestNumber, className, isOngoing, value: { info: { cap, deposit
/>
<div>{percentage}</div>
</td>
<td className='number'>
{contributed && (
formatNumber(contributed.count)
)}
</td>
<td className='button'>
{canDissolve && (
<TxButton

View File

@ -3,10 +3,12 @@
import type BN from 'bn.js';
import type { Campaign, LeasePeriod } from '../types';
import type { Contributed } from './types';
import React, { useMemo, useRef } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Table } from '@polkadot/react-components';
import { useApi, useEventTrigger } from '@polkadot/react-hooks';
import { useTranslation } from '../translate';
import Fund from './Fund';
@ -31,12 +33,16 @@ function extractLists (value: Campaign[] | null, leasePeriod?: LeasePeriod): [Ca
function Funds ({ bestNumber, className, leasePeriod, value }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const trigger = useEventTrigger([api.events.crowdloan.Contributed]);
const [contributors, setContributors] = useState<Contributed[]>([]);
const headerActiveRef = useRef([
[t('ongoing'), 'start', 4],
[t('ending')],
[t('periods')],
[t('raised')],
[t('count')],
[]
]);
@ -46,9 +52,29 @@ function Funds ({ bestNumber, className, leasePeriod, value }: Props): React.Rea
[t('ending')],
[t('periods')],
[t('raised')],
[t('count')],
[]
]);
useEffect((): void => {
trigger && value &&
Promise
.all(value.map(({ childKey }) => api.rpc.childstate.getKeys(childKey, '0x')))
.then((all) => setContributors(
all.map((keys, index) => ({
accountIds: [], // keys.map((a) => encodeAddress(a)),
count: keys.length,
trieIndex: value[index].info.trieIndex
}))
))
.catch(console.error);
}, [api, trigger, value]);
const findContributions = useCallback(
(trieIndex: BN) => contributors.find((c) => trieIndex.eq(c.trieIndex)),
[contributors]
);
const [active, ended] = useMemo(
() => extractLists(value, leasePeriod),
[leasePeriod, value]
@ -64,6 +90,7 @@ function Funds ({ bestNumber, className, leasePeriod, value }: Props): React.Rea
{active?.map((fund) => (
<Fund
bestNumber={bestNumber}
contributed={findContributions(fund.info.trieIndex)}
isOngoing
key={fund.accountId}
value={fund}
@ -78,6 +105,7 @@ function Funds ({ bestNumber, className, leasePeriod, value }: Props): React.Rea
{ended?.map((fund) => (
<Fund
bestNumber={bestNumber}
contributed={findContributions(fund.info.trieIndex)}
key={fund.accountId}
value={fund}
/>

View File

@ -0,0 +1,10 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { TrieIndex } from '@polkadot/types/interfaces';
export interface Contributed {
accountIds: string[];
count: number;
trieIndex: TrieIndex;
}

View File

@ -31,6 +31,7 @@ export interface Campaigns {
}
export interface Campaign extends WinnerData {
childKey: string;
info: FundInfo;
isCapped?: boolean;
isEnded?: boolean;

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type { Option } from '@polkadot/types';
import type { AccountId, BalanceOf, BlockNumber, FundInfo, ParaId } from '@polkadot/types/interfaces';
import type { AccountId, BalanceOf, BlockNumber, FundInfo, ParaId, TrieIndex } from '@polkadot/types/interfaces';
import type { ITuple } from '@polkadot/types/types';
import type { Campaign, Campaigns } from './types';
@ -10,8 +10,8 @@ import BN from 'bn.js';
import { useEffect, useState } from 'react';
import { useApi, useBestNumber, useCall, useEventTrigger } from '@polkadot/react-hooks';
import { BN_ZERO, u8aConcat } from '@polkadot/util';
import { encodeAddress } from '@polkadot/util-crypto';
import { BN_ZERO, u8aConcat, u8aToHex } from '@polkadot/util';
import { blake2AsU8a, encodeAddress } from '@polkadot/util-crypto';
import { CROWD_PREFIX } from './constants';
@ -37,6 +37,17 @@ function hasLease (paraId: ParaId, leased: ParaId[]): boolean {
return leased.some((l) => l.eq(paraId));
}
function createChildKey (trieIndex: TrieIndex): string {
return u8aToHex(
u8aConcat(
':child_storage:default:',
blake2AsU8a(
u8aConcat('crowdloan', trieIndex.toU8a())
)
)
);
}
// map into a campaign
function updateFund (bestNumber: BN, minContribution: BN, retirementPeriod: BN, data: Campaign, leased: ParaId[]): Campaign {
data.isCapped = data.info.cap.sub(data.info.raised).lt(minContribution);
@ -123,6 +134,7 @@ const optFundMulti = {
.filter((v): v is [ParaId, FundInfo] => !!v[1])
.map(([paraId, info]): Campaign => ({
accountId: encodeAddress(createAddress(paraId)),
childKey: createChildKey(info.trieIndex),
firstSlot: info.firstSlot,
info,
isCrowdloan: true,