fix(@cockpit/explorers): consistently display "Mined on" timestamps

Adjust the API endpoints to augment transaction objects with a timestamp
property from their corresponding blocks. This removes the necessity to copy
the timestamp property from a block to its transactions in the client.

Introduce a `formatTimestampForDisplay` util function in Cockpit for
consistently transforming timestamps into relative or absolute dates, depending
on whether a date is sometime during the last day.
This commit is contained in:
Michael Bradley, Jr 2019-07-02 14:24:18 -05:00 committed by Michael Bradley
parent 7d27125eed
commit 52d54f0d87
5 changed files with 24 additions and 11 deletions

View File

@ -610,6 +610,7 @@ class BlockchainConnector {
.then(receipts => { .then(receipts => {
block.transactions.forEach((tx, index) => { block.transactions.forEach((tx, index) => {
tx['receipt'] = receipts[index]; tx['receipt'] = receipts[index];
tx['timestamp'] = block.timestamp;
}); });
blocks.push(block); blocks.push(block);
eachCb(); eachCb();
@ -655,7 +656,15 @@ class BlockchainConnector {
} }
getBlock(blockNumber, cb) { getBlock(blockNumber, cb) {
this.web3.eth.getBlock(blockNumber, true, cb); this.web3.eth.getBlock(blockNumber, true, (err, block) => {
if (err) return cb(err);
if (block.transactions && block.transactions.length) {
block.transactions.forEach(tx => {
tx.timestamp = block.timestamp;
});
}
cb(null, block);
});
} }
getTransactionByHash(hash, cb) { getTransactionByHash(hash, cb) {

View File

@ -3,6 +3,7 @@ import {Link} from "react-router-dom";
import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap'; import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Pagination from './Pagination'; import Pagination from './Pagination';
import {formatTimestampForDisplay} from '../utils/presentation';
import CardTitleIdenticon from './CardTitleIdenticon'; import CardTitleIdenticon from './CardTitleIdenticon';
@ -25,7 +26,7 @@ const Blocks = ({blocks, changePage, currentPage, numberOfPages}) => (
<Row> <Row>
<Col> <Col>
<strong>Mined on:</strong> <strong>Mined on:</strong>
<div>{new Date(block.timestamp * 1000).toLocaleString()}</div> <div>{formatTimestampForDisplay(block.timestamp)}</div>
</Col> </Col>
<Col> <Col>
<strong>Gas Used</strong> <strong>Gas Used</strong>

View File

@ -2,8 +2,7 @@ import React from 'react';
import {Link} from "react-router-dom"; import {Link} from "react-router-dom";
import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap'; import {Row, Col, Card, CardHeader, CardBody} from 'reactstrap';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import isToday from 'date-fns/is_today'; import {formatTimestampForDisplay} from '../utils/presentation';
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
import DebugButton from './DebugButton'; import DebugButton from './DebugButton';
import CardTitleIdenticon from './CardTitleIdenticon'; import CardTitleIdenticon from './CardTitleIdenticon';
@ -50,12 +49,7 @@ const Transactions = ({transactions, contracts, changePage, currentPage, numberO
</Col> </Col>
<Col md={6}> <Col md={6}>
<strong>Mined on:</strong> <strong>Mined on:</strong>
<div> <div>{formatTimestampForDisplay(transaction.timestamp)}</div>
{isToday(new Date(transaction.timestamp * 1000)) ?
distanceInWordsToNow(new Date(transaction.timestamp * 1000), {addSuffix: true}) :
new Date(transaction.timestamp * 1000).toLocaleString()
}
</div>
</Col> </Col>
</Row> </Row>
</div> </div>

View File

@ -97,7 +97,6 @@ class TransactionsContainer extends Component {
const txsLength = txs.length; const txsLength = txs.length;
block.transactions.forEach((tx, idx) => { block.transactions.forEach((tx, idx) => {
txs[txsLength + idx + offset] = tx; txs[txsLength + idx + offset] = tx;
txs[txsLength + idx + offset].timestamp = block.timestamp;
}); });
return txs; return txs;
}, []); }, []);

View File

@ -1,3 +1,6 @@
import isToday from 'date-fns/is_today';
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
export function formatContractForDisplay(contract) { export function formatContractForDisplay(contract) {
let address = (contract.address || contract.deployedAddress); let address = (contract.address || contract.deployedAddress);
let state = 'Deployed'; let state = 'Deployed';
@ -17,3 +20,10 @@ export function formatContractForDisplay(contract) {
} }
return {address, state, stateColor}; return {address, state, stateColor};
} }
export function formatTimestampForDisplay(timestamp) {
if (isToday(new Date(timestamp * 1000))) {
return distanceInWordsToNow(new Date(timestamp * 1000), {addSuffix: true});
}
return new Date(timestamp * 1000).toLocaleString();
}