// Source code for the Substrate Telemetry Server.
// Copyright (C) 2021 Parity Technologies (UK) Ltd.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
import * as React from 'react';
import Measure, { BoundingRect, ContentRect } from 'react-measure';
import { Types, Maybe } from '../../common';
import { Icon, Tooltip, PolkadotIcon } from '../';
import Jdenticon from './Jdenticon';
import checkIcon from '../../icons/check.svg';
import finalizedIcon from '../../icons/finalized.svg';
import hatchingIcon from '../../icons/hatching.svg';
import './ConsensusBlock.css';
export namespace ConsensusBlock {
export interface Props {
authorities: Types.Authority[];
authoritySetId: Maybe;
height: Types.BlockNumber;
firstInRow: boolean;
lastInRow: boolean;
compact: boolean;
measure: boolean;
consensusView: Types.ConsensusView;
changeBlocks: (first: boolean, boundsRect: BoundingRect) => void;
}
}
export class ConsensusBlock extends React.Component {
public state = {
lastConsensusView: '',
};
public shouldComponentUpdate(nextProps: ConsensusBlock.Props): boolean {
if (
this.props.authorities.length === 0 &&
nextProps.authorities.length === 0
) {
return false;
}
const positionInfoChanged =
this.props.firstInRow !== nextProps.firstInRow ||
this.props.lastInRow !== nextProps.lastInRow;
if (positionInfoChanged) {
return true;
}
const newConsensusInfo =
JSON.stringify(nextProps.consensusView) !== this.state.lastConsensusView;
if (newConsensusInfo) {
return true;
}
return false;
}
public render() {
this.state.lastConsensusView = JSON.stringify(this.props.consensusView);
const finalizedByWhom = this.props.authorities.filter((authority) =>
this.isFinalized(authority)
);
const ratio = finalizedByWhom.length + '/' + this.props.authorities.length;
let titleFinal = {ratio};
const majorityFinalized =
finalizedByWhom.length / this.props.authorities.length >= 2 / 3;
if (majorityFinalized && !this.props.compact) {
titleFinal = FINAL;
} else if (majorityFinalized && this.props.compact) {
const hash = this.getFinalizedHash(finalizedByWhom[0]);
titleFinal = (
);
}
const handleOnResize = (contentRect: ContentRect) => {
this.props.changeBlocks(
this.props.firstInRow,
contentRect.bounds as BoundingRect
);
};
const get = (measureRef: Maybe<(ref: Element | null) => void>) => {
return (