From 5dc1f908f454ede5bcf74b6b88ec58695f69a952 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 30 Mar 2020 09:01:59 +0200 Subject: [PATCH] Cleanups on explorer Forks (#2482) * Cleanups on explorer Forks * Small opts --- .../page-explorer/src/BlockInfo/ByHash.tsx | 9 +- packages/page-explorer/src/Forks.tsx | 186 ++++++++---------- .../page-staking/src/Overview/CurrentList.tsx | 10 +- packages/react-components/src/Table.tsx | 41 +--- 4 files changed, 103 insertions(+), 143 deletions(-) diff --git a/packages/page-explorer/src/BlockInfo/ByHash.tsx b/packages/page-explorer/src/BlockInfo/ByHash.tsx index 37166daf8f..07c52ba687 100644 --- a/packages/page-explorer/src/BlockInfo/ByHash.tsx +++ b/packages/page-explorer/src/BlockInfo/ByHash.tsx @@ -28,11 +28,14 @@ function BlockByHash ({ className, value }: Props): React.ReactElement { const getBlock = useCall(api.rpc.chain.getBlock as any, [value], { isSingle: true }); const getHeader = useCall(api.derive.chain.getHeader as any, [value]); + const blockNumber = getHeader?.number.unwrap(); + const parentHash = getHeader?.parentHash.toHex(); + return (
- + {getHeader && ( <> @@ -48,7 +51,7 @@ function BlockByHash ({ className, value }: Props): React.ReactElement { - + @@ -59,7 +62,7 @@ function BlockByHash ({ className, value }: Props): React.ReactElement { {getBlock && getHeader && ( diff --git a/packages/page-explorer/src/Forks.tsx b/packages/page-explorer/src/Forks.tsx index 93801b0741..186ab57ac6 100644 --- a/packages/page-explorer/src/Forks.tsx +++ b/packages/page-explorer/src/Forks.tsx @@ -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 | null { const headersRef = useRef>(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 | 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 => { _subFinHead = await api.rpc.chain.subscribeFinalizedHeads(_newFinalized); @@ -352,8 +365,7 @@ function Forks ({ className }: Props): React.ReactElement | 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); } } } diff --git a/packages/page-staking/src/Overview/CurrentList.tsx b/packages/page-staking/src/Overview/CurrentList.tsx index a74f9f4616..cde628d525 100644 --- a/packages/page-staking/src/Overview/CurrentList.tsx +++ b/packages/page-staking/src/Overview/CurrentList.tsx @@ -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 | null { const { t } = useTranslation(); const [favorites, toggleFavorite] = useFavorites(STORE_FAVS_BASE); - const [{ elected, validators, waiting }, setFiltered] = useState({ elected: [], validators: [] }); + const [{ elected, validators, waiting }, setFiltered] = useState({}); const [nameFilter, setNameFilter] = useState(''); 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 - + {_renderRows(validators, true)}

{getHeader ? formatNumber(getHeader.number.unwrap()) : '-'}

{formatNumber(blockNumber)}

{t('hash')}
{getHeader.author && } {getHeader.hash.toHex()}{getHeader.parentHash.toHex()}{parentHash} {getHeader.extrinsicsRoot.toHex()} {getHeader.stateRoot.toHex()} {t('last #')}  
diff --git a/packages/react-components/src/Table.tsx b/packages/react-components/src/Table.tsx index 18fd3b19bd..0333335775 100644 --- a/packages/react-components/src/Table.tsx +++ b/packages/react-components/src/Table.tsx @@ -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;