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:
parent
2de6112e2c
commit
1c44e010c4
@ -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
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
|
||||
10
packages/page-parachains/src/Crowdloan/types.ts
Normal file
10
packages/page-parachains/src/Crowdloan/types.ts
Normal 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;
|
||||
}
|
||||
@ -31,6 +31,7 @@ export interface Campaigns {
|
||||
}
|
||||
|
||||
export interface Campaign extends WinnerData {
|
||||
childKey: string;
|
||||
info: FundInfo;
|
||||
isCapped?: boolean;
|
||||
isEnded?: boolean;
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user