Commit 4f948605 authored by tom's avatar tom

skeletons for validated blocks by address

parent c91f469d
......@@ -11,6 +11,8 @@ import { getResourceKey } from 'lib/api/useApiQuery';
import useQueryWithPages from 'lib/hooks/useQueryWithPages';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
import { BLOCK } from 'stubs/block';
import { generateListStub } from 'stubs/utils';
import ActionBar from 'ui/shared/ActionBar';
import DataListDisplay from 'ui/shared/DataListDisplay';
import Pagination from 'ui/shared/Pagination';
......@@ -34,6 +36,18 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
resourceName: 'address_blocks_validated',
pathParams: { hash: addressHash },
scrollRef,
options: {
placeholderData: generateListStub<'address_blocks_validated'>(
BLOCK,
50,
{
next_page_params: {
block_number: 9060562,
items_count: 50,
},
},
),
},
});
const handleSocketError = React.useCallback(() => {
......@@ -61,7 +75,7 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
topic: `blocks:${ addressHash.toLowerCase() }`,
onSocketClose: handleSocketError,
onSocketError: handleSocketError,
isDisabled: !addressHash || query.pagination.page !== 1,
isDisabled: !addressHash || query.isPlaceholderData || query.pagination.page !== 1,
});
useSocketMessage({
channel,
......@@ -84,22 +98,32 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
</Tr>
</Thead>
<Tbody>
{ query.data.items.map((item) => (
<AddressBlocksValidatedTableItem key={ item.height } { ...item } page={ query.pagination.page }/>
{ query.data.items.map((item, index) => (
<AddressBlocksValidatedTableItem
key={ item.height + (query.isPlaceholderData ? String(index) : '') }
{ ...item }
page={ query.pagination.page }
isLoading={ query.isPlaceholderData }
/>
)) }
</Tbody>
</Table>
</Hide>
<Show below="lg" ssr={ false }>
{ query.data.items.map((item) => (
<AddressBlocksValidatedListItem key={ item.height } { ...item } page={ query.pagination.page }/>
{ query.data.items.map((item, index) => (
<AddressBlocksValidatedListItem
key={ item.height + (query.isPlaceholderData ? String(index) : '') }
{ ...item }
page={ query.pagination.page }
isLoading={ query.isPlaceholderData }
/>
)) }
</Show>
</>
) : null;
const actionBar = query.isPaginationVisible ? (
<ActionBar mt={ -6 } showShadow={ query.isLoading }>
<ActionBar mt={ -6 }>
<Pagination ml="auto" { ...query.pagination }/>
</ActionBar>
) : null;
......@@ -107,7 +131,7 @@ const AddressBlocksValidated = ({ scrollRef }: Props) => {
return (
<DataListDisplay
isError={ query.isError }
isLoading={ query.isLoading }
isLoading={ false }
items={ query.data?.items }
skeletonProps={{ isLongSkeleton: true, skeletonDesktopColumns: [ '17%', '17%', '16%', '25%', '25%' ] }}
emptyText="There are no validated blocks for this address."
......
import { Text, Flex } from '@chakra-ui/react';
import { Flex, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
......@@ -14,6 +14,7 @@ import Utilization from 'ui/shared/Utilization/Utilization';
type Props = Block & {
page: number;
isLoading: boolean;
};
const AddressBlocksValidatedListItem = (props: Props) => {
......@@ -24,21 +25,31 @@ const AddressBlocksValidatedListItem = (props: Props) => {
return (
<ListItemMobile rowGap={ 2 } isAnimated>
<Flex justifyContent="space-between" w="100%">
<LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
<Text variant="secondary">{ timeAgo }</Text>
<Skeleton isLoaded={ !props.isLoading } display="inline-block">
<LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
</Skeleton>
<Skeleton isLoaded={ !props.isLoading } color="text_secondary" display="inline-block">
<span>{ timeAgo }</span>
</Skeleton>
</Flex>
<Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 } flexShrink={ 0 }>Txn</Text>
<Text variant="secondary">{ props.tx_count }</Text>
<Skeleton isLoaded={ !props.isLoading } fontWeight={ 500 } flexShrink={ 0 }>Txn</Skeleton>
<Skeleton isLoaded={ !props.isLoading } display="inline-block" color="Skeleton_secondary">
<span>{ props.tx_count }</span>
</Skeleton>
</Flex>
<Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 } flexShrink={ 0 }>Gas used</Text>
<Text variant="secondary">{ BigNumber(props.gas_used || 0).toFormat() }</Text>
<Utilization colorScheme="gray" value={ BigNumber(props.gas_used || 0).dividedBy(BigNumber(props.gas_limit)).toNumber() }/>
<Skeleton isLoaded={ !props.isLoading } fontWeight={ 500 } flexShrink={ 0 }>Gas used</Skeleton>
<Skeleton isLoaded={ !props.isLoading } variant="secondary">{ BigNumber(props.gas_used || 0).toFormat() }</Skeleton>
<Utilization
colorScheme="gray"
value={ BigNumber(props.gas_used || 0).dividedBy(BigNumber(props.gas_limit)).toNumber() }
isLoading={ props.isLoading }
/>
</Flex>
<Flex columnGap={ 2 } w="100%">
<Text fontWeight={ 500 } flexShrink={ 0 }>Reward { appConfig.network.currency.symbol }</Text>
<Text variant="secondary">{ totalReward.toFixed() }</Text>
<Skeleton isLoaded={ !props.isLoading } fontWeight={ 500 } flexShrink={ 0 }>Reward { appConfig.network.currency.symbol }</Skeleton>
<Skeleton isLoaded={ !props.isLoading } variant="secondary">{ totalReward.toFixed() }</Skeleton>
</Flex>
</ListItemMobile>
);
......
import { Td, Tr, Text, Box, Flex } from '@chakra-ui/react';
import { Td, Tr, Flex, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
......@@ -12,6 +12,7 @@ import Utilization from 'ui/shared/Utilization/Utilization';
type Props = Block & {
page: number;
isLoading: boolean;
};
const AddressBlocksValidatedTableItem = (props: Props) => {
......@@ -22,22 +23,36 @@ const AddressBlocksValidatedTableItem = (props: Props) => {
return (
<Tr>
<Td>
<LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
<Skeleton isLoaded={ !props.isLoading } display="inline-block">
<LinkInternal href={ blockUrl } fontWeight="700">{ props.height }</LinkInternal>
</Skeleton>
</Td>
<Td>
<Text variant="secondary">{ timeAgo }</Text>
<Skeleton isLoaded={ !props.isLoading } color="text_secondary" display="inline-block">
<span>{ timeAgo }</span>
</Skeleton>
</Td>
<Td>
<Text fontWeight="500">{ props.tx_count }</Text>
<Skeleton isLoaded={ !props.isLoading } display="inline-block" fontWeight="500">
<span>{ props.tx_count }</span>
</Skeleton>
</Td>
<Td>
<Flex alignItems="center" columnGap={ 2 }>
<Box flexBasis="80px">{ BigNumber(props.gas_used || 0).toFormat() }</Box>
<Utilization colorScheme="gray" value={ BigNumber(props.gas_used || 0).dividedBy(BigNumber(props.gas_limit)).toNumber() }/>
<Skeleton isLoaded={ !props.isLoading } flexBasis="80px">
{ BigNumber(props.gas_used || 0).toFormat() }
</Skeleton>
<Utilization
colorScheme="gray"
value={ BigNumber(props.gas_used || 0).dividedBy(BigNumber(props.gas_limit)).toNumber() }
isLoading={ props.isLoading }
/>
</Flex>
</Td>
<Td isNumeric display="flex" justifyContent="end">
{ totalReward.toFixed() }
<Skeleton isLoaded={ !props.isLoading } display="inline-block">
<span>{ totalReward.toFixed() }</span>
</Skeleton>
</Td>
</Tr>
);
......
......@@ -193,7 +193,7 @@ const TxDetails = () => {
</Skeleton>
</DetailsInfoItem>
) }
<DetailsSponsoredItem/>
<DetailsSponsoredItem isLoading={ isPlaceholderData }/>
{ divider }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment