Commit e9297935 authored by tom's avatar tom

skeleton for tx details

parent aa64056d
import type { NextPage } from 'next'; import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import Head from 'next/head'; import Head from 'next/head';
import type { RoutedQuery } from 'nextjs-routes'; import type { RoutedQuery } from 'nextjs-routes';
import React from 'react'; import React from 'react';
import getSeo from 'lib/next/tx/getSeo'; import getSeo from 'lib/next/tx/getSeo';
import Transaction from 'ui/pages/Transaction'; import Page from 'ui/shared/Page/Page';
const Transaction = dynamic(() => import('ui/pages/Transaction'), { ssr: false });
const TransactionPage: NextPage<RoutedQuery<'/tx/[hash]'>> = ({ hash }: RoutedQuery<'/tx/[hash]'>) => { const TransactionPage: NextPage<RoutedQuery<'/tx/[hash]'>> = ({ hash }: RoutedQuery<'/tx/[hash]'>) => {
const { title, description } = getSeo({ hash }); const { title, description } = getSeo({ hash });
...@@ -15,7 +18,9 @@ const TransactionPage: NextPage<RoutedQuery<'/tx/[hash]'>> = ({ hash }: RoutedQu ...@@ -15,7 +18,9 @@ const TransactionPage: NextPage<RoutedQuery<'/tx/[hash]'>> = ({ hash }: RoutedQu
<title>{ title }</title> <title>{ title }</title>
<meta name="description" content={ description }/> <meta name="description" content={ description }/>
</Head> </Head>
<Transaction/> <Page>
<Transaction/>
</Page>
</> </>
); );
}; };
......
...@@ -8,9 +8,9 @@ import useApiQuery from 'lib/api/useApiQuery'; ...@@ -8,9 +8,9 @@ import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext'; import { useAppContext } from 'lib/appContext';
import networkExplorers from 'lib/networks/networkExplorers'; import networkExplorers from 'lib/networks/networkExplorers';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import { TX } from 'stubs/tx';
import TextAd from 'ui/shared/ad/TextAd'; import TextAd from 'ui/shared/ad/TextAd';
import LinkExternal from 'ui/shared/LinkExternal'; import LinkExternal from 'ui/shared/LinkExternal';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs'; import RoutedTabs from 'ui/shared/RoutedTabs/RoutedTabs';
import TxDetails from 'ui/tx/TxDetails'; import TxDetails from 'ui/tx/TxDetails';
...@@ -38,7 +38,10 @@ const TransactionPageContent = () => { ...@@ -38,7 +38,10 @@ const TransactionPageContent = () => {
const { data } = useApiQuery('tx', { const { data } = useApiQuery('tx', {
pathParams: { hash }, pathParams: { hash },
queryOptions: { enabled: Boolean(hash) }, queryOptions: {
enabled: Boolean(hash),
placeholderData: TX,
},
}); });
const explorersLinks = networkExplorers const explorersLinks = networkExplorers
...@@ -66,7 +69,7 @@ const TransactionPageContent = () => { ...@@ -66,7 +69,7 @@ const TransactionPageContent = () => {
); );
return ( return (
<Page> <>
<TextAd mb={ 6 }/> <TextAd mb={ 6 }/>
<PageTitle <PageTitle
text="Transaction details" text="Transaction details"
...@@ -75,7 +78,7 @@ const TransactionPageContent = () => { ...@@ -75,7 +78,7 @@ const TransactionPageContent = () => {
backLinkLabel="Back to transactions list" backLinkLabel="Back to transactions list"
/> />
<RoutedTabs tabs={ TABS }/> <RoutedTabs tabs={ TABS }/>
</Page> </>
); );
}; };
......
...@@ -11,6 +11,7 @@ import { ...@@ -11,6 +11,7 @@ import {
Tooltip, Tooltip,
chakra, chakra,
useColorModeValue, useColorModeValue,
Skeleton,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
...@@ -42,14 +43,13 @@ import TextSeparator from 'ui/shared/TextSeparator'; ...@@ -42,14 +43,13 @@ import TextSeparator from 'ui/shared/TextSeparator';
import TxStatus from 'ui/shared/TxStatus'; import TxStatus from 'ui/shared/TxStatus';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
import TxDetailsActions from 'ui/tx/details/TxDetailsActions'; import TxDetailsActions from 'ui/tx/details/TxDetailsActions';
import TxDetailsSkeleton from 'ui/tx/details/TxDetailsSkeleton';
import TxDetailsTokenTransfers from 'ui/tx/details/TxDetailsTokenTransfers'; import TxDetailsTokenTransfers from 'ui/tx/details/TxDetailsTokenTransfers';
import TxRevertReason from 'ui/tx/details/TxRevertReason'; import TxRevertReason from 'ui/tx/details/TxRevertReason';
import TxSocketAlert from 'ui/tx/TxSocketAlert'; import TxSocketAlert from 'ui/tx/TxSocketAlert';
import useFetchTxInfo from 'ui/tx/useFetchTxInfo'; import useFetchTxInfo from 'ui/tx/useFetchTxInfo';
const TxDetails = () => { const TxDetails = () => {
const { data, isLoading, isError, socketStatus, error } = useFetchTxInfo(); const { data, isPlaceholderData, isError, socketStatus, error } = useFetchTxInfo();
const [ isExpanded, setIsExpanded ] = React.useState(false); const [ isExpanded, setIsExpanded ] = React.useState(false);
...@@ -62,10 +62,6 @@ const TxDetails = () => { ...@@ -62,10 +62,6 @@ const TxDetails = () => {
}, []); }, []);
const executionSuccessIconColor = useColorModeValue('blackAlpha.800', 'whiteAlpha.800'); const executionSuccessIconColor = useColorModeValue('blackAlpha.800', 'whiteAlpha.800');
if (isLoading) {
return <TxDetailsSkeleton/>;
}
if (isError) { if (isError) {
if (error?.status === 422) { if (error?.status === 422) {
throw Error('Invalid tx hash', { cause: error as unknown as Error }); throw Error('Invalid tx hash', { cause: error as unknown as Error });
...@@ -78,6 +74,10 @@ const TxDetails = () => { ...@@ -78,6 +74,10 @@ const TxDetails = () => {
return <DataFetchAlert/>; return <DataFetchAlert/>;
} }
if (!data) {
return null;
}
const addressFromTags = [ const addressFromTags = [
...data.from.private_tags || [], ...data.from.private_tags || [],
...data.from.public_tags || [], ...data.from.public_tags || [],
...@@ -129,20 +129,22 @@ const TxDetails = () => { ...@@ -129,20 +129,22 @@ const TxDetails = () => {
title="Transaction hash" title="Transaction hash"
hint="Unique character string (TxID) assigned to every verified transaction" hint="Unique character string (TxID) assigned to every verified transaction"
flexWrap="nowrap" flexWrap="nowrap"
isLoading={ isPlaceholderData }
> >
{ data.status === null && <Spinner mr={ 2 } size="sm" flexShrink={ 0 }/> } { data.status === null && <Spinner mr={ 2 } size="sm" flexShrink={ 0 }/> }
<Box overflow="hidden"> <Skeleton isLoaded={ !isPlaceholderData } overflow="hidden">
<HashStringShortenDynamic hash={ data.hash }/> <HashStringShortenDynamic hash={ data.hash }/>
</Box> </Skeleton>
<CopyToClipboard text={ data.hash }/> <CopyToClipboard text={ data.hash } isLoading={ isPlaceholderData }/>
{ /* api doesn't support navigation between certain address account tx */ } { /* api doesn't support navigation between certain address account tx */ }
{ /* <PrevNext ml={ 7 }/> */ } { /* <PrevNext ml={ 7 }/> */ }
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Status" title="Status"
hint="Current transaction state: Success, Failed (Error), or Pending (In Process)" hint="Current transaction state: Success, Failed (Error), or Pending (In Process)"
isLoading={ isPlaceholderData }
> >
<TxStatus status={ data.status } errorText={ data.status === 'error' ? data.result : undefined }/> <TxStatus status={ data.status } errorText={ data.status === 'error' ? data.result : undefined } isLoading={ isPlaceholderData }/>
</DetailsInfoItem> </DetailsInfoItem>
{ data.revert_reason && ( { data.revert_reason && (
<DetailsInfoItem <DetailsInfoItem
...@@ -155,16 +157,22 @@ const TxDetails = () => { ...@@ -155,16 +157,22 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Block" title="Block"
hint="Block number containing the transaction" hint="Block number containing the transaction"
isLoading={ isPlaceholderData }
> >
{ data.block === null ? { data.block === null ?
<Text>Pending</Text> : <Text>Pending</Text> : (
<LinkInternal href={ route({ pathname: '/block/[height]', query: { height: String(data.block) } }) }>{ data.block }</LinkInternal> } <Skeleton isLoaded={ !isPlaceholderData }>
<LinkInternal href={ route({ pathname: '/block/[height]', query: { height: String(data.block) } }) }>
{ data.block }
</LinkInternal>
</Skeleton>
) }
{ Boolean(data.confirmations) && ( { Boolean(data.confirmations) && (
<> <>
<TextSeparator color="gray.500"/> <TextSeparator color="gray.500"/>
<Text variant="secondary"> <Skeleton isLoaded={ !isPlaceholderData } color="text_secondary">
{ data.confirmations } Block confirmations <span>{ data.confirmations } Block confirmations</span>
</Text> </Skeleton>
</> </>
) } ) }
</DetailsInfoItem> </DetailsInfoItem>
...@@ -172,12 +180,18 @@ const TxDetails = () => { ...@@ -172,12 +180,18 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Timestamp" title="Timestamp"
hint="Date & time of transaction inclusion, including length of time for confirmation" hint="Date & time of transaction inclusion, including length of time for confirmation"
isLoading={ isPlaceholderData }
> >
<Icon as={ clockIcon } boxSize={ 5 } color="gray.500"/> <Skeleton isLoaded={ !isPlaceholderData } boxSize={ 5 }>
<Text ml={ 1 }>{ dayjs(data.timestamp).fromNow() }</Text> <Icon as={ clockIcon } boxSize={ 5 } color="gray.500"/>
</Skeleton>
<Skeleton isLoaded={ !isPlaceholderData } ml={ 1 }>{ dayjs(data.timestamp).fromNow() }</Skeleton>
<TextSeparator/> <TextSeparator/>
<Text whiteSpace="normal">{ dayjs(data.timestamp).format('LLLL') }<TextSeparator color="gray.500"/></Text> <Skeleton isLoaded={ !isPlaceholderData } whiteSpace="normal">{ dayjs(data.timestamp).format('LLLL') }</Skeleton>
<Text variant="secondary">{ getConfirmationDuration(data.confirmation_duration) }</Text> <TextSeparator color="gray.500"/>
<Skeleton isLoaded={ !isPlaceholderData } color="text_secondary">
<span>{ getConfirmationDuration(data.confirmation_duration) }</span>
</Skeleton>
</DetailsInfoItem> </DetailsInfoItem>
) } ) }
<DetailsSponsoredItem/> <DetailsSponsoredItem/>
...@@ -194,12 +208,13 @@ const TxDetails = () => { ...@@ -194,12 +208,13 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="From" title="From"
hint="Address (external or contract) sending the transaction" hint="Address (external or contract) sending the transaction"
isLoading={ isPlaceholderData }
columnGap={ 3 } columnGap={ 3 }
> >
<Address> <Address>
<AddressIcon address={ data.from }/> <AddressIcon address={ data.from } isLoading={ isPlaceholderData }/>
<AddressLink type="address" ml={ 2 } hash={ data.from.hash }/> <AddressLink type="address" ml={ 2 } hash={ data.from.hash } isLoading={ isPlaceholderData }/>
<CopyToClipboard text={ data.from.hash }/> <CopyToClipboard text={ data.from.hash } isLoading={ isPlaceholderData }/>
</Address> </Address>
{ data.from.name && <Text>{ data.from.name }</Text> } { data.from.name && <Text>{ data.from.name }</Text> }
{ addressFromTags.length > 0 && ( { addressFromTags.length > 0 && (
...@@ -211,6 +226,7 @@ const TxDetails = () => { ...@@ -211,6 +226,7 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title={ data.to?.is_contract ? 'Interacted with contract' : 'To' } title={ data.to?.is_contract ? 'Interacted with contract' : 'To' }
hint="Address (external or contract) receiving the transaction" hint="Address (external or contract) receiving the transaction"
isLoading={ isPlaceholderData }
flexWrap={{ base: 'wrap', lg: 'nowrap' }} flexWrap={{ base: 'wrap', lg: 'nowrap' }}
columnGap={ 3 } columnGap={ 3 }
> >
...@@ -218,11 +234,11 @@ const TxDetails = () => { ...@@ -218,11 +234,11 @@ const TxDetails = () => {
<> <>
{ data.to && data.to.hash ? ( { data.to && data.to.hash ? (
<Address alignItems="center"> <Address alignItems="center">
<AddressIcon address={ toAddress }/> <AddressIcon address={ toAddress } isLoading={ isPlaceholderData }/>
<AddressLink type="address" ml={ 2 } hash={ toAddress.hash }/> <AddressLink type="address" ml={ 2 } hash={ toAddress.hash } isLoading={ isPlaceholderData }/>
{ executionSuccessBadge } { executionSuccessBadge }
{ executionFailedBadge } { executionFailedBadge }
<CopyToClipboard text={ toAddress.hash }/> <CopyToClipboard text={ toAddress.hash } isLoading={ isPlaceholderData }/>
</Address> </Address>
) : ( ) : (
<Flex width={{ base: '100%', lg: 'auto' }} whiteSpace="pre" alignItems="center"> <Flex width={{ base: '100%', lg: 'auto' }} whiteSpace="pre" alignItems="center">
...@@ -252,48 +268,58 @@ const TxDetails = () => { ...@@ -252,48 +268,58 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="Value" title="Value"
hint="Value sent in the native token (and USD) if applicable" hint="Value sent in the native token (and USD) if applicable"
isLoading={ isPlaceholderData }
> >
<CurrencyValue value={ data.value } currency={ appConfig.network.currency.symbol } exchangeRate={ data.exchange_rate }/> <CurrencyValue value={ data.value } currency={ appConfig.network.currency.symbol } exchangeRate={ data.exchange_rate } isLoading={ isPlaceholderData }/>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Transaction fee" title="Transaction fee"
hint="Total transaction fee" hint="Total transaction fee"
isLoading={ isPlaceholderData }
> >
<CurrencyValue <CurrencyValue
value={ data.fee.value } value={ data.fee.value }
currency={ appConfig.network.currency.symbol } currency={ appConfig.network.currency.symbol }
exchangeRate={ data.exchange_rate } exchangeRate={ data.exchange_rate }
flexWrap="wrap" flexWrap="wrap"
isLoading={ isPlaceholderData }
/> />
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Gas price" title="Gas price"
hint="Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage" hint="Price per unit of gas specified by the sender. Higher gas prices can prioritize transaction inclusion during times of high usage"
isLoading={ isPlaceholderData }
> >
<Text mr={ 1 }>{ BigNumber(data.gas_price).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }</Text> <Skeleton isLoaded={ !isPlaceholderData } mr={ 1 }>
<Text variant="secondary">({ BigNumber(data.gas_price).dividedBy(WEI_IN_GWEI).toFixed() } Gwei)</Text> { BigNumber(data.gas_price).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }
</Skeleton>
<Skeleton isLoaded={ !isPlaceholderData } color="text_secondary">
<span>({ BigNumber(data.gas_price).dividedBy(WEI_IN_GWEI).toFixed() } Gwei)</span>
</Skeleton>
</DetailsInfoItem> </DetailsInfoItem>
<DetailsInfoItem <DetailsInfoItem
title="Gas usage & limit by txn" title="Gas usage & limit by txn"
hint="Actual gas amount used by the transaction" hint="Actual gas amount used by the transaction"
isLoading={ isPlaceholderData }
> >
<Text>{ BigNumber(data.gas_used || 0).toFormat() }</Text> <Skeleton isLoaded={ !isPlaceholderData }>{ BigNumber(data.gas_used || 0).toFormat() }</Skeleton>
<TextSeparator/> <TextSeparator/>
<Text >{ BigNumber(data.gas_limit).toFormat() }</Text> <Skeleton isLoaded={ !isPlaceholderData }>{ BigNumber(data.gas_limit).toFormat() }</Skeleton>
<Utilization ml={ 4 } value={ BigNumber(data.gas_used || 0).dividedBy(BigNumber(data.gas_limit)).toNumber() }/> <Utilization ml={ 4 } value={ BigNumber(data.gas_used || 0).dividedBy(BigNumber(data.gas_limit)).toNumber() } isLoading={ isPlaceholderData }/>
</DetailsInfoItem> </DetailsInfoItem>
{ (data.base_fee_per_gas || data.max_fee_per_gas || data.max_priority_fee_per_gas) && ( { (data.base_fee_per_gas || data.max_fee_per_gas || data.max_priority_fee_per_gas) && (
<DetailsInfoItem <DetailsInfoItem
title="Gas fees (Gwei)" title="Gas fees (Gwei)"
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
hint="Base Fee refers to the network Base Fee at the time of the block, while Max Fee & Max Priority Fee refer to the max amount a user is willing to pay for their tx & to give to the miner respectively" hint="Base Fee refers to the network Base Fee at the time of the block, while Max Fee & Max Priority Fee refer to the max amount a user is willing to pay for their tx & to give to the miner respectively"
isLoading={ isPlaceholderData }
> >
{ data.base_fee_per_gas && ( { data.base_fee_per_gas && (
<Box> <Skeleton isLoaded={ !isPlaceholderData }>
<Text as="span" fontWeight="500">Base: </Text> <Text as="span" fontWeight="500">Base: </Text>
<Text fontWeight="600" as="span">{ BigNumber(data.base_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text> <Text fontWeight="600" as="span">{ BigNumber(data.base_fee_per_gas).dividedBy(WEI_IN_GWEI).toFixed() }</Text>
{ (data.max_fee_per_gas || data.max_priority_fee_per_gas) && <TextSeparator/> } { (data.max_fee_per_gas || data.max_priority_fee_per_gas) && <TextSeparator/> }
</Box> </Skeleton>
) } ) }
{ data.max_fee_per_gas && ( { data.max_fee_per_gas && (
<Box> <Box>
...@@ -330,6 +356,7 @@ const TxDetails = () => { ...@@ -330,6 +356,7 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="L1 gas used by txn" title="L1 gas used by txn"
hint="L1 gas used by transaction" hint="L1 gas used by transaction"
isLoading={ isPlaceholderData }
> >
<Text>{ BigNumber(data.l1_gas_used).toFormat() }</Text> <Text>{ BigNumber(data.l1_gas_used).toFormat() }</Text>
</DetailsInfoItem> </DetailsInfoItem>
...@@ -338,6 +365,7 @@ const TxDetails = () => { ...@@ -338,6 +365,7 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="L1 gas price" title="L1 gas price"
hint="L1 gas price" hint="L1 gas price"
isLoading={ isPlaceholderData }
> >
<Text mr={ 1 }>{ BigNumber(data.l1_gas_price).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }</Text> <Text mr={ 1 }>{ BigNumber(data.l1_gas_price).dividedBy(WEI).toFixed() } { appConfig.network.currency.symbol }</Text>
<Text variant="secondary">({ BigNumber(data.l1_gas_price).dividedBy(WEI_IN_GWEI).toFixed() } Gwei)</Text> <Text variant="secondary">({ BigNumber(data.l1_gas_price).dividedBy(WEI_IN_GWEI).toFixed() } Gwei)</Text>
...@@ -348,6 +376,7 @@ const TxDetails = () => { ...@@ -348,6 +376,7 @@ const TxDetails = () => {
title="L1 fee" title="L1 fee"
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
hint={ `L1 Data Fee which is used to cover the L1 "security" cost from the batch submission mechanism. In combination with L2 execution fee, L1 fee makes the total amount of fees that a transaction pays.` } hint={ `L1 Data Fee which is used to cover the L1 "security" cost from the batch submission mechanism. In combination with L2 execution fee, L1 fee makes the total amount of fees that a transaction pays.` }
isLoading={ isPlaceholderData }
> >
<CurrencyValue <CurrencyValue
value={ data.l1_fee } value={ data.l1_fee }
...@@ -361,6 +390,7 @@ const TxDetails = () => { ...@@ -361,6 +390,7 @@ const TxDetails = () => {
<DetailsInfoItem <DetailsInfoItem
title="L1 fee scalar" title="L1 fee scalar"
hint="A Dynamic overhead (fee scalar) premium, which serves as a buffer in case L1 prices rapidly increase." hint="A Dynamic overhead (fee scalar) premium, which serves as a buffer in case L1 prices rapidly increase."
isLoading={ isPlaceholderData }
> >
<Text>{ data.l1_fee_scalar }</Text> <Text>{ data.l1_fee_scalar }</Text>
</DetailsInfoItem> </DetailsInfoItem>
...@@ -369,16 +399,17 @@ const TxDetails = () => { ...@@ -369,16 +399,17 @@ const TxDetails = () => {
) } ) }
<GridItem colSpan={{ base: undefined, lg: 2 }}> <GridItem colSpan={{ base: undefined, lg: 2 }}>
<Element name="TxDetails__cutLink"> <Element name="TxDetails__cutLink">
<Link <Skeleton isLoaded={ !isPlaceholderData } mt={ 6 } display="inline-block">
mt={ 6 } <Link
display="inline-block" display="inline-block"
fontSize="sm" fontSize="sm"
textDecorationLine="underline" textDecorationLine="underline"
textDecorationStyle="dashed" textDecorationStyle="dashed"
onClick={ handleCutClick } onClick={ handleCutClick }
> >
{ isExpanded ? 'Hide details' : 'View details' } { isExpanded ? 'Hide details' : 'View details' }
</Link> </Link>
</Skeleton>
</Element> </Element>
</GridItem> </GridItem>
{ isExpanded && ( { isExpanded && (
......
import { Grid, GridItem, Skeleton } from '@chakra-ui/react';
import React from 'react';
import DetailsSkeletonRow from 'ui/shared/skeletons/DetailsSkeletonRow';
const TxDetailsSkeleton = () => {
const sectionGap = (
<GridItem
colSpan={{ base: undefined, lg: 2 }}
mt={{ base: 2, lg: 3 }}
mb={{ base: 0, lg: 3 }}
borderBottom="1px solid"
borderColor="divider"
/>
);
return (
<Grid columnGap={ 8 } rowGap={{ base: 5, lg: 7 }} templateColumns={{ base: '1fr', lg: '210px 1fr' }} maxW="1000px" pt={{ base: 1, lg: 2 }}>
<DetailsSkeletonRow/>
<DetailsSkeletonRow w="20%"/>
<DetailsSkeletonRow w="50%"/>
<DetailsSkeletonRow/>
<DetailsSkeletonRow w="70%"/>
<DetailsSkeletonRow w="70%"/>
{ sectionGap }
<DetailsSkeletonRow w="40%"/>
<DetailsSkeletonRow w="40%"/>
<DetailsSkeletonRow w="40%"/>
<DetailsSkeletonRow w="40%"/>
<DetailsSkeletonRow w="40%"/>
{ sectionGap }
<GridItem colSpan={{ base: undefined, lg: 2 }}>
<Skeleton h={ 5 } borderRadius="full" w="100px"/>
</GridItem>
</Grid>
);
};
export default TxDetailsSkeleton;
...@@ -12,6 +12,7 @@ import delay from 'lib/delay'; ...@@ -12,6 +12,7 @@ import delay from 'lib/delay';
import getQueryParamString from 'lib/router/getQueryParamString'; import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage'; import useSocketMessage from 'lib/socket/useSocketMessage';
import { TX } from 'stubs/tx';
interface Params { interface Params {
onTxStatusUpdate?: () => void; onTxStatusUpdate?: () => void;
...@@ -33,6 +34,7 @@ export default function useFetchTxInfo({ onTxStatusUpdate, updateDelay }: Params ...@@ -33,6 +34,7 @@ export default function useFetchTxInfo({ onTxStatusUpdate, updateDelay }: Params
queryOptions: { queryOptions: {
enabled: Boolean(hash), enabled: Boolean(hash),
refetchOnMount: false, refetchOnMount: false,
placeholderData: TX,
}, },
}); });
const { data, isError, isLoading } = queryResult; const { data, isError, isLoading } = queryResult;
......
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