Added ago timers

This commit is contained in:
maciejhirsz
2018-07-05 17:04:00 +02:00
parent 81ef3ee14e
commit 01da7dfc47
19 changed files with 200 additions and 48 deletions
+75
View File
@@ -0,0 +1,75 @@
import * as React from 'react';
import './Tile.css';
import { timestamp, Types } from '@dotstats/common';
export namespace Ago {
export interface Props {
when: Types.Timestamp,
}
export interface State {
now: Types.Timestamp,
}
}
const tickers = new Map<Ago, (ts: Types.Timestamp) => void>();
function tick() {
const now = timestamp();
for (const ticker of tickers.values()) {
ticker(now);
}
setTimeout(tick, 100);
}
tick();
export namespace Ago {
export interface State {
now: Types.Timestamp
}
}
export class Ago extends React.Component<Ago.Props, Ago.State> {
public static timeDiff = 0 as Types.Milliseconds;
public state: Ago.State;
constructor(props: Ago.Props) {
super(props);
this.state = {
now: (timestamp() + Ago.timeDiff) as Types.Timestamp
};
}
public componentWillMount() {
tickers.set(this, (now) => {
this.setState({
now: (now + Ago.timeDiff) as Types.Timestamp
});
})
}
public componentWillUnmount() {
tickers.delete(this);
}
public render() {
const ago = Math.max(this.state.now - this.props.when, 0) / 1000;
let agoStr: string;
if (ago < 10) {
agoStr = `${ago.toFixed(1)}s`;
} else if (ago < 60) {
agoStr = `${ago | 0}s`;
} else {
agoStr = `${ ago / 60 | 0}m`;
}
return <span title={new Date(this.props.when).toUTCString()}>{agoStr} ago</span>
}
}
+11
View File
@@ -0,0 +1,11 @@
.Icon {
fill: currentColor;
height: 1em;
vertical-align: middle;
display: inline-block;
}
.Icon svg {
width: auto;
height: 1em;
}
+23
View File
@@ -0,0 +1,23 @@
import * as React from 'react';
import ReactSVG from 'react-svg';
import './Icon.css';
export interface Props {
src: string,
alt: string,
className?: string,
};
export class Icon extends React.Component<{}, Props> {
public props: Props;
public shouldComponentUpdate() {
return false;
}
public render() {
const { alt, className, src } = this.props;
return <ReactSVG title={alt} className={`Icon ${ className || '' }`} path={src} />;
}
}
+32
View File
@@ -0,0 +1,32 @@
import * as React from 'react';
import { formatNumber, trimHash } from '../utils';
import { Ago } from './Ago';
import { Types } from '@dotstats/common';
export namespace Node {
export interface Props {
id: Types.NodeId,
nodeDetails: Types.NodeDetails,
nodeStats: Types.NodeStats,
blockDetails: Types.BlockDetails,
}
}
export function Node(props: Node.Props) {
const [name, implementation, version] = props.nodeDetails;
const [height, hash, blockTime, blockTimestamp] = props.blockDetails;
const [peers, txcount] = props.nodeStats;
return (
<tr>
<td>{name}</td>
<td>{implementation} v{version}</td>
<td>{peers}</td>
<td>{txcount}</td>
<td>#{formatNumber(height)}</td>
<td><span title={hash}>{trimHash(hash, 16)}</span></td>
<td>{(blockTime / 1000).toFixed(3)}s</td>
<td><Ago when={blockTimestamp} /></td>
</tr>
);
}
@@ -0,0 +1,7 @@
.Tile {
font-size: 2.5em;
padding: 20px;
text-align: left;
width: 7em;
display: inline-block;
}
+19
View File
@@ -0,0 +1,19 @@
import * as React from 'react';
import './Tile.css';
import { Icon } from './Icon';
export namespace Tile {
export interface Props {
title: string,
icon: string,
children?: React.ReactNode,
}
}
export function Tile(props: Tile.Props) {
return (
<div className="Tile">
<Icon src={props.icon} alt={props.title} /> {props.children}
</div>
);
}
@@ -0,0 +1,4 @@
export * from './Icon';
export * from './Node';
export * from './Tile';
export * from './Ago';