Cleanups on explorer Forks (#2482)
* Cleanups on explorer Forks * Small opts
This commit is contained in:
parent
eb2167d540
commit
5dc1f908f4
@ -28,11 +28,14 @@ function BlockByHash ({ className, value }: Props): React.ReactElement<Props> {
|
||||
const getBlock = useCall<SignedBlock>(api.rpc.chain.getBlock as any, [value], { isSingle: true });
|
||||
const getHeader = useCall<HeaderExtended>(api.derive.chain.getHeader as any, [value]);
|
||||
|
||||
const blockNumber = getHeader?.number.unwrap();
|
||||
const parentHash = getHeader?.parentHash.toHex();
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<Table isFixed>
|
||||
<Table.Head>
|
||||
<th className='start'><h1>{getHeader ? formatNumber(getHeader.number.unwrap()) : '-'}</h1></th>
|
||||
<th className='start' colSpan={getHeader ? 1 : 6}><h1>{formatNumber(blockNumber)}</h1></th>
|
||||
{getHeader && (
|
||||
<>
|
||||
<th className='start'>{t('hash')}</th>
|
||||
@ -48,7 +51,7 @@ function BlockByHash ({ className, value }: Props): React.ReactElement<Props> {
|
||||
<tr>
|
||||
<td className='address'>{getHeader.author && <AddressMini value={getHeader.author} />}</td>
|
||||
<td className='hash overflow'>{getHeader.hash.toHex()}</td>
|
||||
<td className='hash overflow'><Link to={`/explorer/query/${getHeader.parentHash.toHex()}`}>{getHeader.parentHash.toHex()}</Link></td>
|
||||
<td className='hash overflow'><Link to={`/explorer/query/${parentHash}`}>{parentHash}</Link></td>
|
||||
<td className='hash overflow'>{getHeader.extrinsicsRoot.toHex()}</td>
|
||||
<td className='hash overflow'>{getHeader.stateRoot.toHex()}</td>
|
||||
<td><LinkExternal data={value} type='block' /></td>
|
||||
@ -59,7 +62,7 @@ function BlockByHash ({ className, value }: Props): React.ReactElement<Props> {
|
||||
{getBlock && getHeader && (
|
||||
<Columar>
|
||||
<Extrinsics
|
||||
blockNumber={getHeader.number.unwrap()}
|
||||
blockNumber={blockNumber}
|
||||
value={getBlock.block.extrinsics}
|
||||
/>
|
||||
<Events value={events} />
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import { ApiProps } from '@polkadot/react-api/types';
|
||||
import { Header } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { CardSummary, IdentityIcon, SummaryBox } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
@ -211,84 +211,91 @@ function Forks ({ className }: Props): React.ReactElement<Props> | null {
|
||||
const headersRef = useRef<Map<string, LinkHeader>>(new Map());
|
||||
const firstNumRef = useRef('');
|
||||
|
||||
const _finalize = (hash: string): void => {
|
||||
const hdr = headersRef.current.get(hash);
|
||||
|
||||
if (hdr && !hdr.isFinalized) {
|
||||
hdr.isFinalized = true;
|
||||
|
||||
_finalize(hdr.parent);
|
||||
}
|
||||
};
|
||||
|
||||
// adds children for a specific header, retrieving based on matching parent
|
||||
const _addChildren = (base: LinkHeader, children: LinkArray): LinkArray => {
|
||||
const hdrs = (childrenRef.current.get(base.hash) || [])
|
||||
.map((hash): LinkHeader | null => headersRef.current.get(hash) || null)
|
||||
.filter((hdr): boolean => !!hdr) as LinkHeader[];
|
||||
|
||||
hdrs.forEach((hdr): void => {
|
||||
children.push({ arr: _addChildren(hdr, []), hdr });
|
||||
});
|
||||
|
||||
// caclulate the max height/width for this entry
|
||||
base.height = calcHeight(children);
|
||||
base.width = calcWidth(children);
|
||||
|
||||
// place the active (larger, finalized) columns first for the pyramid display
|
||||
children.sort((a, b): number => {
|
||||
if (a.hdr.width > b.hdr.width || a.hdr.height > b.hdr.height || a.hdr.isFinalized) {
|
||||
return -1;
|
||||
} else if (a.hdr.width < b.hdr.width || a.hdr.height < b.hdr.height || b.hdr.isFinalized) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
// create a tree list from the available headers
|
||||
const _generateTree = (): Link => {
|
||||
const root = createLink();
|
||||
|
||||
// add all the root entries first, we iterate from these
|
||||
// We add the root entry explicitly, it exists as per init
|
||||
(childrenRef.current.get('root') as string[]).forEach((hash): void => {
|
||||
const _finalize = useCallback(
|
||||
(hash: string): void => {
|
||||
const hdr = headersRef.current.get(hash);
|
||||
|
||||
// if this fails, well, we have a bigger issue :(
|
||||
if (hdr) {
|
||||
root.arr.push({ arr: [], hdr: { ...hdr } });
|
||||
if (hdr && !hdr.isFinalized) {
|
||||
hdr.isFinalized = true;
|
||||
|
||||
_finalize(hdr.parent);
|
||||
}
|
||||
});
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
// iterate through, adding the children for each of the root nodes
|
||||
root.arr.forEach(({ arr, hdr }): void => {
|
||||
_addChildren(hdr, arr);
|
||||
});
|
||||
// adds children for a specific header, retrieving based on matching parent
|
||||
const _addChildren = useCallback(
|
||||
(base: LinkHeader, children: LinkArray): LinkArray => {
|
||||
// add the children
|
||||
(childrenRef.current.get(base.hash) || [])
|
||||
.map((hash): LinkHeader | undefined => headersRef.current.get(hash))
|
||||
.filter((hdr): hdr is LinkHeader => !!hdr)
|
||||
.forEach((hdr): void => {
|
||||
children.push({ arr: _addChildren(hdr, []), hdr });
|
||||
});
|
||||
|
||||
// align the columns with empty spacers - this aids in display
|
||||
addColumnSpacers(root.arr);
|
||||
// calculate the max height/width for this entry
|
||||
base.height = calcHeight(children);
|
||||
base.width = calcWidth(children);
|
||||
|
||||
root.hdr.height = calcHeight(root.arr);
|
||||
root.hdr.width = calcWidth(root.arr);
|
||||
// place the active (larger, finalized) columns first for the pyramid display
|
||||
children.sort((a, b): number =>
|
||||
(a.hdr.width > b.hdr.width || a.hdr.height > b.hdr.height || a.hdr.isFinalized)
|
||||
? -1
|
||||
: (a.hdr.width < b.hdr.width || a.hdr.height < b.hdr.height || b.hdr.isFinalized)
|
||||
? 1
|
||||
: 0
|
||||
);
|
||||
|
||||
return root;
|
||||
};
|
||||
return children;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect((): () => void => {
|
||||
let _subFinHead: UnsubFn | null = null;
|
||||
let _subNewHead: UnsubFn | null = null;
|
||||
// create a tree list from the available headers
|
||||
const _generateTree = useCallback(
|
||||
(): Link => {
|
||||
const root = createLink();
|
||||
|
||||
// callback when finalized
|
||||
const _newFinalized = (header: Header): void => {
|
||||
// add all the root entries first, we iterate from these
|
||||
// We add the root entry explicitly, it exists as per init
|
||||
(childrenRef.current.get('root') || []).forEach((hash): void => {
|
||||
const hdr = headersRef.current.get(hash);
|
||||
|
||||
// if this fails, well, we have a bigger issue :(
|
||||
if (hdr) {
|
||||
root.arr.push({ arr: [], hdr: { ...hdr } });
|
||||
}
|
||||
});
|
||||
|
||||
// iterate through, adding the children for each of the root nodes
|
||||
root.arr.forEach(({ arr, hdr }): void => {
|
||||
_addChildren(hdr, arr);
|
||||
});
|
||||
|
||||
// align the columns with empty spacers - this aids in display
|
||||
addColumnSpacers(root.arr);
|
||||
|
||||
root.hdr.height = calcHeight(root.arr);
|
||||
root.hdr.width = calcWidth(root.arr);
|
||||
|
||||
return root;
|
||||
},
|
||||
[_addChildren]
|
||||
);
|
||||
|
||||
// callback when finalized
|
||||
const _newFinalized = useCallback(
|
||||
(header: Header): void => {
|
||||
_finalize(header.hash.toHex());
|
||||
};
|
||||
},
|
||||
[_finalize]
|
||||
);
|
||||
|
||||
// callback for the subscribe headers sub
|
||||
const _newHeader = (header: Header): void => {
|
||||
// callback for the subscribe headers sub
|
||||
const _newHeader = useCallback(
|
||||
(header: Header): void => {
|
||||
// formatted block info
|
||||
const bn = formatNumber(header.number);
|
||||
const hash = header.hash.toHex();
|
||||
@ -341,7 +348,13 @@ function Forks ({ className }: Props): React.ReactElement<Props> | null {
|
||||
// do the magic, extract the info into something useful and add to state
|
||||
setTree(_generateTree());
|
||||
}
|
||||
};
|
||||
},
|
||||
[api, _generateTree]
|
||||
);
|
||||
|
||||
useEffect((): () => void => {
|
||||
let _subFinHead: UnsubFn | null = null;
|
||||
let _subNewHead: UnsubFn | null = null;
|
||||
|
||||
(async (): Promise<void> => {
|
||||
_subFinHead = await api.rpc.chain.subscribeFinalizedHeads(_newFinalized);
|
||||
@ -352,8 +365,7 @@ function Forks ({ className }: Props): React.ReactElement<Props> | null {
|
||||
_subFinHead && _subFinHead();
|
||||
_subNewHead && _subNewHead();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [api, _newFinalized, _newHeader]);
|
||||
|
||||
if (!tree) {
|
||||
return null;
|
||||
@ -384,32 +396,6 @@ export default React.memo(styled(Forks)`
|
||||
border-spacing: 0.25rem;
|
||||
font-family: monospace;
|
||||
|
||||
/* tr {
|
||||
opacity: 0.05;
|
||||
|
||||
&:nth-child(1) { opacity: 1; }
|
||||
&:nth-child(2) { opacity: 0.95; }
|
||||
&:nth-child(3) { opacity: 0.9; }
|
||||
&:nth-child(4) { opacity: 0.85; }
|
||||
&:nth-child(5) { opacity: 0.8; }
|
||||
&:nth-child(6) { opacity: 0.75; }
|
||||
&:nth-child(7) { opacity: 0.70; }
|
||||
&:nth-child(8) { opacity: 0.65; }
|
||||
&:nth-child(9) { opacity: 0.6; }
|
||||
&:nth-child(10) { opacity: 0.55; }
|
||||
&:nth-child(11) { opacity: 0.6; }
|
||||
&:nth-child(12) { opacity: 0.55; }
|
||||
&:nth-child(13) { opacity: 0.5; }
|
||||
&:nth-child(14) { opacity: 0.45; }
|
||||
&:nth-child(15) { opacity: 0.4; }
|
||||
&:nth-child(16) { opacity: 0.35; }
|
||||
&:nth-child(17) { opacity: 0.3; }
|
||||
&:nth-child(18) { opacity: 0.25; }
|
||||
&:nth-child(19) { opacity: 0.2; }
|
||||
&:nth-child(20) { opacity: 0.15; }
|
||||
&:nth-child(21) { opacity: 0.1; }
|
||||
} */
|
||||
|
||||
td {
|
||||
padding: 0.25rem 0.5rem;
|
||||
text-align: center;
|
||||
@ -445,8 +431,8 @@ export default React.memo(styled(Forks)`
|
||||
}
|
||||
|
||||
&.header {
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #eee;
|
||||
background: #fff;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 0.25rem;
|
||||
|
||||
&.isEmpty {
|
||||
@ -456,7 +442,6 @@ export default React.memo(styled(Forks)`
|
||||
|
||||
&.isFinalized {
|
||||
background: rgba(0, 255, 0, 0.1);
|
||||
border-color: rgba(0, 255, 0, 0.17);
|
||||
}
|
||||
|
||||
&.isLink {
|
||||
@ -468,7 +453,6 @@ export default React.memo(styled(Forks)`
|
||||
|
||||
&.isMissing {
|
||||
background: rgba(255, 0, 0, 0.05);
|
||||
border-color: rgba(255, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,8 +29,8 @@ interface Props {
|
||||
type AccountExtend = [string, boolean, boolean];
|
||||
|
||||
interface Filtered {
|
||||
elected: AccountExtend[];
|
||||
validators: AccountExtend[];
|
||||
elected?: AccountExtend[];
|
||||
validators?: AccountExtend[];
|
||||
waiting?: AccountExtend[];
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ function getFiltered (stakingOverview: DeriveStakingOverview, favorites: string[
|
||||
function CurrentList ({ authorsMap, hasQueries, isIntentions, isVisible, lastAuthors, next, recentlyOnline, setNominators, stakingOverview }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const [favorites, toggleFavorite] = useFavorites(STORE_FAVS_BASE);
|
||||
const [{ elected, validators, waiting }, setFiltered] = useState<Filtered>({ elected: [], validators: [] });
|
||||
const [{ elected, validators, waiting }, setFiltered] = useState<Filtered>({});
|
||||
const [nameFilter, setNameFilter] = useState<string>('');
|
||||
const [addressDetails, dispatchDetails] = useReducer(reduceDetails, {});
|
||||
|
||||
@ -111,7 +111,7 @@ function CurrentList ({ authorsMap, hasQueries, isIntentions, isVisible, lastAut
|
||||
}, [favorites, isVisible, next, stakingOverview]);
|
||||
|
||||
useEffect((): void => {
|
||||
stakingOverview && dispatchDetails(
|
||||
stakingOverview && validators && dispatchDetails(
|
||||
getDetails(stakingOverview, validators)
|
||||
);
|
||||
}, [stakingOverview, validators]);
|
||||
@ -156,7 +156,7 @@ function CurrentList ({ authorsMap, hasQueries, isIntentions, isVisible, lastAut
|
||||
<th>{t('last #')}</th>
|
||||
<th> </th>
|
||||
</Table.Head>
|
||||
<Table.Body empty={stakingOverview && t('No active validators found')}>
|
||||
<Table.Body empty={validators && t('No active validators found')}>
|
||||
{_renderRows(validators, true)}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
@ -82,8 +82,6 @@ const Memo = React.memo(styled(Table)`
|
||||
}
|
||||
|
||||
table {
|
||||
// border: 1px solid #e6e6e6;
|
||||
border-radius: 0.25rem;
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
@ -138,20 +136,16 @@ const Memo = React.memo(styled(Table)`
|
||||
tr {
|
||||
width: 100%;
|
||||
|
||||
&.isHighlight {
|
||||
td {
|
||||
background: #ffffed;
|
||||
}
|
||||
&.isHighlight td {
|
||||
background: #ffffed;
|
||||
}
|
||||
|
||||
label {
|
||||
opacity: 0.42;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
label {
|
||||
opacity: 1;
|
||||
}
|
||||
&:hover label {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:not(:hover) {
|
||||
@ -189,7 +183,6 @@ const Memo = React.memo(styled(Table)`
|
||||
}
|
||||
|
||||
td {
|
||||
// border-top: 1px solid #f2f2f2;
|
||||
padding: 0.75rem 1rem;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
@ -209,7 +202,7 @@ const Memo = React.memo(styled(Table)`
|
||||
}
|
||||
|
||||
.ui--Spinner {
|
||||
margin: auto 0.5rem;
|
||||
margin: 0.5rem auto;
|
||||
|
||||
.text {
|
||||
margin-bottom: 0;
|
||||
@ -219,13 +212,6 @@ const Memo = React.memo(styled(Table)`
|
||||
&.address {
|
||||
min-width: 11rem;
|
||||
padding: 0.85rem 1rem;
|
||||
|
||||
> .ui--AddressMini,
|
||||
> .ui--AddressMini.padded {
|
||||
label.ui--AddressMini-label {
|
||||
margin-bottom: -0.3rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.button {
|
||||
@ -238,10 +224,6 @@ const Memo = React.memo(styled(Table)`
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
&.empty {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&.hash {
|
||||
font-family: monospace;
|
||||
}
|
||||
@ -279,27 +261,18 @@ const Memo = React.memo(styled(Table)`
|
||||
}
|
||||
|
||||
th {
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
color: rgba(78, 78, 78, .66);
|
||||
font-family: sans-serif;
|
||||
font-weight: 400;
|
||||
font-weight: 100;
|
||||
text-align: right;
|
||||
padding: 0.75rem 1rem 0.25rem;
|
||||
vertical-align: baseline;
|
||||
white-space: nowrap;
|
||||
|
||||
h1, h2 {
|
||||
color: inherit;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: 0.25rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: 0.25rem;
|
||||
}
|
||||
|
||||
&.isClickable {
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user