Add dissolve for retired funds (#4948)
* Add dissolve for retired funds * Move countdown * Column for retiring countdown * sorting
This commit is contained in:
parent
30da81ca50
commit
2e8ce48c9c
@ -21,7 +21,7 @@ interface Props {
|
||||
value: Campaign;
|
||||
}
|
||||
|
||||
function Fund ({ bestNumber, className, isOngoing, value: { info: { cap, depositor, end, firstSlot, lastSlot, raised, retiring }, isCapped, isEnded, isWinner, paraId } }: Props): React.ReactElement<Props> {
|
||||
function Fund ({ bestNumber, className, 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();
|
||||
@ -35,9 +35,18 @@ function Fund ({ bestNumber, className, isOngoing, value: { info: { cap, deposit
|
||||
[allAccounts, depositor]
|
||||
);
|
||||
|
||||
const blocksLeft = useMemo(
|
||||
() => bestNumber && end.gt(bestNumber) && end.sub(bestNumber),
|
||||
[bestNumber, end]
|
||||
const [blocksLeft, retiringLeft] = useMemo(
|
||||
() => bestNumber
|
||||
? [
|
||||
end.gt(bestNumber)
|
||||
? end.sub(bestNumber)
|
||||
: null,
|
||||
retireEnd?.gt(bestNumber)
|
||||
? retireEnd.sub(bestNumber)
|
||||
: null
|
||||
]
|
||||
: [null, null],
|
||||
[bestNumber, end, retireEnd]
|
||||
);
|
||||
|
||||
// TODO Dissolve should look at retirement and the actual period
|
||||
@ -50,25 +59,35 @@ function Fund ({ bestNumber, className, isOngoing, value: { info: { cap, deposit
|
||||
);
|
||||
|
||||
const canContribute = blocksLeft && !isCapped && !isWinner && retiring.isFalse;
|
||||
const canDissolve = raised.isZero();
|
||||
const canDissolve = raised.isZero() || isRetired;
|
||||
|
||||
return (
|
||||
<tr className={className}>
|
||||
<td className='number'><h1>{formatNumber(paraId)}</h1></td>
|
||||
<td className='badge'><ParaLink id={paraId} /></td>
|
||||
<td>
|
||||
{retiring.isTrue
|
||||
? t<string>('Retiring')
|
||||
: isWinner
|
||||
? t<string>('Winner')
|
||||
: blocksLeft
|
||||
? isCapped
|
||||
? t<string>('Capped')
|
||||
: t<string>('Active')
|
||||
: t<string>('Ended')
|
||||
{isWinner
|
||||
? t<string>('Winner')
|
||||
: isRetired
|
||||
? t<string>('Retired')
|
||||
: retiring.isTrue
|
||||
? t<string>('Retiring')
|
||||
: blocksLeft
|
||||
? isCapped
|
||||
? t<string>('Capped')
|
||||
: t<string>('Active')
|
||||
: t<string>('Ended')
|
||||
}
|
||||
</td>
|
||||
<td className='address'><AddressMini value={depositor} /></td>
|
||||
{!isOngoing && (
|
||||
<td className='all number together'>
|
||||
{retiringLeft && retiring.isTrue && (
|
||||
<BlockToTime value={retiringLeft} />
|
||||
)}
|
||||
{!blocksLeft && <>#{formatNumber(retireEnd)}</>}
|
||||
</td>
|
||||
)}
|
||||
<td className='all number together'>
|
||||
{blocksLeft && (
|
||||
<BlockToTime value={blocksLeft} />
|
||||
@ -85,31 +104,29 @@ function Fund ({ bestNumber, className, isOngoing, value: { info: { cap, deposit
|
||||
/>
|
||||
<div>{percentage}</div>
|
||||
</td>
|
||||
{isOngoing && (
|
||||
<td className='button'>
|
||||
{canDissolve && (
|
||||
<TxButton
|
||||
accountId={depositor}
|
||||
icon='times'
|
||||
isDisabled={!isDepositor}
|
||||
label={
|
||||
isEnded
|
||||
? t<string>('Dissolve')
|
||||
: t<string>('Cancel')
|
||||
}
|
||||
params={[paraId]}
|
||||
tx={api.tx.crowdloan.dissolve}
|
||||
/>
|
||||
)}
|
||||
{canContribute && (
|
||||
<FundContribute
|
||||
cap={cap}
|
||||
paraId={paraId}
|
||||
raised={raised}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
<td className='button'>
|
||||
{canDissolve && (
|
||||
<TxButton
|
||||
accountId={depositor}
|
||||
icon='times'
|
||||
isDisabled={!isDepositor}
|
||||
label={
|
||||
isEnded
|
||||
? t<string>('Dissolve')
|
||||
: t<string>('Cancel')
|
||||
}
|
||||
params={[paraId]}
|
||||
tx={api.tx.crowdloan.dissolve}
|
||||
/>
|
||||
)}
|
||||
{isOngoing && canContribute && (
|
||||
<FundContribute
|
||||
cap={cap}
|
||||
paraId={paraId}
|
||||
raised={raised}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
@ -19,7 +19,10 @@ interface Props {
|
||||
|
||||
function extractLists (value: Campaign[] | null): [Campaign[] | null, Campaign[] | null] {
|
||||
return value
|
||||
? [value.filter(({ isEnded }) => !isEnded), value.filter(({ isEnded }) => isEnded)]
|
||||
? [
|
||||
value.filter(({ isCapped, isEnded, isWinner }) => !(isCapped || isEnded || isWinner)),
|
||||
value.filter(({ isCapped, isEnded, isWinner }) => (isCapped || isEnded || isWinner))
|
||||
]
|
||||
: [null, null];
|
||||
}
|
||||
|
||||
@ -36,9 +39,11 @@ function Funds ({ bestNumber, className, value }: Props): React.ReactElement<Pro
|
||||
|
||||
const headedEndedRef = useRef([
|
||||
[t('completed'), 'start', 4],
|
||||
[t('ended')],
|
||||
[t('retired')],
|
||||
[t('ending')],
|
||||
[t('periods')],
|
||||
[t('raised')]
|
||||
[t('raised')],
|
||||
[]
|
||||
]);
|
||||
|
||||
const [active, ended] = useMemo(
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type BN from 'bn.js';
|
||||
import type { AccountId, BalanceOf, FundInfo, ParaId } from '@polkadot/types/interfaces';
|
||||
|
||||
export interface Campaign {
|
||||
info: FundInfo;
|
||||
isCapped?: boolean;
|
||||
isEnded?: boolean;
|
||||
isRetired?: boolean;
|
||||
isWinner?: boolean;
|
||||
key: string;
|
||||
paraId: ParaId;
|
||||
retireEnd?: BN;
|
||||
}
|
||||
|
||||
export interface LeaseLease {
|
||||
|
||||
@ -45,7 +45,7 @@ function hasLease (paraId: ParaId, leases: Lease[]): boolean {
|
||||
}
|
||||
|
||||
// map into a campaign
|
||||
function updateCampaign (bestNumber: BN, minContribution: BN, data: Campaign, leases: Lease[]): Campaign {
|
||||
function updateCampaign (bestNumber: BN, minContribution: BN, retirementPeriod: BN, data: Campaign, leases: Lease[]): Campaign {
|
||||
if (!data.isEnded && bestNumber.gt(data.info.end)) {
|
||||
data.isEnded = true;
|
||||
}
|
||||
@ -54,6 +54,14 @@ function updateCampaign (bestNumber: BN, minContribution: BN, data: Campaign, le
|
||||
data.isCapped = true;
|
||||
}
|
||||
|
||||
if (!data.retireEnd) {
|
||||
data.retireEnd = data.info.end.add(retirementPeriod);
|
||||
}
|
||||
|
||||
if (!data.isRetired && bestNumber.gt(data.retireEnd)) {
|
||||
data.isRetired = true;
|
||||
}
|
||||
|
||||
if (!data.isWinner && hasLease(data.paraId, leases)) {
|
||||
data.isWinner = true;
|
||||
}
|
||||
@ -61,14 +69,15 @@ function updateCampaign (bestNumber: BN, minContribution: BN, data: Campaign, le
|
||||
return data;
|
||||
}
|
||||
|
||||
function isFundUpdated (bestNumber: BlockNumber, minContribution: BN, { info: { cap, end, raised }, isCapped, isEnded, isWinner, paraId }: Campaign, leases: Lease[]): boolean {
|
||||
function isFundUpdated (bestNumber: BlockNumber, minContribution: BN, retirementPeriod: BN, { info: { cap, end, raised }, isCapped, isEnded, isRetired, isWinner, paraId }: Campaign, leases: Lease[]): boolean {
|
||||
return (!isEnded && bestNumber.gt(end)) ||
|
||||
(!isCapped && cap.sub(raised).lt(minContribution)) ||
|
||||
(!isRetired && bestNumber.gt(end.add(retirementPeriod))) ||
|
||||
(!isWinner && hasLease(paraId, leases));
|
||||
}
|
||||
|
||||
// compare the current campaigns against the previous, manually adding ending and calculating the new totals
|
||||
function createResult (bestNumber: BlockNumber, minContribution: BN, funds: Campaign[], leases: Lease[], prev: Result): Result {
|
||||
function createResult (bestNumber: BlockNumber, minContribution: BN, retirementPeriod: BN, funds: Campaign[], leases: Lease[], prev: Result): Result {
|
||||
const [activeRaised, activeCap, totalRaised, totalCap] = funds.reduce(([ar, ac, tr, tc], { info: { cap, end, raised } }) => [
|
||||
bestNumber.gt(end) ? ar : ar.iadd(raised),
|
||||
bestNumber.gt(end) ? ac : ac.iadd(cap),
|
||||
@ -83,7 +92,7 @@ function createResult (bestNumber: BlockNumber, minContribution: BN, funds: Camp
|
||||
!prev.funds || prev.funds.length !== funds.length ||
|
||||
hasNewActiveCap || hasNewActiveRaised ||
|
||||
hasNewTotalCap || hasNewTotalRaised ||
|
||||
funds.some((c) => isFundUpdated(bestNumber, minContribution, c, leases)) ||
|
||||
funds.some((c) => isFundUpdated(bestNumber, minContribution, retirementPeriod, c, leases)) ||
|
||||
true;
|
||||
|
||||
if (!hasChanged) {
|
||||
@ -98,21 +107,25 @@ function createResult (bestNumber: BlockNumber, minContribution: BN, funds: Camp
|
||||
? activeRaised
|
||||
: prev.activeRaised,
|
||||
funds: funds
|
||||
.map((c) => updateCampaign(bestNumber, minContribution, c, leases))
|
||||
.map((c) => updateCampaign(bestNumber, minContribution, retirementPeriod, c, leases))
|
||||
.sort((a, b) =>
|
||||
a.isWinner !== b.isWinner
|
||||
? a.isWinner
|
||||
? 1
|
||||
: -1
|
||||
? -1
|
||||
: 1
|
||||
: a.isCapped !== b.isCapped
|
||||
? a.isCapped
|
||||
? 1
|
||||
: -1
|
||||
: a.isEnded !== b.isEnded
|
||||
? a.isEnded
|
||||
? -1
|
||||
: 1
|
||||
: a.isRetired !== b.isRetired
|
||||
? a.isRetired
|
||||
? 1
|
||||
: -1
|
||||
: 0
|
||||
: a.isEnded !== b.isEnded
|
||||
? a.isEnded
|
||||
? 1
|
||||
: -1
|
||||
: 0
|
||||
),
|
||||
totalCap: hasNewTotalCap
|
||||
? totalCap
|
||||
@ -168,7 +181,7 @@ export default function useFunds (): Result {
|
||||
// here we manually add the actual ending status and calculate the totals
|
||||
useEffect((): void => {
|
||||
bestNumber && campaigns && leases && setResult((prev) =>
|
||||
createResult(bestNumber, api.consts.crowdloan.minContribution as BlockNumber, campaigns, leases, prev)
|
||||
createResult(bestNumber, api.consts.crowdloan.minContribution as BlockNumber, api.consts.crowdloan.retirementPeriod as BlockNumber, campaigns, leases, prev)
|
||||
);
|
||||
}, [api, bestNumber, campaigns, leases]);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user