Display homepage links for crowdloans (#5521)

* Display homepage links for crowdloans

* Update packages/apps-config/src/endpoints/productionRelayKusama.ts
This commit is contained in:
Jaco 2021-06-09 12:15:14 +03:00 committed by GitHub
parent 7fcbeb1e9c
commit a2da532cb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 128 additions and 80 deletions

View File

@ -45,6 +45,7 @@ export function createKusama (t: TFunction): EndpointOption {
// NOTE: Added alphabetical based on chain name
{
info: 'bifrost',
homepage: 'https://thebifrost.io/',
isUnreachable: true,
paraId: 2001,
text: t('rpc.kusama.bifrost', 'Bifrost', { ns: 'apps-config' }),
@ -54,6 +55,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'shadow',
homepage: 'https://crust.network/',
isUnreachable: true,
paraId: 2012,
text: t('rpc.kusama.shadow', 'Crust Shadow', { ns: 'apps-config' }),
@ -63,6 +65,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'crab',
homepage: 'https://darwinia.network/',
isUnreachable: true,
paraId: 2006,
text: t('rpc.kusama.crab', 'Darwinia Crab', { ns: 'apps-config' }),
@ -72,6 +75,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'encointer_canary',
homepage: 'https://encointer.org/',
isUnreachable: true,
paraId: 2014,
text: t('rpc.kusama.encointer', 'Encointer Canary', { ns: 'apps-config' }),
@ -81,6 +85,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'genshiro',
homepage: 'https://equilibrium.io',
isUnreachable: true,
text: t('rpc.test.equilibriumtestnet', 'Genshiro', { ns: 'apps-config' }),
providers: {
@ -98,6 +103,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'karura',
homepage: 'https://acala.network/karura/join-karura',
paraId: 2000,
text: t('rpc.kusama.karura', 'Karura', { ns: 'apps-config' }),
providers: {
@ -106,6 +112,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'khala',
homepage: 'https://phala.network/',
isUnreachable: true,
paraId: 2004,
text: t('rpc.kusama.khala', 'Khala Network', { ns: 'apps-config' }),
@ -115,6 +122,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'kilt',
homepage: 'https://www.kilt.io/',
isUnreachable: true,
paraId: 2005,
text: t('rpc.kusama.kilt', 'KILT Mainnet', { ns: 'apps-config' }),
@ -124,6 +132,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'polkasmith',
homepage: 'https://polkafoundry.com/',
isUnreachable: true,
paraId: 2009,
text: t('rpc.kusama.polkasmith', 'Polkasmith', { ns: 'apps-config' }),
@ -133,6 +142,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'sakura',
homepage: 'https://clover.finance/',
isUnreachable: true,
paraId: 2016,
text: t('rpc.kusama.sakura', 'Sakura', { ns: 'apps-config' }),
@ -142,6 +152,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'sherpax',
homepage: 'https://chainx.org/',
isUnreachable: true,
paraId: 2013,
text: t('rpc.kusama.sherpax', 'SherpaX', { ns: 'apps-config' }),
@ -151,6 +162,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'shiden',
homepage: 'https://www.plasmnet.io/',
paraId: 2007,
text: t('rpc.kusama.shiden', 'Shiden', { ns: 'apps-config' }),
providers: {
@ -159,6 +171,7 @@ export function createKusama (t: TFunction): EndpointOption {
},
{
info: 'moonriver',
homepage: 'https://moonbeam.foundation/moonriver-crowdloan/',
isUnreachable: true,
paraId: 2023,
text: t('rpc.kusama.moonriver', 'Moonriver', { ns: 'apps-config' }),

View File

@ -6,6 +6,7 @@ import type { Option } from '../settings/types';
export interface EndpointOption {
dnslink?: string;
genesisHash?: string;
homepage?: string;
isChild?: boolean;
isDevelopment?: boolean;
isDisabled?: boolean;
@ -14,6 +15,7 @@ export interface EndpointOption {
info?: string;
paraId?: number;
providers: Record<string, string>;
summary?: string;
teleport?: number[];
text: React.ReactNode;
}
@ -22,6 +24,7 @@ export interface LinkOption extends Option {
dnslink?: string;
genesisHash?: string;
genesisHashRelay?: string;
homepage?: string;
isChild?: boolean;
isDevelopment?: boolean;
isRelay?: boolean;
@ -29,6 +32,7 @@ export interface LinkOption extends Option {
isSpaced?: boolean;
linked?: LinkOption[];
paraId?: number;
summary?: string;
teleport?: number[];
textBy: string;
}

View File

@ -33,9 +33,10 @@ export function expandLinked (input: LinkOption[]): LinkOption[] {
}, []);
}
export function expandEndpoint (t: TFunction, { dnslink, genesisHash, info, isChild, isDisabled, isUnreachable, linked, paraId, providers, teleport, text }: EndpointOption, firstOnly?: boolean): LinkOption[] {
export function expandEndpoint (t: TFunction, { dnslink, genesisHash, homepage, info, isChild, isDisabled, isUnreachable, linked, paraId, providers, teleport, text }: EndpointOption, firstOnly?: boolean): LinkOption[] {
const base = {
genesisHash,
homepage,
info,
isChild,
isDisabled,

View File

@ -9,7 +9,7 @@ import type { Campaign, LeasePeriod } from '../types';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { AddressMini, Icon, ParaLink, TxButton } from '@polkadot/react-components';
import { useAccounts, useApi, useEventTrigger } from '@polkadot/react-hooks';
import { useAccounts, useApi, useEventTrigger, useParaEndpoints } from '@polkadot/react-hooks';
import { BlockToTime, FormatBalance } from '@polkadot/react-query';
import { formatNumber } from '@polkadot/util';
import { encodeAddress } from '@polkadot/util-crypto';
@ -21,6 +21,7 @@ import Refund from './Refund';
interface Props {
bestNumber?: BN;
className?: string;
isOdd?: boolean;
isOngoing?: boolean;
leasePeriod?: LeasePeriod;
value: Campaign;
@ -42,10 +43,11 @@ function extractContributors (allAccounts: string[], keys: StorageKey[], ss58For
};
}
function Fund ({ bestNumber, className, isOngoing, leasePeriod, value: { childKey, info: { cap, depositor, end, firstPeriod, lastPeriod, raised, verifier }, isCapped, isEnded, isWinner, paraId } }: Props): React.ReactElement<Props> {
function Fund ({ bestNumber, className, isOdd, isOngoing, leasePeriod, value: { childKey, info: { cap, depositor, end, firstPeriod, lastPeriod, raised, verifier }, isCapped, isEnded, isWinner, paraId } }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const { allAccounts, isAccount } = useAccounts();
const endpoints = useParaEndpoints(paraId);
const [{ contributors, myAccounts }, setContributors] = useState<Contributions>(NO_CONTRIB);
const trigger = useEventTrigger([api.events.crowdloan.Contributed, api.events.crowdloan.Withdrew, api.events.crowdloan.AllRefunded, api.events.crowdloan.PartiallyRefunded], useCallback(
({ event: { data } }: EventRecord) =>
@ -93,85 +95,107 @@ function Fund ({ bestNumber, className, isOngoing, leasePeriod, value: { childKe
const canContribute = isOngoing && !isCapped && !isWinner && !!blocksLeft;
const canDissolve = raised.isZero();
const canWithdraw = !raised.isZero() && hasEnded;
const homepage = endpoints.length && endpoints[0].homepage;
return (
<tr className={className}>
<td className='number'><h1>{formatNumber(paraId)}</h1></td>
<td className='badge'><ParaLink id={paraId} /></td>
<td className='media--800'>
{isWinner
? t<string>('Winner')
: blocksLeft
? isCapped
? t<string>('Capped')
: isOngoing
? t<string>('Active')
: t<string>('Past')
: t<string>('Ended')
}
</td>
<td className='address media--1400'><AddressMini value={depositor} /></td>
<td className='all number together media--1200'>
{blocksLeft && (
<BlockToTime value={blocksLeft} />
)}
#{formatNumber(end)}
</td>
<td className='number all together'>
{firstPeriod.eq(lastPeriod)
? formatNumber(firstPeriod)
: `${formatNumber(firstPeriod)} - ${formatNumber(lastPeriod)}`
}
</td>
<td className='number together'>
<FormatBalance
value={raised}
withCurrency={false}
/>&nbsp;/&nbsp;<FormatBalance
value={cap}
/>
<div>{percentage}</div>
</td>
<td className='number media--1100'>
{contributors.length !== 0 && (
formatNumber(contributors.length)
)}
</td>
<td className='badge media--1000'>
<Icon
color={myAccounts.length ? 'green' : 'gray'}
icon='asterisk'
/>
</td>
<td className='button media--1000'>
{canWithdraw && contributors.length !== 0 && (
<Refund paraId={paraId} />
)}
{canDissolve && (
<TxButton
accountId={depositor}
className='media--1400'
icon='times'
isDisabled={!isDepositor}
label={
isEnded
? t<string>('Close')
: t<string>('Cancel')
}
params={[paraId]}
tx={api.tx.crowdloan.dissolve}
<>
<tr className={`${className || ''} ${isOdd ? 'isOdd' : 'isEven'} ${isOngoing && homepage ? 'noBorder' : ''}`}>
<td className='number'><h1>{formatNumber(paraId)}</h1></td>
<td className='badge'><ParaLink id={paraId} /></td>
<td className='media--800'>
{isWinner
? t<string>('Winner')
: blocksLeft
? isCapped
? t<string>('Capped')
: isOngoing
? t<string>('Active')
: t<string>('Past')
: t<string>('Ended')
}
</td>
<td className='address media--1400'><AddressMini value={depositor} /></td>
<td className='all number together media--1200'>
{blocksLeft && (
<BlockToTime value={blocksLeft} />
)}
#{formatNumber(end)}
</td>
<td className='number all together'>
{firstPeriod.eq(lastPeriod)
? formatNumber(firstPeriod)
: `${formatNumber(firstPeriod)} - ${formatNumber(lastPeriod)}`
}
</td>
<td className='number together'>
<FormatBalance
value={raised}
withCurrency={false}
/>&nbsp;/&nbsp;<FormatBalance
value={cap}
/>
)}
{isOngoing && canContribute && (
<Contribute
cap={cap}
needsSignature={verifier.isSome}
paraId={paraId}
raised={raised}
<div>{percentage}</div>
</td>
<td className='number media--1100'>
{contributors.length !== 0 && (
formatNumber(contributors.length)
)}
</td>
<td className='badge media--1000'>
<Icon
color={myAccounts.length ? 'green' : 'gray'}
icon='asterisk'
/>
)}
</td>
</tr>
</td>
<td className='button media--1000'>
{canWithdraw && contributors.length !== 0 && (
<Refund paraId={paraId} />
)}
{canDissolve && (
<TxButton
accountId={depositor}
className='media--1400'
icon='times'
isDisabled={!isDepositor}
label={
isEnded
? t<string>('Close')
: t<string>('Cancel')
}
params={[paraId]}
tx={api.tx.crowdloan.dissolve}
/>
)}
{isOngoing && canContribute && (
<Contribute
cap={cap}
needsSignature={verifier.isSome}
paraId={paraId}
raised={raised}
/>
)}
</td>
</tr>
{isOngoing && homepage && (
<tr className={`${className || ''} ${isOdd ? 'isOdd' : 'isEven'} isExpanded`}>
<td colSpan={2} />
<td className='media--800' />
<td className='media--1400' />
<td className='media--1200' />
<td className='all' />
<td />
<td className='media--1100' />
<td className='media--1000' />
<td className='middle no-pad-top media--1000'>
<a
href={homepage}
rel='noopener noreferrer'
target='_blank'
>{t<string>('Homepage')}</a>
</td>
</tr>
)}
</>
);
}

View File

@ -91,9 +91,10 @@ function Funds ({ bestNumber, className, leasePeriod, value }: Props): React.Rea
empty={value && activeSorted && t<string>('No active campaigns found')}
header={headerActiveRef.current}
>
{activeSorted?.map((fund) => (
{activeSorted?.map((fund, index) => (
<Fund
bestNumber={bestNumber}
isOdd={!(index % 2)}
isOngoing
key={fund.accountId}
value={fund}
@ -105,9 +106,10 @@ function Funds ({ bestNumber, className, leasePeriod, value }: Props): React.Rea
empty={value && endedSorted && t<string>('No completed campaigns found')}
header={headedEndedRef.current}
>
{endedSorted?.map((fund) => (
{endedSorted?.map((fund, index) => (
<Fund
bestNumber={bestNumber}
isOdd={!(index % 2)}
key={fund.accountId}
leasePeriod={leasePeriod}
value={fund}

View File

@ -201,6 +201,10 @@ export default React.memo(styled(Table)`
padding-right: 0.125rem;
}
&.no-pad-top {
padding-top: 0.125rem;
}
&.number {
text-align: right;
}