Split parathreads tab (#4997)
* Split parathreads tab * Keep threads warm * Remove extra ?. * Type for id + leases
This commit is contained in:
parent
4c95a929b4
commit
31448157eb
@ -91,7 +91,7 @@ function Bid ({ auctionInfo, className, lastWinners, ownedIds }: Props): React.R
|
||||
/>
|
||||
<Modal.Columns hint={t<string>('The first and last lease period for this bid. The last lease period should be after the first and a maximum of 3 more than the first.')}>
|
||||
<Dropdown
|
||||
label={t<string>('bid period range (first period - last period)')}
|
||||
label={t<string>('bid period range (first lease - last lease)')}
|
||||
onChange={setRange}
|
||||
options={rangeOpts}
|
||||
value={range}
|
||||
@ -99,7 +99,7 @@ function Bid ({ auctionInfo, className, lastWinners, ownedIds }: Props): React.R
|
||||
</Modal.Columns>
|
||||
<Modal.Columns hint={
|
||||
<>
|
||||
<p>{t<string>('The amount to to bid for this parachain period range.')}</p>
|
||||
<p>{t<string>('The amount to to bid for this parachain lease period range.')}</p>
|
||||
<p>{t<string>('The bid should be more than the current range winner to be accepted and influence the auction outcome.')}</p>
|
||||
</>
|
||||
}>
|
||||
|
||||
@ -107,7 +107,7 @@ function Refund ({ allAccounts, className, myAccounts, paraId }: Props): React.R
|
||||
<Button
|
||||
icon='minus'
|
||||
isDisabled={!hasAccounts}
|
||||
label={t<string>('Withdraw')}
|
||||
label={t<string>('Refund')}
|
||||
onClick={toggleOpen}
|
||||
/>
|
||||
{isOpen && (
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ParaLifecycle } from '@polkadot/types/interfaces';
|
||||
import type { QueuedAction } from './types';
|
||||
import type { QueuedAction } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
import type { Option, Vec } from '@polkadot/types';
|
||||
import type { AccountId, BalanceOf, BlockNumber, CandidatePendingAvailability, HeadData, Header, HrmpChannel, HrmpChannelId, ParaId, ParaInfo, ParaLifecycle } from '@polkadot/types/interfaces';
|
||||
import type { Codec, ITuple } from '@polkadot/types/types';
|
||||
import type { LeasePeriod } from '../types';
|
||||
import type { EventMapInfo, QueuedAction, ValidatorInfo } from './types';
|
||||
import type { LeasePeriod, QueuedAction } from '../types';
|
||||
import type { EventMapInfo, ValidatorInfo } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
@ -5,8 +5,8 @@ import type { ApiPromise } from '@polkadot/api';
|
||||
import type { SignedBlockExtended } from '@polkadot/api-derive/types';
|
||||
import type { AccountId, CandidateReceipt, Event, ParaId, ParaValidatorIndex } from '@polkadot/types/interfaces';
|
||||
import type { IEvent } from '@polkadot/types/types';
|
||||
import type { LeasePeriod, ScheduledProposals } from '../types';
|
||||
import type { EventMapInfo, QueuedAction, ValidatorInfo } from './types';
|
||||
import type { LeasePeriod, QueuedAction, ScheduledProposals } from '../types';
|
||||
import type { EventMapInfo, ValidatorInfo } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
@ -15,8 +15,8 @@ import { Table } from '@polkadot/react-components';
|
||||
import { useApi, useBestNumber, useCall, useCallMulti } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import useHrmp from '../useHrmp';
|
||||
import Parachain from './Parachain';
|
||||
import useHrmp from './useHrmp';
|
||||
|
||||
interface Props {
|
||||
actionsQueue: QueuedAction[];
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ParaId } from '@polkadot/types/interfaces';
|
||||
import type { LeasePeriod } from '../types';
|
||||
import type { QueuedAction } from './types';
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
|
||||
import { Table } from '@polkadot/react-components';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Upcoming from './Upcoming';
|
||||
|
||||
interface Props {
|
||||
actionsQueue: QueuedAction[];
|
||||
ids?: ParaId[];
|
||||
leasePeriod?: LeasePeriod;
|
||||
}
|
||||
|
||||
function Upcomings ({ actionsQueue, ids, leasePeriod }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('parathreads'), 'start', 3],
|
||||
[t('head'), 'start'],
|
||||
[t('lifecycle'), 'start'],
|
||||
[t('leases')]
|
||||
]);
|
||||
|
||||
return (
|
||||
<Table
|
||||
empty={leasePeriod && ids && t<string>('There are no upcoming parachains')}
|
||||
header={headerRef.current}
|
||||
>
|
||||
{leasePeriod && ids?.map((id): React.ReactNode => (
|
||||
<Upcoming
|
||||
id={id}
|
||||
key={id.toString()}
|
||||
leasePeriod={leasePeriod}
|
||||
nextAction={actionsQueue.find(({ paraIds }) =>
|
||||
paraIds.some((p) => p.eq(id))
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Upcomings);
|
||||
@ -2,55 +2,38 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ParaId } from '@polkadot/types/interfaces';
|
||||
import type { LeasePeriod, Proposals } from '../types';
|
||||
import type { LeasePeriod, Proposals, QueuedAction } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
import Actions from './Actions';
|
||||
import Parachains from './Parachains';
|
||||
import Summary from './Summary';
|
||||
import Upcomings from './Upcomings';
|
||||
import useActionsQueue from './useActionsQueue';
|
||||
import useUpcomingIds from './useUpcomingIds';
|
||||
|
||||
interface Props {
|
||||
actionsQueue: QueuedAction[];
|
||||
className?: string;
|
||||
leasePeriod?: LeasePeriod;
|
||||
paraIds?: ParaId[];
|
||||
proposals?: Proposals;
|
||||
threadIds?: ParaId[];
|
||||
upcomingIds?: ParaId[];
|
||||
}
|
||||
|
||||
function Overview ({ className, leasePeriod, proposals }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const paraIds = useCall<ParaId[]>(api.query.paras?.parachains);
|
||||
const actionsQueue = useActionsQueue();
|
||||
const upcomingIds = useUpcomingIds();
|
||||
|
||||
function Overview ({ actionsQueue, className, leasePeriod, paraIds, proposals, threadIds }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<div className={className}>
|
||||
<Summary
|
||||
leasePeriod={leasePeriod}
|
||||
parachainCount={paraIds?.length}
|
||||
proposalCount={proposals?.proposalIds.length}
|
||||
upcomingCount={upcomingIds?.length}
|
||||
upcomingCount={threadIds?.length}
|
||||
/>
|
||||
<Parachains
|
||||
actionsQueue={actionsQueue}
|
||||
ids={paraIds}
|
||||
leasePeriod={leasePeriod}
|
||||
scheduled={proposals?.scheduled}
|
||||
/>
|
||||
<Actions />
|
||||
{api.query.paras && (
|
||||
<>
|
||||
<Parachains
|
||||
actionsQueue={actionsQueue}
|
||||
ids={paraIds}
|
||||
leasePeriod={leasePeriod}
|
||||
scheduled={proposals?.scheduled}
|
||||
/>
|
||||
<Upcomings
|
||||
actionsQueue={actionsQueue}
|
||||
ids={upcomingIds}
|
||||
leasePeriod={leasePeriod}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -2,20 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type BN from 'bn.js';
|
||||
import type { AccountId, BalanceOf, HrmpChannel, HrmpChannelId, ParaId, ParaValidatorIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
export type ChannelMap = Record<string, [HrmpChannelId, HrmpChannel][]>;
|
||||
|
||||
export interface LeaseInfo {
|
||||
accountId: AccountId;
|
||||
balance: BalanceOf;
|
||||
period: number;
|
||||
}
|
||||
|
||||
export interface QueuedAction {
|
||||
paraIds: ParaId[];
|
||||
sessionIndex: BN;
|
||||
}
|
||||
import type { AccountId, ParaValidatorIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
export interface EventMapInfo {
|
||||
blockHash: string;
|
||||
|
||||
@ -1,32 +1,30 @@
|
||||
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Option, Vec } from '@polkadot/types';
|
||||
import type { AccountId, BalanceOf, HeadData, ParaGenesisArgs, ParaId, ParaInfo, ParaLifecycle } from '@polkadot/types/interfaces';
|
||||
import type { ITuple } from '@polkadot/types/types';
|
||||
import type { LeasePeriod } from '../types';
|
||||
import type { LeaseInfo, QueuedAction } from './types';
|
||||
import type { Option } from '@polkadot/types';
|
||||
import type { AccountId, HeadData, ParaGenesisArgs, ParaId, ParaInfo, ParaLifecycle } from '@polkadot/types/interfaces';
|
||||
import type { LeaseInfo, LeasePeriod, QueuedAction } from '../types';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { AddressSmall, ParaLink } from '@polkadot/react-components';
|
||||
import { useApi, useCallMulti } from '@polkadot/react-hooks';
|
||||
import { AddressSmall, ParaLink, TxButton } from '@polkadot/react-components';
|
||||
import { useAccounts, useApi, useCallMulti } from '@polkadot/react-hooks';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
import Lifecycle from '../Overview/Lifecycle';
|
||||
import Periods from '../Overview/Periods';
|
||||
import { useTranslation } from '../translate';
|
||||
import { sliceHex } from '../util';
|
||||
import Lifecycle from './Lifecycle';
|
||||
import Periods from './Periods';
|
||||
|
||||
interface Props {
|
||||
id: ParaId;
|
||||
leasePeriod: LeasePeriod;
|
||||
leases: LeaseInfo[];
|
||||
nextAction?: QueuedAction;
|
||||
}
|
||||
|
||||
interface MultiState {
|
||||
headHex: string | null;
|
||||
leases: LeaseInfo[] | null;
|
||||
lifecycle: ParaLifecycle | null;
|
||||
manager: AccountId | null;
|
||||
}
|
||||
@ -34,33 +32,15 @@ interface MultiState {
|
||||
const optMulti = {
|
||||
defaultValue: {
|
||||
headHex: null,
|
||||
leases: null,
|
||||
lifecycle: null,
|
||||
manager: null
|
||||
},
|
||||
transform: ([optHead, optGenesis, optLifecycle, optInfo, leases]: [Option<HeadData>, Option<ParaGenesisArgs>, Option<ParaLifecycle>, Option<ParaInfo>, Vec<Option<ITuple<[AccountId, BalanceOf]>>>]): MultiState => ({
|
||||
transform: ([optHead, optGenesis, optLifecycle, optInfo]: [Option<HeadData>, Option<ParaGenesisArgs>, Option<ParaLifecycle>, Option<ParaInfo>]): MultiState => ({
|
||||
headHex: optHead.isSome
|
||||
? sliceHex(optHead.unwrap())
|
||||
: optGenesis.isSome
|
||||
? sliceHex(optGenesis.unwrap().genesisHead)
|
||||
: null,
|
||||
leases: leases
|
||||
? leases
|
||||
.map((optLease, period): LeaseInfo | null => {
|
||||
if (optLease.isNone) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [accountId, balance] = optLease.unwrap();
|
||||
|
||||
return {
|
||||
accountId,
|
||||
balance,
|
||||
period
|
||||
};
|
||||
})
|
||||
.filter((item): item is LeaseInfo => !!item)
|
||||
: [],
|
||||
lifecycle: optLifecycle.unwrapOr(null),
|
||||
manager: optInfo.isSome
|
||||
? optInfo.unwrap().manager
|
||||
@ -68,15 +48,15 @@ const optMulti = {
|
||||
})
|
||||
};
|
||||
|
||||
function Upcoming ({ id, leasePeriod, nextAction }: Props): React.ReactElement<Props> {
|
||||
function Upcoming ({ id, leasePeriod, leases, nextAction }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { headHex, leases, lifecycle, manager } = useCallMulti<MultiState>([
|
||||
const { isAccount } = useAccounts();
|
||||
const { headHex, lifecycle, manager } = useCallMulti<MultiState>([
|
||||
[api.query.paras.heads, id],
|
||||
[api.query.paras.upcomingParasGenesis, id],
|
||||
[api.query.paras.paraLifecycles, id],
|
||||
[api.query.registrar?.paras, id],
|
||||
[api.query.slots?.leases, id]
|
||||
[api.query.registrar?.paras, id]
|
||||
], optMulti);
|
||||
|
||||
const periods = useMemo(
|
||||
@ -85,6 +65,8 @@ function Upcoming ({ id, leasePeriod, nextAction }: Props): React.ReactElement<P
|
||||
[leasePeriod?.currentPeriod, leases]
|
||||
);
|
||||
|
||||
const isManager = isAccount(manager?.toString());
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td className='number'><h1>{formatNumber(id)}</h1></td>
|
||||
@ -110,6 +92,16 @@ function Upcoming ({ id, leasePeriod, nextAction }: Props): React.ReactElement<P
|
||||
: t('None')
|
||||
)}
|
||||
</td>
|
||||
<td className='button'>
|
||||
<TxButton
|
||||
accountId={manager}
|
||||
icon='times'
|
||||
isDisabled={!isManager}
|
||||
label={t<string>('Deregister')}
|
||||
params={[id]}
|
||||
tx={api.tx.registrar.deregister}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
100
packages/page-parachains/src/Parathreads/index.tsx
Normal file
100
packages/page-parachains/src/Parathreads/index.tsx
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Option } from '@polkadot/types';
|
||||
import type { AccountId, BalanceOf, ParaId } from '@polkadot/types/interfaces';
|
||||
import type { ITuple } from '@polkadot/types/types';
|
||||
import type { LeaseInfo, LeasePeriod, QueuedAction } from '../types';
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
|
||||
import { Table } from '@polkadot/react-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
import Actions from './Actions';
|
||||
import Parathread from './Parathread';
|
||||
|
||||
interface Props {
|
||||
actionsQueue: QueuedAction[];
|
||||
className?: string;
|
||||
ids?: ParaId[];
|
||||
leasePeriod?: LeasePeriod;
|
||||
}
|
||||
|
||||
type ParaMap = [ParaId, LeaseInfo[]][];
|
||||
|
||||
const optLeases = {
|
||||
transform: ([[paraIds], leases]: [[ParaId[]], Option<ITuple<[AccountId, BalanceOf]>>[][]]): ParaMap =>
|
||||
paraIds
|
||||
.reduce((all: ParaMap, id, index): ParaMap => {
|
||||
all.push([
|
||||
id,
|
||||
leases[index]
|
||||
.map((optLease, period): LeaseInfo | null => {
|
||||
if (optLease.isNone) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [accountId, balance] = optLease.unwrap();
|
||||
|
||||
return {
|
||||
accountId,
|
||||
balance,
|
||||
period
|
||||
};
|
||||
})
|
||||
.filter((item): item is LeaseInfo => !!item)
|
||||
]);
|
||||
|
||||
return all;
|
||||
}, [])
|
||||
.sort(([aId, aLeases], [bId, bLeases]) =>
|
||||
aLeases.length && bLeases.length
|
||||
? (aLeases[0].period - bLeases[0].period) || aId.cmp(bId)
|
||||
: aLeases.length
|
||||
? -1
|
||||
: bLeases.length
|
||||
? 1
|
||||
: aId.cmp(bId)
|
||||
),
|
||||
withParamsTransform: true
|
||||
};
|
||||
|
||||
function Parathreads ({ actionsQueue, className, ids, leasePeriod }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const leaseMap = useCall<ParaMap>(ids && api.query.slots.leases.multi, [ids], optLeases);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('parathreads'), 'start', 3],
|
||||
[t('head'), 'start'],
|
||||
[t('lifecycle'), 'start'],
|
||||
[t('leases')],
|
||||
[]
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<Actions />
|
||||
<Table
|
||||
empty={leasePeriod && ids && (ids.length === 0 || leaseMap) && t<string>('There are no available parathreads')}
|
||||
header={headerRef.current}
|
||||
>
|
||||
{leasePeriod && leaseMap?.map(([id, leases]): React.ReactNode => (
|
||||
<Parathread
|
||||
id={id}
|
||||
key={id.toString()}
|
||||
leasePeriod={leasePeriod}
|
||||
leases={leases}
|
||||
nextAction={actionsQueue.find(({ paraIds }) =>
|
||||
paraIds.some((p) => p.eq(id))
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</Table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Parathreads);
|
||||
@ -1,24 +1,29 @@
|
||||
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ParaId } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Tabs } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
import Auctions from './Auctions';
|
||||
import Crowdloan from './Crowdloan';
|
||||
import Overview from './Overview';
|
||||
import Parathreads from './Parathreads';
|
||||
import Proposals from './Proposals';
|
||||
import { useTranslation } from './translate';
|
||||
import useActionsQueue from './useActionsQueue';
|
||||
import useAuctionInfo from './useAuctionInfo';
|
||||
import useFunds from './useFunds';
|
||||
import useLeasePeriod from './useLeasePeriod';
|
||||
import useOwnedIds from './useOwnedIds';
|
||||
import useProposals from './useProposals';
|
||||
import useUpcomingIds from './useUpcomingIds';
|
||||
import useWinningData from './useWinningData';
|
||||
|
||||
interface Props {
|
||||
@ -36,6 +41,9 @@ function ParachainsApp ({ basePath, className }: Props): React.ReactElement<Prop
|
||||
const ownedIds = useOwnedIds();
|
||||
const winningData = useWinningData(auctionInfo);
|
||||
const proposals = useProposals();
|
||||
const paraIds = useCall<ParaId[]>(api.query.paras?.parachains);
|
||||
const actionsQueue = useActionsQueue();
|
||||
const upcomingIds = useUpcomingIds();
|
||||
|
||||
const items = useRef([
|
||||
{
|
||||
@ -43,6 +51,10 @@ function ParachainsApp ({ basePath, className }: Props): React.ReactElement<Prop
|
||||
name: 'overview',
|
||||
text: t<string>('Overview')
|
||||
},
|
||||
{
|
||||
name: 'parathreads',
|
||||
text: t<string>('Parathreads')
|
||||
},
|
||||
api.query.proposeParachain && {
|
||||
name: 'proposals',
|
||||
text: t<string>('Proposals')
|
||||
@ -85,9 +97,18 @@ function ParachainsApp ({ basePath, className }: Props): React.ReactElement<Prop
|
||||
</Route>
|
||||
</Switch>
|
||||
<Overview
|
||||
className={basePath === pathname ? '' : 'parachains--hidden'}
|
||||
actionsQueue={actionsQueue}
|
||||
className={pathname === basePath ? '' : 'parachains--hidden'}
|
||||
leasePeriod={leasePeriod}
|
||||
paraIds={paraIds}
|
||||
proposals={proposals}
|
||||
threadIds={upcomingIds}
|
||||
/>
|
||||
<Parathreads
|
||||
actionsQueue={actionsQueue}
|
||||
className={pathname === `${basePath}/parathreads` ? '' : 'parachains--hidden'}
|
||||
ids={upcomingIds}
|
||||
leasePeriod={leasePeriod}
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
|
||||
@ -2,7 +2,25 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type BN from 'bn.js';
|
||||
import type { AuctionIndex, BlockNumber, FundInfo, LeasePeriodOf, ParachainProposal, ParaId, ParaInfo, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import type { AccountId, AuctionIndex, BalanceOf, BlockNumber, FundInfo, HrmpChannel, HrmpChannelId, LeasePeriodOf, ParachainProposal, ParaId, ParaInfo, SessionIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
export type ChannelMap = Record<string, [HrmpChannelId, HrmpChannel][]>;
|
||||
|
||||
export interface AllChannels {
|
||||
dst: ChannelMap;
|
||||
src: ChannelMap;
|
||||
}
|
||||
|
||||
export interface LeaseInfo {
|
||||
accountId: AccountId;
|
||||
balance: BalanceOf;
|
||||
period: number;
|
||||
}
|
||||
|
||||
export interface QueuedAction {
|
||||
paraIds: ParaId[];
|
||||
sessionIndex: BN;
|
||||
}
|
||||
|
||||
export interface AuctionInfo {
|
||||
endBlock: BlockNumber | null;
|
||||
|
||||
@ -169,7 +169,7 @@ export default function useFunds (): Campaigns {
|
||||
const [paraIds, setParaIds] = useState<ParaId[]>([]);
|
||||
const trigger = useEventTrigger([api.events.crowdloan?.Created]);
|
||||
const campaigns = useCall<Campaign[]>(api.query.crowdloan?.funds.multi, [paraIds], optFundMulti);
|
||||
const leases = useCall<ParaId[]>(api.query.slots?.leases.multi, [paraIds], optLeaseMulti);
|
||||
const leases = useCall<ParaId[]>(api.query.slots.leases.multi, [paraIds], optLeaseMulti);
|
||||
const [result, setResult] = useState<Campaigns>(EMPTY);
|
||||
|
||||
// on event triggers, update the available paraIds
|
||||
|
||||
@ -3,24 +3,19 @@
|
||||
|
||||
import type { Option } from '@polkadot/types';
|
||||
import type { HrmpChannel, HrmpChannelId } from '@polkadot/types/interfaces';
|
||||
import type { ChannelMap } from './types';
|
||||
import type { AllChannels } from './types';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useApi, useCall, useEventTrigger } from '@polkadot/react-hooks';
|
||||
|
||||
interface Result {
|
||||
dst: ChannelMap;
|
||||
src: ChannelMap;
|
||||
}
|
||||
|
||||
const optChannels = {
|
||||
transform: ([[channelIds], channels]: [[HrmpChannelId[]], Option<HrmpChannel>[]]): Result =>
|
||||
transform: ([[channelIds], channels]: [[HrmpChannelId[]], Option<HrmpChannel>[]]): AllChannels =>
|
||||
channelIds
|
||||
.map((id, index): [HrmpChannelId, Option<HrmpChannel>] => [id, channels[index]])
|
||||
.filter(([, opt]) => opt.isSome)
|
||||
.map(([id, opt]): [HrmpChannelId, HrmpChannel] => [id, opt.unwrap()])
|
||||
.reduce((all: Result, [id, channel]): Result => {
|
||||
.reduce((all: AllChannels, [id, channel]): AllChannels => {
|
||||
all.dst[id.receiver.toString()] ||= [];
|
||||
all.src[id.sender.toString()] ||= [];
|
||||
|
||||
@ -32,11 +27,11 @@ const optChannels = {
|
||||
withParamsTransform: true
|
||||
};
|
||||
|
||||
export default function useHrmp (): Result | undefined {
|
||||
export default function useHrmp (): AllChannels | undefined {
|
||||
const { api } = useApi();
|
||||
const [channelIds, setChannelIds] = useState<HrmpChannelId[] | null>(null);
|
||||
const trigger = useEventTrigger([api.events.hrmp?.OpenChannelAccepted, api.events.hrmp?.ChannelClosed]);
|
||||
const allChannels = useCall<Result>(channelIds && api.query.hrmp?.hrmpChannels.multi, [channelIds], optChannels);
|
||||
const allChannels = useCall<AllChannels>(channelIds && api.query.hrmp?.hrmpChannels.multi, [channelIds], optChannels);
|
||||
|
||||
useEffect((): void => {
|
||||
trigger &&
|
||||
@ -13,7 +13,7 @@ export default function useLeasePeriod (): LeasePeriod | undefined {
|
||||
const bestNumber = useBestNumber();
|
||||
|
||||
return useMemo((): LeasePeriod | undefined => {
|
||||
if (!api.consts.slots?.leasePeriod || !bestNumber) {
|
||||
if (!api.consts.slots.leasePeriod || !bestNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ import { useIsMountedRef } from './useIsMountedRef';
|
||||
interface UseAccounts {
|
||||
allAccounts: string[];
|
||||
hasAccounts: boolean;
|
||||
isAccount: (address: string) => boolean;
|
||||
isAccount: (address?: string | null) => boolean;
|
||||
}
|
||||
|
||||
const EMPTY: UseAccounts = { allAccounts: [], hasAccounts: false, isAccount: () => false };
|
||||
@ -24,7 +24,7 @@ export function useAccounts (): UseAccounts {
|
||||
if (mountedRef.current) {
|
||||
const allAccounts = accounts ? Object.keys(accounts) : [];
|
||||
const hasAccounts = allAccounts.length !== 0;
|
||||
const isAccount = (address: string) => allAccounts.includes(address);
|
||||
const isAccount = (address?: string | null) => !!address && allAccounts.includes(address);
|
||||
|
||||
setState({ allAccounts, hasAccounts, isAccount });
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user