Commit 8a494935 authored by isstuev's avatar isstuev

Add tooltip with full date on "age" fields

parent 0ccd05a8
...@@ -3,11 +3,11 @@ import React, { useMemo } from 'react'; ...@@ -3,11 +3,11 @@ import React, { useMemo } from 'react';
import type { NovesResponseData } from 'types/api/noves'; import type { NovesResponseData } from 'types/api/noves';
import dayjs from 'lib/date/dayjs';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import NovesFromTo from 'ui/shared/Noves/NovesFromTo'; import NovesFromTo from 'ui/shared/Noves/NovesFromTo';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = { type Props = {
isPlaceholderData: boolean; isPlaceholderData: boolean;
...@@ -40,9 +40,12 @@ const AddressAccountHistoryListItem = (props: Props) => { ...@@ -40,9 +40,12 @@ const AddressAccountHistoryListItem = (props: Props) => {
Action Action
</Text> </Text>
</Flex> </Flex>
<Text color="text_secondary" fontSize="sm" fontWeight={ 500 }> <TimeAgoWithTooltip
{ dayjs(props.tx.rawTransactionData.timestamp * 1000).fromNow() } timestamp={ (props.tx.rawTransactionData.timestamp * 1000).toString() }
</Text> color="text_secondary"
borderRadius="sm"
fontWeight={ 500 }
/>
</Flex> </Flex>
</Skeleton> </Skeleton>
<Skeleton borderRadius="sm" isLoaded={ !props.isPlaceholderData }> <Skeleton borderRadius="sm" isLoaded={ !props.isPlaceholderData }>
......
import { Td, Tr, Skeleton, Text, Box } from '@chakra-ui/react'; import { Td, Tr, Skeleton, Box } from '@chakra-ui/react';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import type { NovesResponseData } from 'types/api/noves'; import type { NovesResponseData } from 'types/api/noves';
import dayjs from 'lib/date/dayjs';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import NovesFromTo from 'ui/shared/Noves/NovesFromTo'; import NovesFromTo from 'ui/shared/Noves/NovesFromTo';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = { type Props = {
isPlaceholderData: boolean; isPlaceholderData: boolean;
...@@ -25,11 +25,13 @@ const AddressAccountHistoryTableItem = (props: Props) => { ...@@ -25,11 +25,13 @@ const AddressAccountHistoryTableItem = (props: Props) => {
return ( return (
<Tr> <Tr>
<Td px={ 3 } py="18px" fontSize="sm" > <Td px={ 3 } py="18px" fontSize="sm" >
<Skeleton borderRadius="sm" flexShrink={ 0 } isLoaded={ !props.isPlaceholderData }> <TimeAgoWithTooltip
<Text as="span" color="text_secondary"> timestamp={ (props.tx.rawTransactionData.timestamp * 1000).toString() }
{ dayjs(props.tx.rawTransactionData.timestamp * 1000).fromNow() } isLoading={ props.isPlaceholderData }
</Text> color="text_secondary"
</Skeleton> borderRadius="sm"
flexShrink={ 0 }
/>
</Td> </Td>
<Td px={ 3 } py="18px" fontSize="sm" > <Td px={ 3 } py="18px" fontSize="sm" >
<Skeleton borderRadius="sm" isLoaded={ !props.isPlaceholderData }> <Skeleton borderRadius="sm" isLoaded={ !props.isPlaceholderData }>
......
...@@ -6,11 +6,11 @@ import type { Block } from 'types/api/block'; ...@@ -6,11 +6,11 @@ import type { Block } from 'types/api/block';
import config from 'configs/app'; import config from 'configs/app';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import BlockGasUsed from 'ui/shared/block/BlockGasUsed'; import BlockGasUsed from 'ui/shared/block/BlockGasUsed';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = Block & { type Props = Block & {
page: number; page: number;
...@@ -18,7 +18,6 @@ type Props = Block & { ...@@ -18,7 +18,6 @@ type Props = Block & {
}; };
const AddressBlocksValidatedListItem = (props: Props) => { const AddressBlocksValidatedListItem = (props: Props) => {
const timeAgo = useTimeAgoIncrement(props.timestamp, props.page === 1);
const totalReward = getBlockTotalReward(props); const totalReward = getBlockTotalReward(props);
return ( return (
...@@ -30,9 +29,13 @@ const AddressBlocksValidatedListItem = (props: Props) => { ...@@ -30,9 +29,13 @@ const AddressBlocksValidatedListItem = (props: Props) => {
noIcon noIcon
fontWeight={ 700 } fontWeight={ 700 }
/> />
<Skeleton isLoaded={ !props.isLoading } color="text_secondary" display="inline-block"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ props.timestamp }
</Skeleton> enableIncrement={ props.page === 1 }
isLoading={ props.isLoading }
color="text_secondary"
display="inline-block"
/>
</Flex> </Flex>
<Flex columnGap={ 2 } w="100%"> <Flex columnGap={ 2 } w="100%">
<Skeleton isLoaded={ !props.isLoading } fontWeight={ 500 } flexShrink={ 0 }>Txn</Skeleton> <Skeleton isLoaded={ !props.isLoading } fontWeight={ 500 } flexShrink={ 0 }>Txn</Skeleton>
......
...@@ -6,9 +6,9 @@ import type { Block } from 'types/api/block'; ...@@ -6,9 +6,9 @@ import type { Block } from 'types/api/block';
import config from 'configs/app'; import config from 'configs/app';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import BlockGasUsed from 'ui/shared/block/BlockGasUsed'; import BlockGasUsed from 'ui/shared/block/BlockGasUsed';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = Block & { type Props = Block & {
page: number; page: number;
...@@ -16,7 +16,6 @@ type Props = Block & { ...@@ -16,7 +16,6 @@ type Props = Block & {
}; };
const AddressBlocksValidatedTableItem = (props: Props) => { const AddressBlocksValidatedTableItem = (props: Props) => {
const timeAgo = useTimeAgoIncrement(props.timestamp, props.page === 1);
const totalReward = getBlockTotalReward(props); const totalReward = getBlockTotalReward(props);
return ( return (
...@@ -32,9 +31,13 @@ const AddressBlocksValidatedTableItem = (props: Props) => { ...@@ -32,9 +31,13 @@ const AddressBlocksValidatedTableItem = (props: Props) => {
/> />
</Td> </Td>
<Td> <Td>
<Skeleton isLoaded={ !props.isLoading } color="text_secondary" display="inline-block"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ props.timestamp }
</Skeleton> enableIncrement={ props.page === 1 }
isLoading={ props.isLoading }
color="text_secondary"
display="inline-block"
/>
</Td> </Td>
<Td> <Td>
<Skeleton isLoaded={ !props.isLoading } display="inline-block" fontWeight="500"> <Skeleton isLoaded={ !props.isLoading } display="inline-block" fontWeight="500">
......
...@@ -5,11 +5,11 @@ import React from 'react'; ...@@ -5,11 +5,11 @@ import React from 'react';
import type { AddressCoinBalanceHistoryItem } from 'types/api/address'; import type { AddressCoinBalanceHistoryItem } from 'types/api/address';
import { WEI, ZERO } from 'lib/consts'; import { WEI, ZERO } from 'lib/consts';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = AddressCoinBalanceHistoryItem & { type Props = AddressCoinBalanceHistoryItem & {
page: number; page: number;
...@@ -19,7 +19,6 @@ type Props = AddressCoinBalanceHistoryItem & { ...@@ -19,7 +19,6 @@ type Props = AddressCoinBalanceHistoryItem & {
const AddressCoinBalanceListItem = (props: Props) => { const AddressCoinBalanceListItem = (props: Props) => {
const deltaBn = BigNumber(props.delta).div(WEI); const deltaBn = BigNumber(props.delta).div(WEI);
const isPositiveDelta = deltaBn.gte(ZERO); const isPositiveDelta = deltaBn.gte(ZERO);
const timeAgo = useTimeAgoIncrement(props.block_timestamp, props.page === 1);
return ( return (
<ListItemMobile rowGap={ 2 } isAnimated> <ListItemMobile rowGap={ 2 } isAnimated>
...@@ -61,7 +60,12 @@ const AddressCoinBalanceListItem = (props: Props) => { ...@@ -61,7 +60,12 @@ const AddressCoinBalanceListItem = (props: Props) => {
) } ) }
<Flex columnGap={ 2 } w="100%"> <Flex columnGap={ 2 } w="100%">
<Skeleton isLoaded={ !props.isLoading } fontWeight={ 500 } flexShrink={ 0 }>Age</Skeleton> <Skeleton isLoaded={ !props.isLoading } fontWeight={ 500 } flexShrink={ 0 }>Age</Skeleton>
<Skeleton isLoaded={ !props.isLoading } color="text_secondary"><span>{ timeAgo }</span></Skeleton> <TimeAgoWithTooltip
timestamp={ props.block_timestamp }
enableIncrement={ props.page === 1 }
isLoading={ props.isLoading }
color="text_secondary"
/>
</Flex> </Flex>
</ListItemMobile> </ListItemMobile>
); );
......
...@@ -5,9 +5,9 @@ import React from 'react'; ...@@ -5,9 +5,9 @@ import React from 'react';
import type { AddressCoinBalanceHistoryItem } from 'types/api/address'; import type { AddressCoinBalanceHistoryItem } from 'types/api/address';
import { WEI, ZERO } from 'lib/consts'; import { WEI, ZERO } from 'lib/consts';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = AddressCoinBalanceHistoryItem & { type Props = AddressCoinBalanceHistoryItem & {
page: number; page: number;
...@@ -17,7 +17,6 @@ type Props = AddressCoinBalanceHistoryItem & { ...@@ -17,7 +17,6 @@ type Props = AddressCoinBalanceHistoryItem & {
const AddressCoinBalanceTableItem = (props: Props) => { const AddressCoinBalanceTableItem = (props: Props) => {
const deltaBn = BigNumber(props.delta).div(WEI); const deltaBn = BigNumber(props.delta).div(WEI);
const isPositiveDelta = deltaBn.gte(ZERO); const isPositiveDelta = deltaBn.gte(ZERO);
const timeAgo = useTimeAgoIncrement(props.block_timestamp, props.page === 1);
return ( return (
<Tr> <Tr>
...@@ -43,9 +42,13 @@ const AddressCoinBalanceTableItem = (props: Props) => { ...@@ -43,9 +42,13 @@ const AddressCoinBalanceTableItem = (props: Props) => {
) } ) }
</Td> </Td>
<Td> <Td>
<Skeleton isLoaded={ !props.isLoading } color="text_secondary" display="inline-block"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ props.block_timestamp }
</Skeleton> enableIncrement={ props.page === 1 }
isLoading={ props.isLoading }
color="text_secondary"
display="inline-block"
/>
</Td> </Td>
<Td isNumeric pr={ 1 }> <Td isNumeric pr={ 1 }>
<Skeleton isLoaded={ !props.isLoading } color="text_secondary" display="inline-block"> <Skeleton isLoaded={ !props.isLoading } color="text_secondary" display="inline-block">
......
...@@ -5,7 +5,6 @@ import React from 'react'; ...@@ -5,7 +5,6 @@ import React from 'react';
import type { InternalTransaction } from 'types/api/internalTransaction'; import type { InternalTransaction } from 'types/api/internalTransaction';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
...@@ -13,6 +12,7 @@ import BlockEntity from 'ui/shared/entities/block/BlockEntity'; ...@@ -13,6 +12,7 @@ import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TxStatus from 'ui/shared/statusTag/TxStatus'; import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils'; import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
type Props = InternalTransaction & { currentAddress: string; isLoading?: boolean }; type Props = InternalTransaction & { currentAddress: string; isLoading?: boolean };
...@@ -47,9 +47,13 @@ const TxInternalsListItem = ({ ...@@ -47,9 +47,13 @@ const TxInternalsListItem = ({
fontWeight={ 700 } fontWeight={ 700 }
truncation="constant_long" truncation="constant_long"
/> />
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" fontSize="sm"> <TimeAgoWithTooltip
<span>{ dayjs(timestamp).fromNow() }</span> timestamp={ timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
fontWeight="400"
fontSize="sm"
/>
</Flex> </Flex>
<HStack spacing={ 1 }> <HStack spacing={ 1 }>
<Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Block</Skeleton> <Skeleton isLoaded={ !isLoading } fontSize="sm" fontWeight={ 500 }>Block</Skeleton>
......
...@@ -5,12 +5,12 @@ import React from 'react'; ...@@ -5,12 +5,12 @@ import React from 'react';
import type { InternalTransaction } from 'types/api/internalTransaction'; import type { InternalTransaction } from 'types/api/internalTransaction';
import config from 'configs/app'; import config from 'configs/app';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxStatus from 'ui/shared/statusTag/TxStatus'; import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils'; import { TX_INTERNALS_ITEMS } from 'ui/tx/internals/utils';
type Props = InternalTransaction & { currentAddress: string; isLoading?: boolean } type Props = InternalTransaction & { currentAddress: string; isLoading?: boolean }
...@@ -32,8 +32,6 @@ const AddressIntTxsTableItem = ({ ...@@ -32,8 +32,6 @@ const AddressIntTxsTableItem = ({
const typeTitle = TX_INTERNALS_ITEMS.find(({ id }) => id === type)?.title; const typeTitle = TX_INTERNALS_ITEMS.find(({ id }) => id === type)?.title;
const toData = to ? to : createdContract; const toData = to ? to : createdContract;
const timeAgo = useTimeAgoIncrement(timestamp, true);
return ( return (
<Tr alignItems="top"> <Tr alignItems="top">
<Td verticalAlign="middle"> <Td verticalAlign="middle">
...@@ -45,11 +43,14 @@ const AddressIntTxsTableItem = ({ ...@@ -45,11 +43,14 @@ const AddressIntTxsTableItem = ({
noIcon noIcon
truncation="constant_long" truncation="constant_long"
/> />
{ timestamp && ( <TimeAgoWithTooltip
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" fontSize="sm"> timestamp={ timestamp }
<span>{ timeAgo }</span> enableIncrement
</Skeleton> isLoading={ isLoading }
) } color="text_secondary"
fontWeight="400"
fontSize="sm"
/>
</Flex> </Flex>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
......
import { Skeleton, chakra } from '@chakra-ui/react';
import React from 'react';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
interface Props {
ts: string;
isEnabled?: boolean;
isLoading?: boolean;
className?: string;
}
const BlockTimestamp = ({ ts, isEnabled, isLoading, className }: Props) => {
const timeAgo = useTimeAgoIncrement(ts, isEnabled);
return (
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight={ 400 } className={ className } display="inline-block">
<span>{ timeAgo }</span>
</Skeleton>
);
};
export default React.memo(chakra(BlockTimestamp));
...@@ -12,13 +12,13 @@ import getBlockTotalReward from 'lib/block/getBlockTotalReward'; ...@@ -12,13 +12,13 @@ import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import { WEI } from 'lib/consts'; import { WEI } from 'lib/consts';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import BlockGasUsed from 'ui/shared/block/BlockGasUsed'; import BlockGasUsed from 'ui/shared/block/BlockGasUsed';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
interface Props { interface Props {
...@@ -46,7 +46,14 @@ const BlocksListItem = ({ data, isLoading, enableTimeIncrement }: Props) => { ...@@ -46,7 +46,14 @@ const BlocksListItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
fontWeight={ 600 } fontWeight={ 600 }
/> />
</Flex> </Flex>
<BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement } isLoading={ isLoading }/> <TimeAgoWithTooltip
timestamp={ data.timestamp }
enableIncrement={ enableTimeIncrement }
isLoading={ isLoading }
color="text_secondary"
fontWeight={ 400 }
display="inline-block"
/>
</Flex> </Flex>
<Flex columnGap={ 2 }> <Flex columnGap={ 2 }>
<Text fontWeight={ 500 }>Size</Text> <Text fontWeight={ 500 }>Size</Text>
......
...@@ -10,12 +10,12 @@ import { route } from 'nextjs-routes'; ...@@ -10,12 +10,12 @@ import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import { WEI } from 'lib/consts'; import { WEI } from 'lib/consts';
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import BlockGasUsed from 'ui/shared/block/BlockGasUsed'; import BlockGasUsed from 'ui/shared/block/BlockGasUsed';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import Utilization from 'ui/shared/Utilization/Utilization'; import Utilization from 'ui/shared/Utilization/Utilization';
interface Props { interface Props {
...@@ -56,7 +56,14 @@ const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => { ...@@ -56,7 +56,14 @@ const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
/> />
</Tooltip> </Tooltip>
</Flex> </Flex>
<BlockTimestamp ts={ data.timestamp } isEnabled={ enableTimeIncrement } isLoading={ isLoading }/> <TimeAgoWithTooltip
timestamp={ data.timestamp }
enableIncrement={ enableTimeIncrement }
isLoading={ isLoading }
color="text_secondary"
fontWeight={ 400 }
display="inline-block"
/>
</Td> </Td>
<Td fontSize="sm"> <Td fontSize="sm">
<Skeleton isLoaded={ !isLoading } display="inline-block"> <Skeleton isLoaded={ !isLoading } display="inline-block">
......
...@@ -5,20 +5,18 @@ import React from 'react'; ...@@ -5,20 +5,18 @@ import React from 'react';
import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2'; import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressEntityL1 from 'ui/shared/entities/address/AddressEntityL1'; import AddressEntityL1 from 'ui/shared/entities/address/AddressEntityL1';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2DepositsItem; isLoading?: boolean }; type Props = { item: OptimisticL2DepositsItem; isLoading?: boolean };
const OptimisticDepositsListItem = ({ item, isLoading }: Props) => { const OptimisticDepositsListItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
return null; return null;
} }
...@@ -50,7 +48,11 @@ const OptimisticDepositsListItem = ({ item, isLoading }: Props) => { ...@@ -50,7 +48,11 @@ const OptimisticDepositsListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.l1_block_timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label>
......
...@@ -5,18 +5,17 @@ import React from 'react'; ...@@ -5,18 +5,17 @@ import React from 'react';
import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2'; import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressEntityL1 from 'ui/shared/entities/address/AddressEntityL1'; import AddressEntityL1 from 'ui/shared/entities/address/AddressEntityL1';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2DepositsItem; isLoading?: boolean }; type Props = { item: OptimisticL2DepositsItem; isLoading?: boolean };
const OptimisticDepositsTableItem = ({ item, isLoading }: Props) => { const OptimisticDepositsTableItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
return null; return null;
...@@ -45,7 +44,12 @@ const OptimisticDepositsTableItem = ({ item, isLoading }: Props) => { ...@@ -45,7 +44,12 @@ const OptimisticDepositsTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"><span>{ timeAgo }</span></Skeleton> <TimeAgoWithTooltip
timestamp={ item.l1_block_timestamp }
isLoading={ isLoading }
color="text_secondary"
display="inline-block"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<TxEntityL1 <TxEntityL1
......
import { Skeleton } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { ShibariumDepositsItem } from 'types/api/shibarium'; import type { ShibariumDepositsItem } from 'types/api/shibarium';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const feature = config.features.rollup; const feature = config.features.rollup;
type Props = { item: ShibariumDepositsItem; isLoading?: boolean }; type Props = { item: ShibariumDepositsItem; isLoading?: boolean };
const DepositsListItem = ({ item, isLoading }: Props) => { const DepositsListItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.timestamp).fromNow();
if (!(feature.isEnabled && feature.type === 'shibarium')) { if (!(feature.isEnabled && feature.type === 'shibarium')) {
return null; return null;
} }
...@@ -70,7 +67,11 @@ const DepositsListItem = ({ item, isLoading }: Props) => { ...@@ -70,7 +67,11 @@ const DepositsListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
</ListItemMobileGrid.Container> </ListItemMobileGrid.Container>
......
import { Td, Tr, Skeleton } from '@chakra-ui/react'; import { Td, Tr } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { ShibariumDepositsItem } from 'types/api/shibarium'; import type { ShibariumDepositsItem } from 'types/api/shibarium';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const feature = config.features.rollup; const feature = config.features.rollup;
type Props = { item: ShibariumDepositsItem; isLoading?: boolean }; type Props = { item: ShibariumDepositsItem; isLoading?: boolean };
const DepositsTableItem = ({ item, isLoading }: Props) => { const DepositsTableItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.timestamp).fromNow();
if (!(feature.isEnabled && feature.type === 'shibarium')) { if (!(feature.isEnabled && feature.type === 'shibarium')) {
return null; return null;
...@@ -59,7 +58,12 @@ const DepositsTableItem = ({ item, isLoading }: Props) => { ...@@ -59,7 +58,12 @@ const DepositsTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"><span>{ timeAgo }</span></Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
color="text_secondary"
display="inline-block"
/>
</Td> </Td>
</Tr> </Tr>
); );
......
...@@ -5,11 +5,11 @@ import React from 'react'; ...@@ -5,11 +5,11 @@ import React from 'react';
import type { ZkEvmL2DepositsItem } from 'types/api/zkEvmL2'; import type { ZkEvmL2DepositsItem } from 'types/api/zkEvmL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
...@@ -20,8 +20,6 @@ const ZkEvmL2DepositsListItem = ({ item, isLoading }: Props) => { ...@@ -20,8 +20,6 @@ const ZkEvmL2DepositsListItem = ({ item, isLoading }: Props) => {
return null; return null;
} }
const timeAgo = dayjs(item.timestamp).fromNow();
return ( return (
<ListItemMobileGrid.Container> <ListItemMobileGrid.Container>
...@@ -56,7 +54,11 @@ const ZkEvmL2DepositsListItem = ({ item, isLoading }: Props) => { ...@@ -56,7 +54,11 @@ const ZkEvmL2DepositsListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L2 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L2 txn hash</ListItemMobileGrid.Label>
......
...@@ -5,10 +5,10 @@ import React from 'react'; ...@@ -5,10 +5,10 @@ import React from 'react';
import type { ZkEvmL2DepositsItem } from 'types/api/zkEvmL2'; import type { ZkEvmL2DepositsItem } from 'types/api/zkEvmL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
...@@ -19,8 +19,6 @@ const ZkEvmL2DepositsTableItem = ({ item, isLoading }: Props) => { ...@@ -19,8 +19,6 @@ const ZkEvmL2DepositsTableItem = ({ item, isLoading }: Props) => {
return null; return null;
} }
const timeAgo = dayjs(item.timestamp).fromNow();
return ( return (
<Tr> <Tr>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
...@@ -49,9 +47,11 @@ const ZkEvmL2DepositsTableItem = ({ item, isLoading }: Props) => { ...@@ -49,9 +47,11 @@ const ZkEvmL2DepositsTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ item.l2_transaction_hash ? ( { item.l2_transaction_hash ? (
......
...@@ -4,11 +4,11 @@ import React from 'react'; ...@@ -4,11 +4,11 @@ import React from 'react';
import type { OptimisticL2DisputeGamesItem } from 'types/api/optimisticL2'; import type { OptimisticL2DisputeGamesItem } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2'; import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
...@@ -53,7 +53,11 @@ const OptimisticL2DisputeGamesListItem = ({ item, isLoading }: Props) => { ...@@ -53,7 +53,11 @@ const OptimisticL2DisputeGamesListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ dayjs(item.created_at).fromNow() }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.created_at }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Status</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Status</ListItemMobileGrid.Label>
...@@ -64,7 +68,11 @@ const OptimisticL2DisputeGamesListItem = ({ item, isLoading }: Props) => { ...@@ -64,7 +68,11 @@ const OptimisticL2DisputeGamesListItem = ({ item, isLoading }: Props) => {
{ item.resolved_at && ( { item.resolved_at && (
<> <>
<ListItemMobileGrid.Label isLoading={ isLoading }>Resolution age</ListItemMobileGrid.Label><ListItemMobileGrid.Value> <ListItemMobileGrid.Label isLoading={ isLoading }>Resolution age</ListItemMobileGrid.Label><ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ dayjs(item.resolved_at).fromNow() }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.resolved_at }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
</> </>
) } ) }
......
...@@ -4,10 +4,10 @@ import React from 'react'; ...@@ -4,10 +4,10 @@ import React from 'react';
import type { OptimisticL2DisputeGamesItem } from 'types/api/optimisticL2'; import type { OptimisticL2DisputeGamesItem } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2'; import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const faultProofSystemFeature = config.features.faultProofSystem; const faultProofSystemFeature = config.features.faultProofSystem;
...@@ -44,15 +44,22 @@ const OptimisticL2DisputeGamesTableItem = ({ item, isLoading }: Props) => { ...@@ -44,15 +44,22 @@ const OptimisticL2DisputeGamesTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } display="inline-block">{ dayjs(item.created_at).fromNow() }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.created_at }
isLoading={ isLoading }
display="inline-block"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } display="inline-block">{ item.status }</Skeleton> <Skeleton isLoaded={ !isLoading } display="inline-block">{ item.status }</Skeleton>
</Td> </Td>
<Td> <Td>
<Skeleton isLoaded={ !isLoading } display="inline-block"> <TimeAgoWithTooltip
{ item.resolved_at ? dayjs(item.resolved_at).fromNow() : 'N/A' } timestamp={ item.resolved_at }
</Skeleton> fallbackText="N/A"
isLoading={ isLoading }
display="inline-block"
/>
</Td> </Td>
</Tr> </Tr>
); );
......
...@@ -12,9 +12,9 @@ import type { Block } from 'types/api/block'; ...@@ -12,9 +12,9 @@ import type { Block } from 'types/api/block';
import config from 'configs/app'; import config from 'configs/app';
import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = { type Props = {
block: Block; block: Block;
...@@ -46,10 +46,13 @@ const LatestBlocksItem = ({ block, isLoading }: Props) => { ...@@ -46,10 +46,13 @@ const LatestBlocksItem = ({ block, isLoading }: Props) => {
fontWeight={ 500 } fontWeight={ 500 }
mr="auto" mr="auto"
/> />
<BlockTimestamp <TimeAgoWithTooltip
ts={ block.timestamp } timestamp={ block.timestamp }
isEnabled={ !isLoading } enableIncrement={ !isLoading }
isLoading={ isLoading } isLoading={ isLoading }
color="text_secondary"
fontWeight={ 400 }
display="inline-block"
fontSize="sm" fontSize="sm"
flexShrink={ 0 } flexShrink={ 0 }
ml={ 2 } ml={ 2 }
......
...@@ -9,11 +9,11 @@ import React from 'react'; ...@@ -9,11 +9,11 @@ import React from 'react';
import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2'; import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const feature = config.features.rollup; const feature = config.features.rollup;
...@@ -23,7 +23,6 @@ type Props = { ...@@ -23,7 +23,6 @@ type Props = {
} }
const LatestDepositsItem = ({ item, isLoading }: Props) => { const LatestDepositsItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
if (!feature.isEnabled || feature.type !== 'optimistic') { if (!feature.isEnabled || feature.type !== 'optimistic') {
...@@ -66,9 +65,11 @@ const LatestDepositsItem = ({ item, isLoading }: Props) => { ...@@ -66,9 +65,11 @@ const LatestDepositsItem = ({ item, isLoading }: Props) => {
<> <>
<Flex justifyContent="space-between" alignItems="center" mb={ 1 }> <Flex justifyContent="space-between" alignItems="center" mb={ 1 }>
{ l1BlockLink } { l1BlockLink }
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.l1_block_timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
/>
</Flex> </Flex>
<Grid gridTemplateColumns="56px auto"> <Grid gridTemplateColumns="56px auto">
<Skeleton isLoaded={ !isLoading } my="5px" w="fit-content"> <Skeleton isLoaded={ !isLoading } my="5px" w="fit-content">
...@@ -91,9 +92,14 @@ const LatestDepositsItem = ({ item, isLoading }: Props) => { ...@@ -91,9 +92,14 @@ const LatestDepositsItem = ({ item, isLoading }: Props) => {
L1 txn L1 txn
</Skeleton> </Skeleton>
{ l1TxLink } { l1TxLink }
<Skeleton isLoaded={ !isLoading } color="text_secondary" w="fit-content" h="fit-content" my="2px"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.l1_block_timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
w="fit-content"
h="fit-content"
my="2px"
/>
<Skeleton isLoaded={ !isLoading } w="fit-content" h="fit-content" my="2px"> <Skeleton isLoaded={ !isLoading } w="fit-content" h="fit-content" my="2px">
L2 txn L2 txn
</Skeleton> </Skeleton>
......
...@@ -12,11 +12,11 @@ import type { Transaction } from 'types/api/transaction'; ...@@ -12,11 +12,11 @@ import type { Transaction } from 'types/api/transaction';
import config from 'configs/app'; import config from 'configs/app';
import getValueWithUnit from 'lib/getValueWithUnit'; import getValueWithUnit from 'lib/getValueWithUnit';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxStatus from 'ui/shared/statusTag/TxStatus'; import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import TxFee from 'ui/shared/tx/TxFee'; import TxFee from 'ui/shared/tx/TxFee';
import TxWatchListTags from 'ui/shared/tx/TxWatchListTags'; import TxWatchListTags from 'ui/shared/tx/TxWatchListTags';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -29,7 +29,6 @@ type Props = { ...@@ -29,7 +29,6 @@ type Props = {
const LatestTxsItem = ({ tx, isLoading }: Props) => { const LatestTxsItem = ({ tx, isLoading }: Props) => {
const dataTo = tx.to ? tx.to : tx.created_contract; const dataTo = tx.to ? tx.to : tx.created_contract;
const timeAgo = useTimeAgoIncrement(tx.timestamp || '0', true);
const columnNum = config.UI.views.tx.hiddenFields?.value && config.UI.views.tx.hiddenFields?.tx_fee ? 2 : 3; const columnNum = config.UI.views.tx.hiddenFields?.value && config.UI.views.tx.hiddenFields?.tx_fee ? 2 : 3;
return ( return (
...@@ -65,18 +64,16 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => { ...@@ -65,18 +64,16 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
hash={ tx.hash } hash={ tx.hash }
fontWeight="700" fontWeight="700"
/> />
{ tx.timestamp && ( <TimeAgoWithTooltip
<Skeleton timestamp={ tx.timestamp }
isLoaded={ !isLoading } enableIncrement
color="text_secondary" isLoading={ isLoading }
fontWeight="400" color="text_secondary"
fontSize="sm" fontWeight="400"
flexShrink={ 0 } fontSize="sm"
ml={ 2 } flexShrink={ 0 }
> ml={ 2 }
<span>{ timeAgo }</span> />
</Skeleton>
) }
</Flex> </Flex>
</Box> </Box>
</Flex> </Flex>
......
...@@ -11,11 +11,11 @@ import type { Transaction } from 'types/api/transaction'; ...@@ -11,11 +11,11 @@ import type { Transaction } from 'types/api/transaction';
import config from 'configs/app'; import config from 'configs/app';
import getValueWithUnit from 'lib/getValueWithUnit'; import getValueWithUnit from 'lib/getValueWithUnit';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxStatus from 'ui/shared/statusTag/TxStatus'; import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import TxFee from 'ui/shared/tx/TxFee'; import TxFee from 'ui/shared/tx/TxFee';
import TxWatchListTags from 'ui/shared/tx/TxWatchListTags'; import TxWatchListTags from 'ui/shared/tx/TxWatchListTags';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -28,7 +28,6 @@ type Props = { ...@@ -28,7 +28,6 @@ type Props = {
const LatestTxsItem = ({ tx, isLoading }: Props) => { const LatestTxsItem = ({ tx, isLoading }: Props) => {
const dataTo = tx.to ? tx.to : tx.created_contract; const dataTo = tx.to ? tx.to : tx.created_contract;
const timeAgo = useTimeAgoIncrement(tx.timestamp || '0', true);
return ( return (
<Box <Box
...@@ -60,11 +59,15 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => { ...@@ -60,11 +59,15 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => {
fontWeight="700" fontWeight="700"
truncation="constant_long" truncation="constant_long"
/> />
{ tx.timestamp && ( <TimeAgoWithTooltip
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" fontSize="sm" ml={ 3 }> timestamp={ tx.timestamp }
<span>{ timeAgo }</span> enableIncrement
</Skeleton> isLoading={ isLoading }
) } color="text_secondary"
fontWeight="400"
fontSize="sm"
ml={ 3 }
/>
</Flex> </Flex>
<AddressFromTo <AddressFromTo
from={ tx.from } from={ tx.from }
......
...@@ -10,10 +10,10 @@ import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2'; ...@@ -10,10 +10,10 @@ import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus'; import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = { type Props = {
batch: ZkEvmL2TxnBatchesItem; batch: ZkEvmL2TxnBatchesItem;
...@@ -44,10 +44,13 @@ const LatestZkevmL2BatchItem = ({ batch, isLoading }: Props) => { ...@@ -44,10 +44,13 @@ const LatestZkevmL2BatchItem = ({ batch, isLoading }: Props) => {
fontWeight={ 500 } fontWeight={ 500 }
mr="auto" mr="auto"
/> />
<BlockTimestamp <TimeAgoWithTooltip
ts={ batch.timestamp } timestamp={ batch.timestamp }
isEnabled={ !isLoading } enableIncrement={ !isLoading }
isLoading={ isLoading } isLoading={ isLoading }
color="text_secondary"
fontWeight={ 400 }
display="inline-block"
fontSize="sm" fontSize="sm"
flexShrink={ 0 } flexShrink={ 0 }
ml={ 2 } ml={ 2 }
......
...@@ -4,13 +4,13 @@ import React from 'react'; ...@@ -4,13 +4,13 @@ import React from 'react';
import type { ArbitrumL2MessagesItem } from 'types/api/arbitrumL2'; import type { ArbitrumL2MessagesItem } from 'types/api/arbitrumL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import ArbitrumL2MessageStatus from 'ui/shared/statusTag/ArbitrumL2MessageStatus'; import ArbitrumL2MessageStatus from 'ui/shared/statusTag/ArbitrumL2MessageStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import type { MessagesDirection } from './ArbitrumL2Messages'; import type { MessagesDirection } from './ArbitrumL2Messages';
...@@ -23,8 +23,6 @@ const ArbitrumL2MessagesListItem = ({ item, isLoading, direction }: Props) => { ...@@ -23,8 +23,6 @@ const ArbitrumL2MessagesListItem = ({ item, isLoading, direction }: Props) => {
return null; return null;
} }
const timeAgo = dayjs(item.origination_timestamp).fromNow();
const l1TxHash = direction === 'from-rollup' ? item.completion_transaction_hash : item.origination_transaction_hash; const l1TxHash = direction === 'from-rollup' ? item.completion_transaction_hash : item.origination_transaction_hash;
const l2TxHash = direction === 'from-rollup' ? item.origination_transaction_hash : item.completion_transaction_hash; const l2TxHash = direction === 'from-rollup' ? item.origination_transaction_hash : item.completion_transaction_hash;
...@@ -88,7 +86,11 @@ const ArbitrumL2MessagesListItem = ({ item, isLoading, direction }: Props) => { ...@@ -88,7 +86,11 @@ const ArbitrumL2MessagesListItem = ({ item, isLoading, direction }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.origination_timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Status</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Status</ListItemMobileGrid.Label>
......
...@@ -4,12 +4,12 @@ import React from 'react'; ...@@ -4,12 +4,12 @@ import React from 'react';
import type { ArbitrumL2MessagesItem } from 'types/api/arbitrumL2'; import type { ArbitrumL2MessagesItem } from 'types/api/arbitrumL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import ArbitrumL2MessageStatus from 'ui/shared/statusTag/ArbitrumL2MessageStatus'; import ArbitrumL2MessageStatus from 'ui/shared/statusTag/ArbitrumL2MessageStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import type { MessagesDirection } from './ArbitrumL2Messages'; import type { MessagesDirection } from './ArbitrumL2Messages';
...@@ -22,8 +22,6 @@ const ArbitrumL2MessagesTableItem = ({ item, direction, isLoading }: Props) => { ...@@ -22,8 +22,6 @@ const ArbitrumL2MessagesTableItem = ({ item, direction, isLoading }: Props) => {
return null; return null;
} }
const timeAgo = dayjs(item.origination_timestamp).fromNow();
const l1TxHash = direction === 'from-rollup' ? item.completion_transaction_hash : item.origination_transaction_hash; const l1TxHash = direction === 'from-rollup' ? item.completion_transaction_hash : item.origination_transaction_hash;
const l2TxHash = direction === 'from-rollup' ? item.origination_transaction_hash : item.completion_transaction_hash; const l2TxHash = direction === 'from-rollup' ? item.origination_transaction_hash : item.completion_transaction_hash;
...@@ -75,9 +73,11 @@ const ArbitrumL2MessagesTableItem = ({ item, direction, isLoading }: Props) => { ...@@ -75,9 +73,11 @@ const ArbitrumL2MessagesTableItem = ({ item, direction, isLoading }: Props) => {
) } ) }
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.origination_timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<ArbitrumL2MessageStatus status={ item.status } isLoading={ isLoading }/> <ArbitrumL2MessageStatus status={ item.status } isLoading={ isLoading }/>
......
import { Skeleton } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type * as bens from '@blockscout/bens-types'; import type * as bens from '@blockscout/bens-types';
...@@ -6,12 +5,12 @@ import type * as bens from '@blockscout/bens-types'; ...@@ -6,12 +5,12 @@ import type * as bens from '@blockscout/bens-types';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import stripTrailingSlash from 'lib/stripTrailingSlash'; import stripTrailingSlash from 'lib/stripTrailingSlash';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
interface Props { interface Props {
event: bens.DomainEvent; event: bens.DomainEvent;
...@@ -38,9 +37,12 @@ const NameDomainHistoryListItem = ({ isLoading, domain, event }: Props) => { ...@@ -38,9 +37,12 @@ const NameDomainHistoryListItem = ({ isLoading, domain, event }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"> <TimeAgoWithTooltip
<span>{ dayjs(event.timestamp).fromNow() }</span> timestamp={ event.timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
{ event.from_address && ( { event.from_address && (
......
import { Tr, Td, Skeleton } from '@chakra-ui/react'; import { Tr, Td } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type * as bens from '@blockscout/bens-types'; import type * as bens from '@blockscout/bens-types';
...@@ -6,11 +6,11 @@ import type * as bens from '@blockscout/bens-types'; ...@@ -6,11 +6,11 @@ import type * as bens from '@blockscout/bens-types';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import stripTrailingSlash from 'lib/stripTrailingSlash'; import stripTrailingSlash from 'lib/stripTrailingSlash';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
interface Props { interface Props {
event: bens.DomainEvent; event: bens.DomainEvent;
...@@ -41,9 +41,12 @@ const NameDomainHistoryTableItem = ({ isLoading, event, domain }: Props) => { ...@@ -41,9 +41,12 @@ const NameDomainHistoryTableItem = ({ isLoading, event, domain }: Props) => {
/> />
</Td> </Td>
<Td pl={ 9 } verticalAlign="middle"> <Td pl={ 9 } verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"> <TimeAgoWithTooltip
<span>{ dayjs(event.timestamp).fromNow() }</span> timestamp={ event.timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
display="inline-block"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ event.from_address && <AddressEntity address={ event.from_address } isLoading={ isLoading } truncation="constant"/> } { event.from_address && <AddressEntity address={ event.from_address } isLoading={ isLoading } truncation="constant"/> }
......
...@@ -4,20 +4,18 @@ import React from 'react'; ...@@ -4,20 +4,18 @@ import React from 'react';
import type { OptimisticL2OutputRootsItem } from 'types/api/optimisticL2'; import type { OptimisticL2OutputRootsItem } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2'; import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2OutputRootsItem; isLoading?: boolean }; type Props = { item: OptimisticL2OutputRootsItem; isLoading?: boolean };
const OptimisticL2OutputRootsListItem = ({ item, isLoading }: Props) => { const OptimisticL2OutputRootsListItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_timestamp).fromNow();
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
return null; return null;
} }
...@@ -32,9 +30,11 @@ const OptimisticL2OutputRootsListItem = ({ item, isLoading }: Props) => { ...@@ -32,9 +30,11 @@ const OptimisticL2OutputRootsListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.l1_timestamp }
</Skeleton> isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L2 block #</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L2 block #</ListItemMobileGrid.Label>
......
...@@ -4,19 +4,17 @@ import React from 'react'; ...@@ -4,19 +4,17 @@ import React from 'react';
import type { OptimisticL2OutputRootsItem } from 'types/api/optimisticL2'; import type { OptimisticL2OutputRootsItem } from 'types/api/optimisticL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2'; import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2OutputRootsItem; isLoading?: boolean }; type Props = { item: OptimisticL2OutputRootsItem; isLoading?: boolean };
const OptimisticL2OutputRootsTableItem = ({ item, isLoading }: Props) => { const OptimisticL2OutputRootsTableItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_timestamp).fromNow();
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
return null; return null;
} }
...@@ -27,7 +25,12 @@ const OptimisticL2OutputRootsTableItem = ({ item, isLoading }: Props) => { ...@@ -27,7 +25,12 @@ const OptimisticL2OutputRootsTableItem = ({ item, isLoading }: Props) => {
<Skeleton isLoaded={ !isLoading } display="inline-block">{ item.l2_output_index }</Skeleton> <Skeleton isLoaded={ !isLoading } display="inline-block">{ item.l2_output_index }</Skeleton>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"><span>{ timeAgo }</span></Skeleton> <TimeAgoWithTooltip
timestamp={ item.l1_timestamp }
isLoading={ isLoading }
display="inline-block"
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<BlockEntityL2 <BlockEntityL2
......
import { Skeleton, Tooltip, chakra } from '@chakra-ui/react';
import React from 'react';
import dayjs from 'lib/date/dayjs';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
type Props = {
timestamp?: string | null;
fallbackText?: string;
isLoading?: boolean;
enableIncrement?: boolean;
className?: string;
}
const TimeAgoWithTooltip = ({ timestamp, fallbackText, isLoading, enableIncrement, className }: Props) => {
const timeAgo = useTimeAgoIncrement(timestamp || '', enableIncrement && !isLoading);
if (!timestamp && !fallbackText) {
return null;
}
const content = timestamp ?
<Tooltip label={ dayjs(timestamp).format('llll') }><span>{ timeAgo }</span></Tooltip> :
<span>{ fallbackText }</span>;
return (
<Skeleton isLoaded={ !isLoading } className={ className }>
{ content }
</Skeleton>
);
};
export default chakra(TimeAgoWithTooltip);
...@@ -4,7 +4,6 @@ import React from 'react'; ...@@ -4,7 +4,6 @@ import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { getTokenTypeName } from 'lib/token/tokenTypes'; import { getTokenTypeName } from 'lib/token/tokenTypes';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
...@@ -15,6 +14,8 @@ import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; ...@@ -15,6 +14,8 @@ import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers'; import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
import TimeAgoWithTooltip from '../TimeAgoWithTooltip';
type Props = TokenTransfer & { type Props = TokenTransfer & {
baseAddress?: string; baseAddress?: string;
showTxInfo?: boolean; showTxInfo?: boolean;
...@@ -35,7 +36,6 @@ const TokenTransferListItem = ({ ...@@ -35,7 +36,6 @@ const TokenTransferListItem = ({
enableTimeIncrement, enableTimeIncrement,
isLoading, isLoading,
}: Props) => { }: Props) => {
const timeAgo = useTimeAgoIncrement(timestamp, enableTimeIncrement);
const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({ const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({
value: total.value, value: total.value,
exchangeRate: token.exchange_rate, exchangeRate: token.exchange_rate,
...@@ -71,11 +71,14 @@ const TokenTransferListItem = ({ ...@@ -71,11 +71,14 @@ const TokenTransferListItem = ({
truncation="constant_long" truncation="constant_long"
fontWeight="700" fontWeight="700"
/> />
{ timestamp && ( <TimeAgoWithTooltip
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" fontSize="sm"> timestamp={ timestamp }
<span>{ timeAgo }</span> enableIncrement={ enableTimeIncrement }
</Skeleton> isLoading={ isLoading }
) } color="text_secondary"
fontWeight="400"
fontSize="sm"
/>
</Flex> </Flex>
) } ) }
<AddressFromTo <AddressFromTo
......
...@@ -4,7 +4,6 @@ import React from 'react'; ...@@ -4,7 +4,6 @@ import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { getTokenTypeName } from 'lib/token/tokenTypes'; import { getTokenTypeName } from 'lib/token/tokenTypes';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
...@@ -14,6 +13,8 @@ import TxEntity from 'ui/shared/entities/tx/TxEntity'; ...@@ -14,6 +13,8 @@ import TxEntity from 'ui/shared/entities/tx/TxEntity';
import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers'; import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
import TimeAgoWithTooltip from '../TimeAgoWithTooltip';
type Props = TokenTransfer & { type Props = TokenTransfer & {
baseAddress?: string; baseAddress?: string;
showTxInfo?: boolean; showTxInfo?: boolean;
...@@ -34,7 +35,6 @@ const TokenTransferTableItem = ({ ...@@ -34,7 +35,6 @@ const TokenTransferTableItem = ({
enableTimeIncrement, enableTimeIncrement,
isLoading, isLoading,
}: Props) => { }: Props) => {
const timeAgo = useTimeAgoIncrement(timestamp, enableTimeIncrement);
const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({ const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({
value: total.value, value: total.value,
exchangeRate: token.exchange_rate, exchangeRate: token.exchange_rate,
...@@ -78,11 +78,15 @@ const TokenTransferTableItem = ({ ...@@ -78,11 +78,15 @@ const TokenTransferTableItem = ({
mt="7px" mt="7px"
truncation="constant_long" truncation="constant_long"
/> />
{ timestamp && ( <TimeAgoWithTooltip
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" mt="10px" display="inline-block"> timestamp={ timestamp }
<span>{ timeAgo }</span> enableIncrement={ enableTimeIncrement }
</Skeleton> isLoading={ isLoading }
) } color="text_secondary"
fontWeight="400"
mt="10px"
display="inline-block"
/>
</Td> </Td>
) } ) }
<Td> <Td>
......
...@@ -4,13 +4,13 @@ import React from 'react'; ...@@ -4,13 +4,13 @@ import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes'; import { NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import TruncatedValue from 'ui/shared/TruncatedValue'; import TruncatedValue from 'ui/shared/TruncatedValue';
type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean }; type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean };
...@@ -26,7 +26,6 @@ const TokenTransferListItem = ({ ...@@ -26,7 +26,6 @@ const TokenTransferListItem = ({
tokenId, tokenId,
isLoading, isLoading,
}: Props) => { }: Props) => {
const timeAgo = useTimeAgoIncrement(timestamp, true);
const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({ const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({
value: total.value, value: total.value,
exchangeRate: token.exchange_rate, exchangeRate: token.exchange_rate,
...@@ -44,13 +43,15 @@ const TokenTransferListItem = ({ ...@@ -44,13 +43,15 @@ const TokenTransferListItem = ({
truncation="constant_long" truncation="constant_long"
fontWeight="700" fontWeight="700"
/> />
{ timestamp && ( <TimeAgoWithTooltip
<Skeleton isLoaded={ !isLoading } display="inline-block" fontWeight="400" fontSize="sm" color="text_secondary"> timestamp={ timestamp }
<span> enableIncrement
{ timeAgo } isLoading={ isLoading }
</span> color="text_secondary"
</Skeleton> fontWeight="400"
) } fontSize="sm"
display="inline-block"
/>
</Flex> </Flex>
{ method && <Tag isLoading={ isLoading }>{ method }</Tag> } { method && <Tag isLoading={ isLoading }>{ method }</Tag> }
<AddressFromTo <AddressFromTo
......
...@@ -4,12 +4,12 @@ import React from 'react'; ...@@ -4,12 +4,12 @@ import React from 'react';
import type { TokenTransfer } from 'types/api/tokenTransfer'; import type { TokenTransfer } from 'types/api/tokenTransfer';
import getCurrencyValue from 'lib/getCurrencyValue'; import getCurrencyValue from 'lib/getCurrencyValue';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes'; import { NFT_TOKEN_TYPE_IDS } from 'lib/token/tokenTypes';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import NftEntity from 'ui/shared/entities/nft/NftEntity'; import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean } type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean }
...@@ -24,7 +24,6 @@ const TokenTransferTableItem = ({ ...@@ -24,7 +24,6 @@ const TokenTransferTableItem = ({
tokenId, tokenId,
isLoading, isLoading,
}: Props) => { }: Props) => {
const timeAgo = useTimeAgoIncrement(timestamp, true);
const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({ const { usd, valueStr } = 'value' in total && total.value !== null ? getCurrencyValue({
value: total.value, value: total.value,
exchangeRate: token.exchange_rate, exchangeRate: token.exchange_rate,
...@@ -44,13 +43,15 @@ const TokenTransferTableItem = ({ ...@@ -44,13 +43,15 @@ const TokenTransferTableItem = ({
noIcon noIcon
truncation="constant_long" truncation="constant_long"
/> />
{ timestamp && ( <TimeAgoWithTooltip
<Skeleton isLoaded={ !isLoading } display="inline-block" color="gray.500" fontWeight="400" ml="10px"> timestamp={ timestamp }
<span> enableIncrement
{ timeAgo } isLoading={ isLoading }
</span> display="inline-block"
</Skeleton> color="gray.500"
) } fontWeight="400"
ml="10px"
/>
</Flex> </Flex>
</Td> </Td>
<Td> <Td>
......
...@@ -6,21 +6,19 @@ import type { ArbitrumL2TxnBatchesItem } from 'types/api/arbitrumL2'; ...@@ -6,21 +6,19 @@ import type { ArbitrumL2TxnBatchesItem } from 'types/api/arbitrumL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import ArbitrumL2TxnBatchStatus from 'ui/shared/statusTag/ArbitrumL2TxnBatchStatus'; import ArbitrumL2TxnBatchStatus from 'ui/shared/statusTag/ArbitrumL2TxnBatchStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: ArbitrumL2TxnBatchesItem; isLoading?: boolean }; type Props = { item: ArbitrumL2TxnBatchesItem; isLoading?: boolean };
const ArbitrumL2TxnBatchesListItem = ({ item, isLoading }: Props) => { const ArbitrumL2TxnBatchesListItem = ({ item, isLoading }: Props) => {
const timeAgo = item.commitment_transaction.timestamp ? dayjs(item.commitment_transaction.timestamp).fromNow() : 'Undefined';
if (!rollupFeature.isEnabled || rollupFeature.type !== 'arbitrum') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'arbitrum') {
return null; return null;
} }
...@@ -76,7 +74,12 @@ const ArbitrumL2TxnBatchesListItem = ({ item, isLoading }: Props) => { ...@@ -76,7 +74,12 @@ const ArbitrumL2TxnBatchesListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.commitment_transaction.timestamp }
fallbackText="Undefined"
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Txn count</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Txn count</ListItemMobileGrid.Label>
......
...@@ -6,20 +6,18 @@ import type { ArbitrumL2TxnBatchesItem } from 'types/api/arbitrumL2'; ...@@ -6,20 +6,18 @@ import type { ArbitrumL2TxnBatchesItem } from 'types/api/arbitrumL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1'; import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ArbitrumL2TxnBatchStatus from 'ui/shared/statusTag/ArbitrumL2TxnBatchStatus'; import ArbitrumL2TxnBatchStatus from 'ui/shared/statusTag/ArbitrumL2TxnBatchStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: ArbitrumL2TxnBatchesItem; isLoading?: boolean }; type Props = { item: ArbitrumL2TxnBatchesItem; isLoading?: boolean };
const TxnBatchesTableItem = ({ item, isLoading }: Props) => { const TxnBatchesTableItem = ({ item, isLoading }: Props) => {
const timeAgo = item.commitment_transaction.timestamp ? dayjs(item.commitment_transaction.timestamp).fromNow() : 'Undefined';
if (!rollupFeature.isEnabled || rollupFeature.type !== 'arbitrum') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'arbitrum') {
return null; return null;
} }
...@@ -60,9 +58,12 @@ const TxnBatchesTableItem = ({ item, isLoading }: Props) => { ...@@ -60,9 +58,12 @@ const TxnBatchesTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.commitment_transaction.timestamp }
</Skeleton> fallbackText="Undefined"
isLoading={ isLoading }
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<LinkInternal <LinkInternal
......
...@@ -6,19 +6,17 @@ import type { OptimisticL2TxnBatchesItem } from 'types/api/optimisticL2'; ...@@ -6,19 +6,17 @@ import type { OptimisticL2TxnBatchesItem } from 'types/api/optimisticL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2'; import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2TxnBatchesItem; isLoading?: boolean }; type Props = { item: OptimisticL2TxnBatchesItem; isLoading?: boolean };
const OptimisticL2TxnBatchesListItem = ({ item, isLoading }: Props) => { const OptimisticL2TxnBatchesListItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_timestamp).fromNow();
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
return null; return null;
} }
...@@ -67,7 +65,11 @@ const OptimisticL2TxnBatchesListItem = ({ item, isLoading }: Props) => { ...@@ -67,7 +65,11 @@ const OptimisticL2TxnBatchesListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.l1_timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
</ListItemMobileGrid.Container> </ListItemMobileGrid.Container>
......
...@@ -6,18 +6,16 @@ import type { OptimisticL2TxnBatchesItem } from 'types/api/optimisticL2'; ...@@ -6,18 +6,16 @@ import type { OptimisticL2TxnBatchesItem } from 'types/api/optimisticL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2'; import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2TxnBatchesItem; isLoading?: boolean }; type Props = { item: OptimisticL2TxnBatchesItem; isLoading?: boolean };
const OptimisticL2TxnBatchesTableItem = ({ item, isLoading }: Props) => { const OptimisticL2TxnBatchesTableItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.l1_timestamp).fromNow();
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
return null; return null;
} }
...@@ -60,9 +58,13 @@ const OptimisticL2TxnBatchesTableItem = ({ item, isLoading }: Props) => { ...@@ -60,9 +58,13 @@ const OptimisticL2TxnBatchesTableItem = ({ item, isLoading }: Props) => {
</VStack> </VStack>
</Td> </Td>
<Td> <Td>
<Skeleton isLoaded={ !isLoading } color="text_secondary" my={ 1 } display="inline-block"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.l1_timestamp }
</Skeleton> isLoading={ isLoading }
display="inline-block"
color="text_secondary"
my={ 1 }
/>
</Td> </Td>
</Tr> </Tr>
); );
......
...@@ -6,20 +6,18 @@ import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2'; ...@@ -6,20 +6,18 @@ import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus'; import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: ZkEvmL2TxnBatchesItem; isLoading?: boolean }; type Props = { item: ZkEvmL2TxnBatchesItem; isLoading?: boolean };
const ZkEvmTxnBatchesListItem = ({ item, isLoading }: Props) => { const ZkEvmTxnBatchesListItem = ({ item, isLoading }: Props) => {
const timeAgo = item.timestamp ? dayjs(item.timestamp).fromNow() : 'Undefined';
if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkEvm') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkEvm') {
return null; return null;
} }
...@@ -45,7 +43,12 @@ const ZkEvmTxnBatchesListItem = ({ item, isLoading }: Props) => { ...@@ -45,7 +43,12 @@ const ZkEvmTxnBatchesListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
fallbackText="Undefined"
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Txn count</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Txn count</ListItemMobileGrid.Label>
......
...@@ -6,19 +6,17 @@ import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2'; ...@@ -6,19 +6,17 @@ import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus'; import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: ZkEvmL2TxnBatchesItem; isLoading?: boolean }; type Props = { item: ZkEvmL2TxnBatchesItem; isLoading?: boolean };
const TxnBatchesTableItem = ({ item, isLoading }: Props) => { const TxnBatchesTableItem = ({ item, isLoading }: Props) => {
const timeAgo = item.timestamp ? dayjs(item.timestamp).fromNow() : 'Undefined';
if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkEvm') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkEvm') {
return null; return null;
} }
...@@ -39,9 +37,12 @@ const TxnBatchesTableItem = ({ item, isLoading }: Props) => { ...@@ -39,9 +37,12 @@ const TxnBatchesTableItem = ({ item, isLoading }: Props) => {
<ZkEvmL2TxnBatchStatus status={ item.status } isLoading={ isLoading }/> <ZkEvmL2TxnBatchStatus status={ item.status } isLoading={ isLoading }/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.timestamp }
</Skeleton> fallbackText="Undefined"
isLoading={ isLoading }
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<LinkInternal <LinkInternal
......
...@@ -6,20 +6,18 @@ import type { ZkSyncBatchesItem } from 'types/api/zkSyncL2'; ...@@ -6,20 +6,18 @@ import type { ZkSyncBatchesItem } from 'types/api/zkSyncL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import ZkSyncL2TxnBatchStatus from 'ui/shared/statusTag/ZkSyncL2TxnBatchStatus'; import ZkSyncL2TxnBatchStatus from 'ui/shared/statusTag/ZkSyncL2TxnBatchStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: ZkSyncBatchesItem; isLoading?: boolean }; type Props = { item: ZkSyncBatchesItem; isLoading?: boolean };
const ZkSyncTxnBatchesListItem = ({ item, isLoading }: Props) => { const ZkSyncTxnBatchesListItem = ({ item, isLoading }: Props) => {
const timeAgo = item.timestamp ? dayjs(item.timestamp).fromNow() : 'Undefined';
if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkSync') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkSync') {
return null; return null;
} }
...@@ -45,7 +43,12 @@ const ZkSyncTxnBatchesListItem = ({ item, isLoading }: Props) => { ...@@ -45,7 +43,12 @@ const ZkSyncTxnBatchesListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
fallbackText="Undefined"
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Txn count</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Txn count</ListItemMobileGrid.Label>
......
...@@ -6,19 +6,17 @@ import type { ZkSyncBatchesItem } from 'types/api/zkSyncL2'; ...@@ -6,19 +6,17 @@ import type { ZkSyncBatchesItem } from 'types/api/zkSyncL2';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2'; import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkInternal from 'ui/shared/links/LinkInternal'; import LinkInternal from 'ui/shared/links/LinkInternal';
import ZkSyncL2TxnBatchStatus from 'ui/shared/statusTag/ZkSyncL2TxnBatchStatus'; import ZkSyncL2TxnBatchStatus from 'ui/shared/statusTag/ZkSyncL2TxnBatchStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: ZkSyncBatchesItem; isLoading?: boolean }; type Props = { item: ZkSyncBatchesItem; isLoading?: boolean };
const ZkSyncTxnBatchesTableItem = ({ item, isLoading }: Props) => { const ZkSyncTxnBatchesTableItem = ({ item, isLoading }: Props) => {
const timeAgo = item.timestamp ? dayjs(item.timestamp).fromNow() : 'Undefined';
if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkSync') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkSync') {
return null; return null;
} }
...@@ -39,9 +37,12 @@ const ZkSyncTxnBatchesTableItem = ({ item, isLoading }: Props) => { ...@@ -39,9 +37,12 @@ const ZkSyncTxnBatchesTableItem = ({ item, isLoading }: Props) => {
<ZkSyncL2TxnBatchStatus status={ item.status } isLoading={ isLoading }/> <ZkSyncL2TxnBatchStatus status={ item.status } isLoading={ isLoading }/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.timestamp }
</Skeleton> fallbackText="Undefined"
isLoading={ isLoading }
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<LinkInternal <LinkInternal
......
...@@ -9,7 +9,6 @@ import type { Transaction } from 'types/api/transaction'; ...@@ -9,7 +9,6 @@ import type { Transaction } from 'types/api/transaction';
import config from 'configs/app'; import config from 'configs/app';
import getValueWithUnit from 'lib/getValueWithUnit'; import getValueWithUnit from 'lib/getValueWithUnit';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import { space } from 'lib/html-entities'; import { space } from 'lib/html-entities';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
...@@ -17,6 +16,7 @@ import BlockEntity from 'ui/shared/entities/block/BlockEntity'; ...@@ -17,6 +16,7 @@ import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TxStatus from 'ui/shared/statusTag/TxStatus'; import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import TxFee from 'ui/shared/tx/TxFee'; import TxFee from 'ui/shared/tx/TxFee';
import TxWatchListTags from 'ui/shared/tx/TxWatchListTags'; import TxWatchListTags from 'ui/shared/tx/TxWatchListTags';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -35,8 +35,6 @@ type Props = { ...@@ -35,8 +35,6 @@ type Props = {
const TxsListItem = ({ tx, isLoading, showBlockInfo, currentAddress, enableTimeIncrement }: Props) => { const TxsListItem = ({ tx, isLoading, showBlockInfo, currentAddress, enableTimeIncrement }: Props) => {
const dataTo = tx.to ? tx.to : tx.created_contract; const dataTo = tx.to ? tx.to : tx.created_contract;
const timeAgo = useTimeAgoIncrement(tx.timestamp, enableTimeIncrement);
return ( return (
<ListItemMobile display="block" width="100%" isAnimated key={ tx.hash }> <ListItemMobile display="block" width="100%" isAnimated key={ tx.hash }>
<Flex justifyContent="space-between" mt={ 4 }> <Flex justifyContent="space-between" mt={ 4 }>
...@@ -58,11 +56,14 @@ const TxsListItem = ({ tx, isLoading, showBlockInfo, currentAddress, enableTimeI ...@@ -58,11 +56,14 @@ const TxsListItem = ({ tx, isLoading, showBlockInfo, currentAddress, enableTimeI
fontWeight="700" fontWeight="700"
iconName={ tx.tx_types.includes('blob_transaction') ? 'blob' : undefined } iconName={ tx.tx_types.includes('blob_transaction') ? 'blob' : undefined }
/> />
{ tx.timestamp && ( <TimeAgoWithTooltip
<Skeleton isLoaded={ !isLoading } color="text_secondary" fontWeight="400" fontSize="sm"> timestamp={ tx.timestamp }
<span>{ timeAgo }</span> enableIncrement={ enableTimeIncrement }
</Skeleton> isLoading={ isLoading }
) } color="text_secondary"
fontWeight="400"
fontSize="sm"
/>
</Flex> </Flex>
{ tx.method && ( { tx.method && (
<Flex mt={ 3 }> <Flex mt={ 3 }>
......
...@@ -2,7 +2,6 @@ import { ...@@ -2,7 +2,6 @@ import {
Tr, Tr,
Td, Td,
VStack, VStack,
Skeleton,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import React from 'react'; import React from 'react';
...@@ -10,13 +9,13 @@ import React from 'react'; ...@@ -10,13 +9,13 @@ import React from 'react';
import type { Transaction } from 'types/api/transaction'; import type { Transaction } from 'types/api/transaction';
import config from 'configs/app'; import config from 'configs/app';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import AddressFromTo from 'ui/shared/address/AddressFromTo'; import AddressFromTo from 'ui/shared/address/AddressFromTo';
import Tag from 'ui/shared/chakra/Tag'; import Tag from 'ui/shared/chakra/Tag';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxStatus from 'ui/shared/statusTag/TxStatus'; import TxStatus from 'ui/shared/statusTag/TxStatus';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import TxFee from 'ui/shared/tx/TxFee'; import TxFee from 'ui/shared/tx/TxFee';
import TxWatchListTags from 'ui/shared/tx/TxWatchListTags'; import TxWatchListTags from 'ui/shared/tx/TxWatchListTags';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
...@@ -34,7 +33,6 @@ type Props = { ...@@ -34,7 +33,6 @@ type Props = {
const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement, isLoading }: Props) => { const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement, isLoading }: Props) => {
const dataTo = tx.to ? tx.to : tx.created_contract; const dataTo = tx.to ? tx.to : tx.created_contract;
const timeAgo = useTimeAgoIncrement(tx.timestamp, enableTimeIncrement);
return ( return (
<Tr <Tr
...@@ -58,7 +56,13 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement, ...@@ -58,7 +56,13 @@ const TxsTableItem = ({ tx, showBlockInfo, currentAddress, enableTimeIncrement,
maxW="100%" maxW="100%"
truncation="constant_long" truncation="constant_long"
/> />
{ tx.timestamp && <Skeleton color="text_secondary" fontWeight="400" isLoaded={ !isLoading }><span>{ timeAgo }</span></Skeleton> } <TimeAgoWithTooltip
timestamp={ tx.timestamp }
enableIncrement={ enableTimeIncrement }
isLoading={ isLoading }
color="text_secondary"
fontWeight="400"
/>
</VStack> </VStack>
</Td> </Td>
<Td> <Td>
......
...@@ -4,13 +4,13 @@ import React from 'react'; ...@@ -4,13 +4,13 @@ import React from 'react';
import type { UserOpsItem } from 'types/api/userOps'; import type { UserOpsItem } from 'types/api/userOps';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity'; import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import UserOpStatus from 'ui/shared/userOps/UserOpStatus'; import UserOpStatus from 'ui/shared/userOps/UserOpStatus';
type Props = { type Props = {
...@@ -21,8 +21,6 @@ type Props = { ...@@ -21,8 +21,6 @@ type Props = {
}; };
const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => { const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => {
const timeAgo = dayjs(item.timestamp).fromNow();
return ( return (
<ListItemMobileGrid.Container gridTemplateColumns="100px auto"> <ListItemMobileGrid.Container gridTemplateColumns="100px auto">
...@@ -33,7 +31,12 @@ const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => { ...@@ -33,7 +31,12 @@ const UserOpsListItem = ({ item, isLoading, showTx, showSender }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"><span>{ timeAgo }</span></Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
color="text_secondary"
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Status</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Status</ListItemMobileGrid.Label>
......
import { Td, Tr, Skeleton } from '@chakra-ui/react'; import { Td, Tr } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { UserOpsItem } from 'types/api/userOps'; import type { UserOpsItem } from 'types/api/userOps';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity'; import UserOpEntity from 'ui/shared/entities/userOp/UserOpEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
import UserOpStatus from 'ui/shared/userOps/UserOpStatus'; import UserOpStatus from 'ui/shared/userOps/UserOpStatus';
type Props = { type Props = {
...@@ -20,15 +20,18 @@ import UserOpStatus from 'ui/shared/userOps/UserOpStatus'; ...@@ -20,15 +20,18 @@ import UserOpStatus from 'ui/shared/userOps/UserOpStatus';
}; };
const UserOpsTableItem = ({ item, isLoading, showTx, showSender }: Props) => { const UserOpsTableItem = ({ item, isLoading, showTx, showSender }: Props) => {
const timeAgo = dayjs(item.timestamp).fromNow();
return ( return (
<Tr> <Tr>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<UserOpEntity hash={ item.hash } isLoading={ isLoading } noIcon fontWeight={ 700 } truncation="constant_long"/> <UserOpEntity hash={ item.hash } isLoading={ isLoading } noIcon fontWeight={ 700 } truncation="constant_long"/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"><span>{ timeAgo }</span></Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
color="text_secondary"
display="inline-block"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
<UserOpStatus status={ item.status } isLoading={ isLoading }/> <UserOpStatus status={ item.status } isLoading={ isLoading }/>
......
...@@ -6,7 +6,6 @@ import type { VerifiedContract } from 'types/api/contracts'; ...@@ -6,7 +6,6 @@ import type { VerifiedContract } from 'types/api/contracts';
import config from 'configs/app'; import config from 'configs/app';
import { CONTRACT_LICENSES } from 'lib/contracts/licenses'; import { CONTRACT_LICENSES } from 'lib/contracts/licenses';
import dayjs from 'lib/date/dayjs';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel'; import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
...@@ -14,6 +13,7 @@ import AddressEntity from 'ui/shared/entities/address/AddressEntity'; ...@@ -14,6 +13,7 @@ import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile'; import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
interface Props { interface Props {
data: VerifiedContract; data: VerifiedContract;
...@@ -86,9 +86,11 @@ const VerifiedContractsListItem = ({ data, isLoading }: Props) => { ...@@ -86,9 +86,11 @@ const VerifiedContractsListItem = ({ data, isLoading }: Props) => {
<Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>Verified</Skeleton> <Skeleton isLoaded={ !isLoading } fontWeight={ 500 }>Verified</Skeleton>
<Flex alignItems="center" columnGap={ 2 }> <Flex alignItems="center" columnGap={ 2 }>
<IconSvg name="status/success" boxSize={ 4 } color="green.500" isLoading={ isLoading }/> <IconSvg name="status/success" boxSize={ 4 } color="green.500" isLoading={ isLoading }/>
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ dayjs(data.verified_at).fromNow() }</span> timestamp={ data.verified_at }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
/>
</Flex> </Flex>
</Flex> </Flex>
<Flex columnGap={ 3 }> <Flex columnGap={ 3 }>
......
...@@ -6,12 +6,12 @@ import type { VerifiedContract } from 'types/api/contracts'; ...@@ -6,12 +6,12 @@ import type { VerifiedContract } from 'types/api/contracts';
import config from 'configs/app'; import config from 'configs/app';
import { CONTRACT_LICENSES } from 'lib/contracts/licenses'; import { CONTRACT_LICENSES } from 'lib/contracts/licenses';
import dayjs from 'lib/date/dayjs';
import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel'; import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel';
import CopyToClipboard from 'ui/shared/CopyToClipboard'; import CopyToClipboard from 'ui/shared/CopyToClipboard';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import HashStringShorten from 'ui/shared/HashStringShorten'; import HashStringShorten from 'ui/shared/HashStringShorten';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
interface Props { interface Props {
data: VerifiedContract; data: VerifiedContract;
...@@ -90,9 +90,11 @@ const VerifiedContractsTableItem = ({ data, isLoading }: Props) => { ...@@ -90,9 +90,11 @@ const VerifiedContractsTableItem = ({ data, isLoading }: Props) => {
<Td> <Td>
<Flex alignItems="center" columnGap={ 2 } my={ 1 }> <Flex alignItems="center" columnGap={ 2 } my={ 1 }>
<IconSvg name="status/success" boxSize={ 4 } color="green.500" isLoading={ isLoading }/> <IconSvg name="status/success" boxSize={ 4 } color="green.500" isLoading={ isLoading }/>
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ dayjs(data.verified_at).fromNow() }</span> timestamp={ data.verified_at }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
/>
</Flex> </Flex>
</Td> </Td>
<Td> <Td>
......
...@@ -6,12 +6,12 @@ import type { BlockWithdrawalsItem } from 'types/api/block'; ...@@ -6,12 +6,12 @@ import type { BlockWithdrawalsItem } from 'types/api/block';
import type { WithdrawalsItem } from 'types/api/withdrawals'; import type { WithdrawalsItem } from 'types/api/withdrawals';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import { currencyUnits } from 'lib/units'; import { currencyUnits } from 'lib/units';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const feature = config.features.beaconChain; const feature = config.features.beaconChain;
...@@ -74,7 +74,11 @@ const BeaconChainWithdrawalsListItem = ({ item, isLoading, view }: Props) => { ...@@ -74,7 +74,11 @@ const BeaconChainWithdrawalsListItem = ({ item, isLoading, view }: Props) => {
<> <>
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ dayjs(item.timestamp).fromNow() }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Value</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Value</ListItemMobileGrid.Label>
......
...@@ -5,10 +5,10 @@ import type { AddressWithdrawalsItem } from 'types/api/address'; ...@@ -5,10 +5,10 @@ import type { AddressWithdrawalsItem } from 'types/api/address';
import type { BlockWithdrawalsItem } from 'types/api/block'; import type { BlockWithdrawalsItem } from 'types/api/block';
import type { WithdrawalsItem } from 'types/api/withdrawals'; import type { WithdrawalsItem } from 'types/api/withdrawals';
import dayjs from 'lib/date/dayjs';
import CurrencyValue from 'ui/shared/CurrencyValue'; import CurrencyValue from 'ui/shared/CurrencyValue';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
type Props = ({ type Props = ({
item: WithdrawalsItem; item: WithdrawalsItem;
...@@ -52,9 +52,12 @@ const BeaconChainWithdrawalsTableItem = ({ item, view, isLoading }: Props) => { ...@@ -52,9 +52,12 @@ const BeaconChainWithdrawalsTableItem = ({ item, view, isLoading }: Props) => {
) } ) }
{ view !== 'block' && ( { view !== 'block' && (
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } display="inline-block" color="text_secondary"> <TimeAgoWithTooltip
<span>{ dayjs(item.timestamp).fromNow() }</span> timestamp={ item.timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
display="inline-block"
/>
</Td> </Td>
) } ) }
<Td verticalAlign="middle"> <Td verticalAlign="middle">
......
...@@ -10,13 +10,13 @@ import TxEntity from 'ui/shared/entities/tx/TxEntity'; ...@@ -10,13 +10,13 @@ import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkExternal from 'ui/shared/links/LinkExternal'; import LinkExternal from 'ui/shared/links/LinkExternal';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2WithdrawalsItem; isLoading?: boolean }; type Props = { item: OptimisticL2WithdrawalsItem; isLoading?: boolean };
const OptimisticL2WithdrawalsListItem = ({ item, isLoading }: Props) => { const OptimisticL2WithdrawalsListItem = ({ item, isLoading }: Props) => {
const timeAgo = item.l2_timestamp ? dayjs(item.l2_timestamp).fromNow() : null;
const timeToEnd = item.challenge_period_end ? dayjs(item.challenge_period_end).fromNow(true) + ' left' : null; const timeToEnd = item.challenge_period_end ? dayjs(item.challenge_period_end).fromNow(true) + ' left' : null;
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
...@@ -57,13 +57,15 @@ const OptimisticL2WithdrawalsListItem = ({ item, isLoading }: Props) => { ...@@ -57,13 +57,15 @@ const OptimisticL2WithdrawalsListItem = ({ item, isLoading }: Props) => {
/> />
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
{ timeAgo && ( { item.l2_timestamp && (
<> <>
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block"> <TimeAgoWithTooltip
{ timeAgo } timestamp={ item.l2_timestamp }
</Skeleton> isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
</> </>
) } ) }
......
...@@ -9,13 +9,13 @@ import AddressEntity from 'ui/shared/entities/address/AddressEntity'; ...@@ -9,13 +9,13 @@ import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import LinkExternal from 'ui/shared/links/LinkExternal'; import LinkExternal from 'ui/shared/links/LinkExternal';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
type Props = { item: OptimisticL2WithdrawalsItem; isLoading?: boolean }; type Props = { item: OptimisticL2WithdrawalsItem; isLoading?: boolean };
const OptimisticL2WithdrawalsTableItem = ({ item, isLoading }: Props) => { const OptimisticL2WithdrawalsTableItem = ({ item, isLoading }: Props) => {
const timeAgo = item.l2_timestamp ? dayjs(item.l2_timestamp).fromNow() : 'N/A';
const timeToEnd = item.challenge_period_end ? dayjs(item.challenge_period_end).fromNow(true) + ' left' : ''; const timeToEnd = item.challenge_period_end ? dayjs(item.challenge_period_end).fromNow(true) + ' left' : '';
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') { if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
...@@ -47,9 +47,13 @@ const OptimisticL2WithdrawalsTableItem = ({ item, isLoading }: Props) => { ...@@ -47,9 +47,13 @@ const OptimisticL2WithdrawalsTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"> <TimeAgoWithTooltip
<span> { timeAgo }</span> timestamp={ item.l2_timestamp }
</Skeleton> fallbackText="N/A"
isLoading={ isLoading }
display="inline-block"
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ item.status === 'Ready for relay' && rollupFeature.L2WithdrawalUrl ? { item.status === 'Ready for relay' && rollupFeature.L2WithdrawalUrl ?
......
import { Skeleton } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { ShibariumWithdrawalsItem } from 'types/api/shibarium'; import type { ShibariumWithdrawalsItem } from 'types/api/shibarium';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const feature = config.features.rollup; const feature = config.features.rollup;
type Props = { item: ShibariumWithdrawalsItem; isLoading?: boolean }; type Props = { item: ShibariumWithdrawalsItem; isLoading?: boolean };
const WithdrawalsListItem = ({ item, isLoading }: Props) => { const WithdrawalsListItem = ({ item, isLoading }: Props) => {
const timeAgo = item.timestamp ? dayjs(item.timestamp).fromNow() : null;
if (!(feature.isEnabled && feature.type === 'shibarium')) { if (!(feature.isEnabled && feature.type === 'shibarium')) {
return null; return null;
} }
...@@ -69,7 +66,11 @@ const WithdrawalsListItem = ({ item, isLoading }: Props) => { ...@@ -69,7 +66,11 @@ const WithdrawalsListItem = ({ item, isLoading }: Props) => {
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
</ListItemMobileGrid.Container> </ListItemMobileGrid.Container>
......
import { Td, Tr, Skeleton } from '@chakra-ui/react'; import { Td, Tr } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { ShibariumWithdrawalsItem } from 'types/api/shibarium'; import type { ShibariumWithdrawalsItem } from 'types/api/shibarium';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam'; import AddressStringOrParam from 'ui/shared/entities/address/AddressStringOrParam';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const feature = config.features.rollup; const feature = config.features.rollup;
type Props = { item: ShibariumWithdrawalsItem; isLoading?: boolean }; type Props = { item: ShibariumWithdrawalsItem; isLoading?: boolean };
const WithdrawalsTableItem = ({ item, isLoading }: Props) => { const WithdrawalsTableItem = ({ item, isLoading }: Props) => {
const timeAgo = dayjs(item.timestamp).fromNow();
if (!(feature.isEnabled && feature.type === 'shibarium')) { if (!(feature.isEnabled && feature.type === 'shibarium')) {
return null; return null;
} }
...@@ -59,7 +57,12 @@ const WithdrawalsTableItem = ({ item, isLoading }: Props) => { ...@@ -59,7 +57,12 @@ const WithdrawalsTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } color="text_secondary" display="inline-block"><span>{ timeAgo }</span></Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
display="inline-block"
color="text_secondary"
/>
</Td> </Td>
</Tr> </Tr>
); );
......
...@@ -5,11 +5,11 @@ import React from 'react'; ...@@ -5,11 +5,11 @@ import React from 'react';
import type { ZkEvmL2WithdrawalsItem } from 'types/api/zkEvmL2'; import type { ZkEvmL2WithdrawalsItem } from 'types/api/zkEvmL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid'; import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
...@@ -20,8 +20,6 @@ const ZkEvmL2WithdrawalsListItem = ({ item, isLoading }: Props) => { ...@@ -20,8 +20,6 @@ const ZkEvmL2WithdrawalsListItem = ({ item, isLoading }: Props) => {
return null; return null;
} }
const timeAgo = dayjs(item.timestamp).fromNow();
return ( return (
<ListItemMobileGrid.Container> <ListItemMobileGrid.Container>
...@@ -56,7 +54,11 @@ const ZkEvmL2WithdrawalsListItem = ({ item, isLoading }: Props) => { ...@@ -56,7 +54,11 @@ const ZkEvmL2WithdrawalsListItem = ({ item, isLoading }: Props) => {
<ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>Age</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value> <ListItemMobileGrid.Value>
<Skeleton isLoaded={ !isLoading } display="inline-block">{ timeAgo }</Skeleton> <TimeAgoWithTooltip
timestamp={ item.timestamp }
isLoading={ isLoading }
display="inline-block"
/>
</ListItemMobileGrid.Value> </ListItemMobileGrid.Value>
<ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label> <ListItemMobileGrid.Label isLoading={ isLoading }>L1 txn hash</ListItemMobileGrid.Label>
......
...@@ -5,10 +5,10 @@ import React from 'react'; ...@@ -5,10 +5,10 @@ import React from 'react';
import type { ZkEvmL2WithdrawalsItem } from 'types/api/zkEvmL2'; import type { ZkEvmL2WithdrawalsItem } from 'types/api/zkEvmL2';
import config from 'configs/app'; import config from 'configs/app';
import dayjs from 'lib/date/dayjs';
import BlockEntity from 'ui/shared/entities/block/BlockEntity'; import BlockEntity from 'ui/shared/entities/block/BlockEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1'; import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip';
const rollupFeature = config.features.rollup; const rollupFeature = config.features.rollup;
...@@ -19,8 +19,6 @@ const ZkEvmL2WithdrawalsTableItem = ({ item, isLoading }: Props) => { ...@@ -19,8 +19,6 @@ const ZkEvmL2WithdrawalsTableItem = ({ item, isLoading }: Props) => {
return null; return null;
} }
const timeAgo = dayjs(item.timestamp).fromNow();
return ( return (
<Tr> <Tr>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
...@@ -49,9 +47,11 @@ const ZkEvmL2WithdrawalsTableItem = ({ item, isLoading }: Props) => { ...@@ -49,9 +47,11 @@ const ZkEvmL2WithdrawalsTableItem = ({ item, isLoading }: Props) => {
/> />
</Td> </Td>
<Td verticalAlign="middle" pr={ 12 }> <Td verticalAlign="middle" pr={ 12 }>
<Skeleton isLoaded={ !isLoading } color="text_secondary"> <TimeAgoWithTooltip
<span>{ timeAgo }</span> timestamp={ item.timestamp }
</Skeleton> isLoading={ isLoading }
color="text_secondary"
/>
</Td> </Td>
<Td verticalAlign="middle"> <Td verticalAlign="middle">
{ item.l1_transaction_hash ? ( { item.l1_transaction_hash ? (
......
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