Commit a6c764d4 authored by tom's avatar tom

update block timestamp in list view

parent 2c6b0b0f
...@@ -4,3 +4,9 @@ export const WEI = new BigNumber(10 ** 18); ...@@ -4,3 +4,9 @@ export const WEI = new BigNumber(10 ** 18);
export const GWEI = new BigNumber(10 ** 9); export const GWEI = new BigNumber(10 ** 9);
export const WEI_IN_GWEI = WEI.dividedBy(GWEI); export const WEI_IN_GWEI = WEI.dividedBy(GWEI);
export const ZERO = new BigNumber(0); export const ZERO = new BigNumber(0);
export const SECOND = 1_000;
export const MINUTE = 60 * SECOND;
export const HOUR = 60 * MINUTE;
export const DAY = 24 * HOUR;
export const WEEK = 7 * DAY;
import React from 'react';
import { DAY, HOUR, MINUTE, SECOND } from 'lib/consts';
import dayjs from 'lib/date/dayjs';
function getUnits(diff: number) {
if (diff < MINUTE) {
return [ SECOND, MINUTE ];
}
if (diff < HOUR) {
return [ MINUTE, HOUR ];
}
if (diff < DAY) {
return [ HOUR, DAY ];
}
return [ DAY, 2 * DAY ];
}
function getUpdateParams(ts: string) {
const timeDiff = Date.now() - new Date(ts).getTime();
const [ unit, higherUnit ] = getUnits(timeDiff);
if (unit === DAY) {
return { interval: DAY };
}
const leftover = unit - timeDiff % unit;
return {
startTimeout: unit === SECOND ?
0 :
// here we assume that in current dayjs locale time difference is rounded by Math.round function
// so we have to update displayed value whenever time comes over the middle of the unit interval
// since it will be rounded to the upper bound
(leftover < unit / 2 ? leftover + unit / 2 : leftover - unit / 2) + SECOND,
endTimeout: higherUnit - timeDiff + SECOND,
interval: unit,
};
}
export default function useTimeAgoIncrement(ts: string, isEnabled?: boolean) {
const [ value, setValue ] = React.useState(dayjs(ts).fromNow());
React.useEffect(() => {
const timeouts: Array<number> = [];
const intervals: Array<number> = [];
const startIncrement = () => {
const { startTimeout, interval, endTimeout } = getUpdateParams(ts);
if (!startTimeout && !endTimeout) {
return;
}
let intervalId: number;
const startTimeoutId = window.setTimeout(() => {
setValue(dayjs(ts).fromNow());
intervalId = window.setInterval(() => {
setValue(dayjs(ts).fromNow());
}, interval);
intervals.push(intervalId);
}, startTimeout);
const endTimeoutId = window.setTimeout(() => {
window.clearInterval(intervalId);
startIncrement();
}, endTimeout);
timeouts.push(startTimeoutId);
timeouts.push(endTimeoutId);
};
isEnabled && startIncrement();
return () => {
timeouts.forEach(window.clearTimeout);
intervals.forEach(window.clearInterval);
};
}, [ isEnabled, ts ]);
return value;
}
...@@ -12,7 +12,8 @@ interface Props { ...@@ -12,7 +12,8 @@ interface Props {
const BlocksList = ({ data }: Props) => { const BlocksList = ({ data }: Props) => {
return ( return (
<Box mt={ 8 }> <Box mt={ 8 }>
{ data.map((item) => <BlocksListItem key={ item.height } data={ item }/>) } { /* TODO prop "enableTimeIncrement" should be set to false for second and later pages */ }
{ data.map((item) => <BlocksListItem key={ item.height } data={ item } enableTimeIncrement/>) }
</Box> </Box>
); );
}; };
......
...@@ -8,7 +8,7 @@ import appConfig from 'configs/app/config'; ...@@ -8,7 +8,7 @@ import appConfig from 'configs/app/config';
import flameIcon from 'icons/flame.svg'; import flameIcon from 'icons/flame.svg';
import getBlockReward from 'lib/block/getBlockReward'; import getBlockReward from 'lib/block/getBlockReward';
import { WEI } from 'lib/consts'; import { WEI } from 'lib/consts';
import dayjs from 'lib/date/dayjs'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link'; import link from 'lib/link/link';
import AccountListItemMobile from 'ui/shared/AccountListItemMobile'; import AccountListItemMobile from 'ui/shared/AccountListItemMobile';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
...@@ -18,11 +18,13 @@ import Utilization from 'ui/shared/Utilization'; ...@@ -18,11 +18,13 @@ import Utilization from 'ui/shared/Utilization';
interface Props { interface Props {
data: Block; data: Block;
isPending?: boolean; isPending?: boolean;
enableTimeIncrement?: boolean;
} }
const BlocksListItem = ({ data, isPending }: Props) => { const BlocksListItem = ({ data, isPending, enableTimeIncrement }: Props) => {
const spinnerEmptyColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200'); const spinnerEmptyColor = useColorModeValue('blackAlpha.200', 'whiteAlpha.200');
const { totalReward, burntFees, txFees } = getBlockReward(data); const { totalReward, burntFees, txFees } = getBlockReward(data);
const blockTimestampTimeAgo = useTimeAgoIncrement(data.timestamp, enableTimeIncrement);
return ( return (
<AccountListItemMobile rowGap={ 3 }> <AccountListItemMobile rowGap={ 3 }>
...@@ -36,7 +38,7 @@ const BlocksListItem = ({ data, isPending }: Props) => { ...@@ -36,7 +38,7 @@ const BlocksListItem = ({ data, isPending }: Props) => {
{ data.height } { data.height }
</Link> </Link>
</Flex> </Flex>
<Text variant="secondary"fontWeight={ 400 }>{ dayjs(data.timestamp).fromNow() }</Text> <Text variant="secondary"fontWeight={ 400 }>{ blockTimestampTimeAgo }</Text>
</Flex> </Flex>
<Flex columnGap={ 2 }> <Flex columnGap={ 2 }>
<Text fontWeight={ 500 }>Size</Text> <Text fontWeight={ 500 }>Size</Text>
......
...@@ -27,7 +27,8 @@ const BlocksTable = ({ data }: Props) => { ...@@ -27,7 +27,8 @@ const BlocksTable = ({ data }: Props) => {
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
{ data.map((item) => <BlocksTableItem key={ item.height } data={ item }/>) } { /* TODO prop "enableTimeIncrement" should be set to false for second and later pages */ }
{ data.map((item) => <BlocksTableItem key={ item.height } data={ item } enableTimeIncrement/>) }
</Tbody> </Tbody>
</Table> </Table>
</TableContainer> </TableContainer>
......
...@@ -7,7 +7,7 @@ import type { Block } from 'types/api/block'; ...@@ -7,7 +7,7 @@ import type { Block } from 'types/api/block';
import flameIcon from 'icons/flame.svg'; import flameIcon from 'icons/flame.svg';
import getBlockReward from 'lib/block/getBlockReward'; import getBlockReward from 'lib/block/getBlockReward';
import { WEI } from 'lib/consts'; import { WEI } from 'lib/consts';
import dayjs from 'lib/date/dayjs'; import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import link from 'lib/link/link'; import link from 'lib/link/link';
import AddressLink from 'ui/shared/address/AddressLink'; import AddressLink from 'ui/shared/address/AddressLink';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio'; import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
...@@ -16,10 +16,12 @@ import Utilization from 'ui/shared/Utilization'; ...@@ -16,10 +16,12 @@ import Utilization from 'ui/shared/Utilization';
interface Props { interface Props {
data: Block; data: Block;
isPending?: boolean; isPending?: boolean;
enableTimeIncrement?: boolean;
} }
const BlocksTableItem = ({ data, isPending }: Props) => { const BlocksTableItem = ({ data, isPending, enableTimeIncrement }: Props) => {
const { totalReward, burntFees, txFees } = getBlockReward(data); const { totalReward, burntFees, txFees } = getBlockReward(data);
const blockTimestampTimeAgo = useTimeAgoIncrement(data.timestamp, enableTimeIncrement);
return ( return (
<Tr> <Tr>
...@@ -35,7 +37,7 @@ const BlocksTableItem = ({ data, isPending }: Props) => { ...@@ -35,7 +37,7 @@ const BlocksTableItem = ({ data, isPending }: Props) => {
</Link> </Link>
</Tooltip> </Tooltip>
</Flex> </Flex>
<Text variant="secondary" mt={ 2 } fontWeight={ 400 }>{ dayjs(data.timestamp).fromNow() }</Text> <Text variant="secondary" mt={ 2 } fontWeight={ 400 }>{ blockTimestampTimeAgo }</Text>
</Td> </Td>
<Td fontSize="sm">{ data.size.toLocaleString('en') } bytes</Td> <Td fontSize="sm">{ data.size.toLocaleString('en') } bytes</Td>
<Td fontSize="sm"> <Td fontSize="sm">
......
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