Display time delays in referenda tooltip headers (#8575)

* Display time delays in referenda tooltip headers

* Adjust with estimated actual time
This commit is contained in:
Jaco 2022-12-19 09:54:02 +02:00 committed by GitHub
parent f65678f33e
commit 6bb0eae625
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 9 deletions

View File

@ -1,7 +1,8 @@
// Copyright 2017-2022 @polkadot/app-referenda authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ChartOptions } from 'chart.js';
import type { ChartOptions, ChartTypeRegistry, TooltipItem } from 'chart.js';
import type { TFunction } from 'react-i18next';
import type { PalletConvictionVotingTally, PalletRankedCollectiveTally, PalletReferendaReferendumInfoConvictionVotingTally, PalletReferendaReferendumInfoRankedCollectiveTally } from '@polkadot/types/lookup';
import type { BN } from '@polkadot/util';
import type { BaseReferendumProps as Props, CurveGraph, ReferendumProps } from '../types';
@ -10,8 +11,9 @@ import React, { useMemo } from 'react';
import styled from 'styled-components';
import { Chart, Columar, ExpandButton, LinkExternal } from '@polkadot/react-components';
import { useBestNumber, useToggle } from '@polkadot/react-hooks';
import { BN_MILLION, BN_THOUSAND, formatNumber, objectSpread } from '@polkadot/util';
import { useBestNumber, useBlockInterval, useToggle } from '@polkadot/react-hooks';
import { calcBlockTime } from '@polkadot/react-hooks/useBlockTime';
import { BN_MILLION, BN_THOUSAND, BN_ZERO, bnToBn, formatNumber, objectSpread } from '@polkadot/util';
import { useTranslation } from '../translate';
import Killed from './RefKilled';
@ -74,6 +76,27 @@ interface ChartProps extends ChartResult {
options: typeof OPTIONS;
}
function tooltipTitle (bestNumber: BN, blockInterval: BN, t: TFunction): (items: TooltipItem<keyof ChartTypeRegistry>[]) => string | string[] {
return (items: TooltipItem<keyof ChartTypeRegistry>[]): string | string[] => {
const label = items[0].label;
try {
const blocks = bnToBn(label.replace(/,/g, '')).sub(bestNumber);
if (blocks.gt(BN_ZERO)) {
const when = new Date(Date.now() + blocks.mul(blockInterval).toNumber()).toLocaleString();
const calc = calcBlockTime(blockInterval, blocks, t);
return [`#${label}`, t('{{when}} (est.)', { replace: { when } }), calc[1]];
}
} catch {
// ignore
}
return `#${label}`;
};
}
function getChartResult (totalEligible: BN, isConvictionVote: boolean, info: PalletReferendaReferendumInfoConvictionVotingTally | PalletReferendaReferendumInfoRankedCollectiveTally, trackGraph: CurveGraph): ChartResultExt[] | null {
if (totalEligible && isConvictionVote && info.isOngoing) {
const ongoing = info.asOngoing;
@ -124,7 +147,7 @@ function getChartResult (totalEligible: BN, isConvictionVote: boolean, info: Pal
return null;
}
function getChartProps (bestNumber: BN, chartProps: ChartResultExt[]): ChartProps[] {
function getChartProps (bestNumber: BN, chartProps: ChartResultExt[], tooltipTitle: (items: TooltipItem<keyof ChartTypeRegistry>[]) => string | string[]): ChartProps[] {
return chartProps.map(({ changeX, currentY, labels, progress, since, trackGraph: { x }, values }, index): ChartProps => {
const maxX = labels.length;
const currentX = maxX * (
@ -179,6 +202,11 @@ function getChartProps (bestNumber: BN, chartProps: ChartResultExt[]): ChartProp
}
: {}
)
},
tooltip: {
callbacks: {
title: tooltipTitle
}
}
}
}, OPTIONS),
@ -191,6 +219,7 @@ function getChartProps (bestNumber: BN, chartProps: ChartResultExt[]): ChartProp
function Referendum (props: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const bestNumber = useBestNumber();
const blockInterval = useBlockInterval();
const { activeIssuance, className = '', palletReferenda, value: { id, info, isConvictionVote, trackGraph } } = props;
const [isExpanded, toggleExpanded] = useToggle(false);
@ -205,8 +234,8 @@ function Referendum (props: Props): React.ReactElement<Props> {
);
const chartProps = useMemo(
() => bestNumber && chartResult && getChartProps(bestNumber, chartResult),
[bestNumber, chartResult]
() => bestNumber && chartResult && getChartProps(bestNumber, chartResult, tooltipTitle(bestNumber, blockInterval, t)),
[bestNumber, blockInterval, chartResult, t]
);
const chartLegend = useMemo(

View File

@ -13,9 +13,9 @@ import { createNamedHook } from './createNamedHook';
import { useTranslation } from './translate';
import { useBlockInterval } from './useBlockInterval';
type Result = [number, string, Time];
type Result = [blockInterval: number, timeStr: string, time: Time];
function calcResult (blockTime: BN, blocks: BN, t: TFunction): Result {
export function calcBlockTime (blockTime: BN, blocks: BN, t: TFunction): Result {
// in the case of excessively large locks, limit to the max JS integer value
const value = bnMin(BN_MAX_INTEGER, blockTime.mul(blocks)).toNumber();
@ -59,7 +59,7 @@ function useBlockTimeImpl (blocks: number | BN = BN_ONE, apiOverride?: ApiPromis
const blockTime = useBlockInterval(apiOverride);
return useMemo(
() => calcResult(blockTime, bnToBn(blocks), t),
() => calcBlockTime(blockTime, bnToBn(blocks), t),
[blockTime, blocks, t]
);
}