mirror of
https://github.com/pezkuwichain/pezkuwi-telemetry.git
synced 2026-06-12 00:41:09 +00:00
9730c730f3
* feat: Adding a show-all-chains button * feat: Show all-chains overlay selector
176 lines
4.5 KiB
TypeScript
176 lines
4.5 KiB
TypeScript
import * as React from 'react';
|
|
import { Types, SortedCollection } from '@dotstats/common';
|
|
import { AllChains, Chains, Chain, Ago, OfflineIndicator } from './components';
|
|
import { Connection } from './Connection';
|
|
import { PersistentObject, PersistentSet } from './persist';
|
|
import { State, Node, ChainData } from './state';
|
|
import { getHashData } from './utils';
|
|
import stable from 'stable';
|
|
|
|
import './App.css';
|
|
|
|
export default class App extends React.Component<{}, State> {
|
|
public state: State;
|
|
private readonly settings: PersistentObject<State.Settings>;
|
|
private readonly pins: PersistentSet<Types.NodeName>;
|
|
private readonly connection: Promise<Connection>;
|
|
|
|
constructor(props: {}) {
|
|
super(props);
|
|
|
|
this.settings = new PersistentObject(
|
|
'settings',
|
|
{
|
|
validator: true,
|
|
location: true,
|
|
implementation: true,
|
|
networkId: false,
|
|
peers: true,
|
|
txs: true,
|
|
cpu: true,
|
|
mem: true,
|
|
upload: false,
|
|
download: false,
|
|
blocknumber: true,
|
|
blockhash: true,
|
|
blocktime: true,
|
|
finalized: false,
|
|
finalizedhash: false,
|
|
blockpropagation: true,
|
|
blocklasttime: false,
|
|
networkstate: false,
|
|
},
|
|
(settings) => this.setState({ settings })
|
|
);
|
|
|
|
this.pins = new PersistentSet<Types.NodeName>('pinned_names', (pins) => {
|
|
const { nodes } = this.state;
|
|
|
|
nodes.mutEachAndSort((node) => node.setPinned(pins.has(node.name)));
|
|
|
|
this.setState({ nodes, pins });
|
|
});
|
|
|
|
const { tab = '' } = getHashData();
|
|
|
|
this.state = {
|
|
status: 'offline',
|
|
best: 0 as Types.BlockNumber,
|
|
finalized: 0 as Types.BlockNumber,
|
|
consensusInfo: new Array() as Types.ConsensusInfo,
|
|
displayConsensusLoadingScreen: true,
|
|
authorities: new Array() as Types.Authorities,
|
|
authoritySetId: null,
|
|
sendFinality: false,
|
|
blockTimestamp: 0 as Types.Timestamp,
|
|
blockAverage: null,
|
|
timeDiff: 0 as Types.Milliseconds,
|
|
subscribed: null,
|
|
chains: new Map(),
|
|
nodes: new SortedCollection(Node.compare),
|
|
settings: this.settings.raw(),
|
|
pins: this.pins.get(),
|
|
tab,
|
|
};
|
|
|
|
this.connection = Connection.create(this.pins, (changes) => {
|
|
if (changes) {
|
|
this.setState(changes);
|
|
}
|
|
|
|
return this.state;
|
|
});
|
|
}
|
|
|
|
public render() {
|
|
const { timeDiff, subscribed, status, tab } = this.state;
|
|
const chains = this.chains();
|
|
|
|
Ago.timeDiff = timeDiff;
|
|
|
|
if (chains.length === 0) {
|
|
return (
|
|
<div className="App App-no-telemetry">
|
|
<OfflineIndicator status={status} />
|
|
Waiting for telemetry…
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const overlay = tab === 'all-chains'
|
|
? <AllChains chains={chains} subscribed={subscribed} connection={this.connection} />
|
|
: null;
|
|
|
|
return (
|
|
<div className="App">
|
|
<OfflineIndicator status={status} />
|
|
<Chains chains={chains} subscribed={subscribed} connection={this.connection} />
|
|
<Chain appState={this.state} connection={this.connection} settings={this.settings} pins={this.pins} />
|
|
{overlay}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
public componentWillMount() {
|
|
window.addEventListener('keydown', this.onKeyPress);
|
|
window.addEventListener('hashchange', this.onHashChange);
|
|
}
|
|
|
|
public componentWillUnmount() {
|
|
window.removeEventListener('keydown', this.onKeyPress);
|
|
window.removeEventListener('hashchange', this.onHashChange);
|
|
}
|
|
|
|
private onKeyPress = (event: KeyboardEvent) => {
|
|
if (event.keyCode !== 9) { // TAB KEY
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
|
|
const { subscribed } = this.state;
|
|
const chains = Array.from(this.state.chains.keys());
|
|
|
|
let index = 0;
|
|
|
|
if (subscribed) {
|
|
index = (chains.indexOf(subscribed) + 1) % chains.length;
|
|
|
|
// Do nothing if it's the same chain
|
|
if (chains[index] === subscribed) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.connection.then((connection) => {
|
|
connection.subscribe(chains[index]);
|
|
})
|
|
}
|
|
|
|
private onHashChange = (event: Event) => {
|
|
const { tab = '' } = getHashData();
|
|
|
|
this.setState({ tab });
|
|
}
|
|
|
|
private chains(): ChainData[] {
|
|
return stable
|
|
.inplace(
|
|
Array.from(this.state.chains.entries()),
|
|
(a, b) => {
|
|
if (a[0] === 'Alexander') {
|
|
return -1;
|
|
}
|
|
|
|
if (b[0] === 'Alexander') {
|
|
return 1;
|
|
}
|
|
|
|
return b[1] - a[1];
|
|
}
|
|
)
|
|
.map(([label, nodeCount]) => ({ label, nodeCount }));
|
|
}
|
|
|
|
}
|