-
Notifications
You must be signed in to change notification settings - Fork 2.1k
[Insight] Chain details page #3974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
MicahMaphet
wants to merge
56
commits into
bitpay:master
Choose a base branch
from
MicahMaphet:chain-details
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
0e6c23f
create chain page and added header with link to blocks
MicahMaphet 8ff3057
Merge branch 'master' into chain-details
MicahMaphet 0150419
added block list to chain page
MicahMaphet 56ba11e
[REF] replace oneinch with coingecko for token lists
gabrielbazan7 180c2a1
v10.10.6
nitsujlangston 6bcac67
prevent redefine _getX/Y
Sayrix ce76c31
verify prePublishRaw tx
leolambo 6ccb7d9
Adding sourceAddress for SPL proposals
leolambo 46ebbd7
add all recipients by default
leolambo b324db6
feedback
leolambo 8c2b6bb
v10.10.7
nitsujlangston c5506ee
feat(templates): removes horizontal rule from email
mahume 9a891a6
[FIX] select inputs when replaceTxByFee - reuse one original input
gabrielbazan7 f77b083
removed unused lodash imports
MicahMaphet e5dcf28
v10.10.8
nitsujlangston cd2a8ae
add feePerKb to Solana getFee
leolambo 06bee9f
add solana base fee to defaults
leolambo 3814bee
lint
leolambo 2f8941f
v10.10.9
nitsujlangston 1ae8b3b
Merge branch 'master' of https://github.com/bitpay/bitcore into chain…
MicahMaphet ec13fa5
moved block list (now 10 blocks) to the right and linting
MicahMaphet fc181a1
Merge branch 'fee-data' into chain-details
MicahMaphet aa43033
added view blocks buton to bottom of transactions and fee data block
MicahMaphet 158b008
replaced table with block chain
MicahMaphet 09435bd
added fee chart
MicahMaphet cf28776
refactored chain-details page and added block tip fee
MicahMaphet b332934
Merge branch 'master' of https://github.com/bitpay/bitcore into chain…
MicahMaphet 554f259
added median fee to block data display (WIP: removing Promise nesting…
MicahMaphet dd837ef
refactored nested promises to use feeData on block route
MicahMaphet 3120ea0
added price labels to chart and aesthetic changes
MicahMaphet 8956bd6
removed y title from price chart
MicahMaphet cbd7484
added fee data graph
MicahMaphet e1552a7
started 'idle' version of block sample expand viewer
MicahMaphet 0feaabb
added data expansion to the currency block rows
MicahMaphet edada1f
moved currency colored chip label to top when expanded
MicahMaphet f5f7cb5
added sats/byte to fee data using new FeeBox element
MicahMaphet 8b74526
replaced boxes with tables broken up into two columns for most data e…
MicahMaphet 5f7cee3
made some text not bold
MicahMaphet eac648e
added block chip darken on hover
MicahMaphet b392e21
incorporated background darkening into the date of the BlockChipHeader
MicahMaphet 05569e4
added light mode
MicahMaphet eedb2f3
fixed bug messing up data-box children
MicahMaphet 0a521d4
Merge branch 'master' into chain-details
MicahMaphet 7ea4da1
redid chain details header, put graphs next to each other, redid colo…
MicahMaphet 71e2056
redid block listing making it more like a data table and numerous sty…
MicahMaphet 5c9f03c
added the rest of the data to the block expansion, refactoring with i…
MicahMaphet 6010234
improved color scheme, especially dark mode and added details in the …
MicahMaphet 6e3cbf3
added InfiniteScroll to blocks list in chain page
MicahMaphet dc71645
added view transactions and next block links to blocks list; changed …
MicahMaphet 1f678b3
removed unnecessary container in chain page
MicahMaphet 67db607
fixed ETH error on chain-page: handle no fee data (as well as other d…
MicahMaphet 16f4d7e
Merge branch 'master' into chain-details
MicahMaphet c562399
renamed block-sample -> block-list and removed blocks page
MicahMaphet bad27d5
renamed chain page to blocks page; renamed InfoCard -> info-card
MicahMaphet fb66c40
refactored expanded data with a list of all data that can be showed a…
MicahMaphet 15dffb4
Michal Stachnik's review changes: fee and price change components and…
MicahMaphet File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,207 @@ | ||
| import React, {FC, useState} from 'react'; | ||
| import {getApiRoot, getConvertedValue, getDifficultyFromBits, getFormattedDate} from 'src/utilities/helper-methods'; | ||
| import {BitcoinBlockType} from 'src/utilities/models'; | ||
| import Cube from '../assets/images/cube.svg'; | ||
| import Arrow from '../assets/images/arrow-thin.svg'; | ||
| import ArrowOutward from '../assets/images/arrow-outward.svg'; | ||
| import ForwardArrow from '../assets/images/arrow-forward-blue.svg'; | ||
| import ArrowDown from '../assets/images/arrow-down.svg'; | ||
| import styled, {useTheme} from 'styled-components'; | ||
| import InfoCard from './info-card'; | ||
| import InfiniteScroll from 'react-infinite-scroll-component'; | ||
| import {fetcher} from 'src/api/api'; | ||
| import InfiniteScrollLoadSpinner from './infinite-scroll-load-spinner'; | ||
| import Info from './info'; | ||
| import {useNavigate} from 'react-router-dom'; | ||
| import {useBlocks} from 'src/pages/blocks'; | ||
|
|
||
| const BlockListTableRow = styled.tr` | ||
| text-align: center; | ||
| line-height: 45px; | ||
|
|
||
| &:nth-child(odd) { | ||
| background-color: ${({theme: {dark}}) => (dark ? '#2a2a2a' : '#f6f7f9')}; | ||
| } | ||
|
|
||
| &:nth-child(even) { | ||
| background-color: ${({theme: {dark}}) => (dark ? '#0f0f0f' : '#e0e4e7')}; | ||
| } | ||
|
|
||
| font-size: 16px; | ||
| `; | ||
|
|
||
|
|
||
| const getBlocksUrl = (currency: string, network: string) => { | ||
| return `${getApiRoot(currency)}/${currency}/${network}/block?limit=200`; | ||
| }; | ||
|
|
||
| const BlockList: FC<{currency: string, network: string}> = ({currency, network}) => { | ||
| const theme = useTheme(); | ||
| const { blocks, setBlocks } = useBlocks(); | ||
| if (!blocks) | ||
| return null; | ||
| const navigate = useNavigate(); | ||
| const [expandedBlocks, setExpandedBlocks] = useState<number[]>([]); | ||
| const [error, setError] = useState(''); | ||
| const [hasMore, setHasMore] = useState(true); | ||
| const hasFees = blocks.every(block => block.feeData); | ||
| const columnProportion = hasFees ? '20%' : '25%'; | ||
|
|
||
| const fetchMore = async (_blocksList: BitcoinBlockType[]) => { | ||
| if (!_blocksList.length || !currency || !network) return; | ||
| const since = _blocksList[_blocksList.length - 1].height; | ||
| try { | ||
| const newData: [BitcoinBlockType] = await fetcher( | ||
| `${getBlocksUrl(currency, network)}&since=${since}&paging=height&direction=-1`, | ||
| ); | ||
| if (newData?.length) { | ||
| setBlocks(_blocksList.concat(newData)); | ||
| } else { | ||
| setHasMore(false); | ||
| } | ||
| } catch (e: any) { | ||
| setError(e.message || 'Something went wrong. Please try again later.'); | ||
| } | ||
| }; | ||
|
|
||
| const gotoSingleBlockDetailsView = (hash: string) => { | ||
| navigate(`/${currency}/${network}/block/${hash}`); | ||
| }; | ||
|
|
||
| if (!blocks?.length) return null; | ||
| return ( | ||
| <> | ||
| {error ? <Info type={'error'} message={error} /> : null} | ||
| <InfiniteScroll | ||
| next={() => fetchMore(blocks)} | ||
| hasMore={hasMore} | ||
| loader={<InfiniteScrollLoadSpinner />} | ||
| dataLength={blocks.length}> | ||
| <table style={{width: '100%', overflowX: 'hidden', borderCollapse: 'collapse'}}> | ||
| <thead> | ||
| <BlockListTableRow> | ||
| <th style={{textAlign: 'left', paddingLeft: '3rem', width: columnProportion}}>Height</th> | ||
| <th style={{width: columnProportion}}>Timestamp</th> | ||
| <th style={{width: columnProportion}}>Transactions</th> | ||
| <th style={{width: columnProportion}}>Size</th> | ||
| {hasFees && <th style={{textAlign: 'right', paddingRight: '3rem', width: '20%'}}>Fee Rate</th>} | ||
| </BlockListTableRow> | ||
| </thead> | ||
| <tbody> | ||
| <tr /> | ||
| { | ||
| blocks.map((block: BitcoinBlockType, index: number) => { | ||
| const feeData = block.feeData; | ||
| const expanded = expandedBlocks.includes(block.height); | ||
|
|
||
| const dataRowsDB = { | ||
| 'Previous block': {label: 'Previous block', value: block.height - 1}, | ||
| 'Bits': {label: 'Bits', value: block.bits}, | ||
| 'Version': {label: 'Version', value: block.version}, | ||
| 'Block reward': {label: 'Block reward', value: `${getConvertedValue(block.reward, currency).toFixed(3)} ${currency}`}, | ||
| 'Miner fees': {label: 'Miner fees', value: `${getConvertedValue(feeData?.feeTotal, currency).toFixed(5)} ${currency}`}, | ||
| 'Next block': {label: 'Next block', value: | ||
| <> | ||
| {block.height + 1} | ||
| <img | ||
| src={ArrowOutward} | ||
| style={{width: '24px', cursor: 'pointer'}} | ||
| onClick={() => gotoSingleBlockDetailsView(blocks[index - 1].hash)} | ||
| alt='Next Block' | ||
| title={`Go to block ${block.height + 1}`} | ||
| /> | ||
| </> | ||
| }, | ||
| 'Nonce': {label: 'Nonce', value: block.nonce}, | ||
| 'Confirmations': {label: 'Confirmations', value: blocks[0].height - block.height + 1}, | ||
| 'Difficulty': {label: 'Difficulty', value: getDifficultyFromBits(block.bits).toFixed(0)}, | ||
| 'Fee data': {label: 'Fee data', value: | ||
| <div style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between', width: '100%'}}> | ||
| {[{label: 'Mean', value: feeData?.mean}, {label: 'Median', value: feeData?.median}, {label: 'Mode', value: feeData?.mode}] | ||
| .map(({label, value}, key) => { | ||
| return <React.Fragment key={key}> | ||
| <div style={{display: 'flex', flexDirection: 'column', lineHeight: 1.1, marginTop: '-0.4rem'}}> | ||
| <span style={{color: theme.dark ? '#888' : '#474d53', alignSelf: 'flex-start', lineHeight: 2, marginBottom: -2, fontSize: '16px'}}>{label}</span> | ||
| {value?.toFixed(4)} | ||
| </div> | ||
| </React.Fragment> | ||
| }) | ||
| } | ||
| </div> | ||
| } | ||
| }; | ||
|
|
||
| type IDataRowsDB = keyof typeof dataRowsDB; | ||
| let columnLeftExpandedDataKeys: IDataRowsDB[]; | ||
| let columnRightExpandedDataKeys: IDataRowsDB[]; | ||
|
|
||
| if (currency === 'ETH') { | ||
| columnLeftExpandedDataKeys = ['Previous block', 'Block reward']; | ||
| columnRightExpandedDataKeys = ['Next block', 'Nonce', 'Confirmations']; | ||
| } else { | ||
| columnLeftExpandedDataKeys = ['Previous block', 'Bits', 'Version', 'Block reward', 'Miner fees']; | ||
| columnRightExpandedDataKeys = ['Next block', 'Nonce', 'Confirmations', 'Difficulty', 'Fee data']; | ||
| } | ||
| const columnLeftExpandedData : Array<{label: string, value: any}> = columnLeftExpandedDataKeys.map(key => dataRowsDB[key]); | ||
| const columnRightExpandedData : Array<{label: string, value: any}> = columnRightExpandedDataKeys.map(key => dataRowsDB[key]); | ||
|
|
||
| return ( | ||
| <React.Fragment key={index}> | ||
MicahMaphet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| <BlockListTableRow key={index}> | ||
| <td style={{textAlign: 'left', color: '#2240C4', paddingLeft: '1rem'}}> | ||
| <span | ||
| style={{display: 'flex', alignItems: 'center', gap: '0.5em', width: 'fit-content', cursor: 'pointer'}} | ||
| onClick={() => expanded | ||
| ? setExpandedBlocks(expandedBlocks.filter(h => h !== block.height)) | ||
| : setExpandedBlocks([...expandedBlocks, block.height])}> | ||
| {expanded | ||
| ? <img src={ArrowDown} style={{height: '2rem', marginLeft: '-2px', marginRight: '-7px'}} alt='arrow' /> | ||
| : <img src={Arrow} style={{height: '1.8rem', marginRight: '-6px'}} alt='arrow' /> | ||
| } | ||
| <img src={Cube} style={{height: '1.2rem'}} alt='cube' /> | ||
| {block.height} | ||
| </span> | ||
| </td> | ||
| <td>{getFormattedDate(block.time)}</td> | ||
| <td>{block.transactionCount}</td> | ||
| <td>{block.size}</td> | ||
| { feeData && <td style={{textAlign: 'right', paddingRight: '3rem'}}>{feeData.median.toFixed(4)}</td> } | ||
| </BlockListTableRow> | ||
| {expanded && <> | ||
| {/* Alternates the color so the data below this row stays the same*/} | ||
| <BlockListTableRow /> | ||
| <BlockListTableRow> | ||
|
|
||
| <td colSpan={5} style={{padding: '1rem 2rem'}}> | ||
| <div style={{display: 'flex', flexDirection: 'column', gap: '1rem'}}> | ||
| <hr style={{border: 'none', borderTop: '1px solid #eee', margin: '0 -2rem', marginTop: '-0.8rem'}} /> | ||
| <InfoCard data={[ | ||
| {label: 'Block Hash', value: block.hash, copyText: true}, | ||
| {label: 'Merkle Root', value: block.merkleRoot, copyText: true}, | ||
| ]}/> | ||
| <span style={{fontSize: '20px', alignSelf: 'flex-start'}}>Summary</span> | ||
| <div style={{display: 'flex', gap: '1rem'}}> | ||
| <InfoCard data={columnLeftExpandedData}/> | ||
| <InfoCard data={columnRightExpandedData}/> | ||
| </div> | ||
| <span style={{display: 'flex', alignItems: 'center', width: 'fit-content', cursor: 'pointer'}} onClick={() => gotoSingleBlockDetailsView(block.hash)}> | ||
| <span style={{color: '#2240C4', marginRight: '0.75rem', fontSize: '18px'}}>View transactions</span> | ||
| <img src={ForwardArrow} style={{height: '1.75rem'}} alt='arrow' /> | ||
| </span> | ||
| </div> | ||
| </td> | ||
| </BlockListTableRow> | ||
| </> | ||
| } | ||
| </React.Fragment> | ||
| ); | ||
| }) | ||
| } | ||
| </tbody> | ||
| </table> | ||
| </InfiniteScroll> | ||
| </> | ||
| ); | ||
| }; | ||
|
|
||
| export default BlockList; | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.