Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: referenda tracks Max #1591

Merged
merged 2 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

/* eslint-disable react/jsx-max-props-per-line */
/* eslint-disable react/jsx-first-prop-new-line */

import type { DecidingCount } from '../../hooks/useDecidingCount';
import type { Track } from './utils/types';

import { Container, Divider, Grid, type SxProps, type Theme, Typography, useTheme } from '@mui/material';
import useMediaQuery from '@mui/material/useMediaQuery';
import React from 'react';

import { ShortAddress, ShowBalance, ShowValue } from '../../components';
import { useApi, useDecimal, useToken, useTranslation } from '../../hooks';
import { DecidingCount } from '../../hooks/useDecidingCount';
import { Track } from '../../hooks/useTracks';
import { useInfo, useTranslation } from '../../hooks';
import useStyles from './styles/styles';
import { kusama } from './tracks/kusama';
import { polkadot } from './tracks/polkadot';
import { blockToX, toSnakeCase, toTitleCase } from './utils/util';
import { Separator } from './AllReferendaStats';
import ThresholdCurves from './Curves';
Expand All @@ -27,20 +28,19 @@ interface Props {
track: Track | undefined;
}

const findItemDecidingCount = (item: string, decidingCounts: DecidingCount[] | undefined): number | undefined => {
const findItemDecidingCount = (item: string, decidingCounts: DecidingCount | undefined): number => {
if (!decidingCounts) {
return undefined;
return 0;
}

const filtered = decidingCounts.referenda.concat(decidingCounts.fellowship).find(([key]) =>
key === item.toLowerCase().replace(' ', '_') ||
key === item.toLowerCase());

return filtered?.[1];
return filtered?.[1] || 0;
};

export const LabelValue = ({ asShortAddress, label, value, noBorder, style, valueStyle = { fontSize: '18px', fontWeight: 500 }, labelStyle = { fontSize: '16px', fontWeight: 400 } }
: { asShortAddress?: boolean, label: string, labelStyle?: SxProps<Theme>, noBorder?: boolean, style?: SxProps<Theme>, value: any, valueStyle?: SxProps<Theme> }) => {
export const LabelValue = ({ asShortAddress, label, labelStyle = { fontSize: '16px', fontWeight: 400 }, noBorder, style, value, valueStyle = { fontSize: '18px', fontWeight: 500 } }: { asShortAddress?: boolean, label: string, labelStyle?: SxProps<Theme>, noBorder?: boolean, style?: SxProps<Theme>, value: unknown, valueStyle?: SxProps<Theme> }) => {
const theme = useTheme();

return (
Expand All @@ -50,25 +50,26 @@ export const LabelValue = ({ asShortAddress, label, value, noBorder, style, valu
borderBottomColor: `${theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.2)' : theme.palette.text.disabled}`, ...style
}}>
<Grid item sx={{ ...labelStyle }}>
<Typography >
<Typography>
{label}
</Typography>
</Grid>
<Grid item sx={{ '> .MuiSkeleton-root': { display: 'block' }, ...valueStyle }}>
{asShortAddress
? <ShortAddress address={value} showCopy charsCount={30} />
: <ShowValue value={value} />
? <ShortAddress address={value as string} charsCount={30} showCopy />
: <ShowValue value={value as string | number} />
}
</Grid>
</Grid>
);
};

export function TrackStats({ address, decidingCounts, selectedSubMenu, topMenu, track }: Props): React.ReactElement<Props> {
export function TrackStats ({ address, decidingCounts, selectedSubMenu, topMenu, track }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const api = useApi(address);
const decimal = useDecimal(address);
const token = useToken(address);

const { api, decimal, token } = useInfo(address);

const chainGovInfo = token === 'KSM' ? kusama : polkadot;
const firstBreakpoint = !useMediaQuery('(min-width:1000px)');
const secondBreakpoint = !useMediaQuery('(min-width:675px)');
const styles = useStyles(firstBreakpoint, secondBreakpoint);
Expand All @@ -88,15 +89,15 @@ export function TrackStats({ address, decidingCounts, selectedSubMenu, topMenu,
</Grid>
<Grid container item>
<Typography color='text.disableText' fontSize={16} fontWeight={400}>
{kusama[topMenu.toLocaleLowerCase()].find(({ name }) => name === snakeCaseTrackName)?.text}
{chainGovInfo[topMenu.toLocaleLowerCase()].find(({ name }) => name === snakeCaseTrackName)?.text}
</Typography>
</Grid>
</Grid>
<Grid container item justifyContent='space-between'>
<Grid container item sx={styles.trackStatsChild}>
<LabelValue
label={t('Remaining Slots')}
value={decidingCounts && track?.[1]?.maxDeciding && `${track[1].maxDeciding - findItemDecidingCount(selectedSubMenu, decidingCounts)} out of ${track?.[1]?.maxDeciding}`}
value={decidingCounts && track?.[1]?.maxDeciding && `${track[1].maxDeciding as unknown as number - findItemDecidingCount(selectedSubMenu, decidingCounts)} out of ${track?.[1]?.maxDeciding as unknown as number}`}
/>
<LabelValue
label={t('Prepare Period')}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2017-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

import type { TrackInfo } from './types';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright 2017-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

import type { TrackInfo } from './types.js';

Expand Down Expand Up @@ -32,7 +31,7 @@ const SPEND_LIMITS = {
};

export const polkadot: Record<string, TrackInfo[]> = {
fellowshipReferenda: [
fellowship: [
{
compare: compareFellowshipRank(0),
id: 0,
Expand Down Expand Up @@ -206,4 +205,4 @@ export const polkadot: Record<string, TrackInfo[]> = {
text: `Origin able to spend up to ${SPEND_LIMITS.BigSpender} from the treasury at once`
}
]
};
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright 2017-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

import { BN, formatBalance } from '@polkadot/util';
import type { BN } from '@polkadot/util';

import { formatBalance } from '@polkadot/util';

interface FormatOptions {
decimals: number;
Expand All @@ -11,15 +12,15 @@ interface FormatOptions {
withUnit: string;
}

export function formatSpendFactory(options: FormatOptions): (mul: number, value: BN) => string {
export function formatSpendFactory (options: FormatOptions): (mul: number, value: BN) => string {
return (mul: number, value: BN): string => {
// We lose the decimals here... depending on chain config, this could be non-optimal
// (A simple formatBalance(value.muln(mul), FMT_OPTS) formats to 4 decimals)
return `${formatBalance(value.muln(mul), options).split('.')[0]} ${options.withUnit}`;
};
}

export function compareFellowshipRank(trackId: number): (rank: BN) => boolean {
export function compareFellowshipRank (trackId: number): (rank: BN) => boolean {
return (rank: BN): boolean =>
rank.gten(trackId);
}
47 changes: 26 additions & 21 deletions packages/extension-polkagate/src/hooks/useDecidingCount.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,70 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

import type { u32 } from '@polkadot/types';

import { useEffect, useMemo, useState } from 'react';

import useApi from './useApi';
import useChain from './useChain';
import useInfo from './useInfo';
import useTracks from './useTracks';

export type Count = [string, number];

export type DecidingCount = { referenda: Count[]; fellowship: Count[]; };
export interface DecidingCount {
referenda: Count[];
fellowship: Count[];
}

export default function useDecidingCount (address: string | undefined): DecidingCount | undefined {
const { api, chain } = useInfo(address);

export default function useDecidingCount(address: string | undefined): DecidingCount | undefined {
const api = useApi(address);
const chain = useChain(address);
const { fellowshipTracks, tracks } = useTracks(address);

const [counts, setCounts] = useState<DecidingCount | undefined>(undefined);
const trackIds = useMemo(() => tracks?.map(([id, { name }]) => [id, name]), [tracks]);
const fellowshipTrackIds = useMemo(() => fellowshipTracks?.map(([id, { name }]) => [id, name]), [fellowshipTracks]);

useEffect(() => {
async function fetchDecidingCounts() {
async function fetchDecidingCounts () {
if ((!trackIds && !fellowshipTrackIds) || !api) {
return;
}

try {
let allCount = 0;
const fellowshipDecidingCounts: Count[] = [];
let decidingCounts;
let decidingCounts: Count[] = [];
let fellowshipCounts;

if (trackIds) {
const counts = await Promise.all(trackIds.map(([id]) => api.query.referenda.decidingCount(id)));
const counts = await Promise.all(trackIds.map(([id]) => api.query['referenda']['decidingCount'](id))) as unknown as u32[];

decidingCounts = counts.map((count, index) => {
const _count = count.toNumber();

decidingCounts = counts.map((count, index): Count => {
if (!['whitelisted_caller', 'fellowship_admin'].includes(trackIds[index][1])) {
allCount += count.toNumber();
if (!['whitelisted_caller', 'fellowship_admin'].includes(trackIds[index][1] as unknown as string)) {
allCount += _count;
} else {
fellowshipDecidingCounts.push([String(trackIds[index][1]), count.toNumber() as number]);
fellowshipDecidingCounts.push([String(trackIds[index][1]), _count]);
}

return [String(trackIds[index][1]), count.toNumber() as number];
return [String(trackIds[index][1]), _count];
});

decidingCounts.push(['all', allCount]);
}

if (fellowshipTrackIds) {
fellowshipCounts = await Promise.all(fellowshipTracks.map(([id]) => api.query.fellowshipReferenda.decidingCount(id)));
if (fellowshipTrackIds && fellowshipTracks) {
fellowshipCounts = await Promise.all(fellowshipTracks.map(([id]) => api.query['fellowshipReferenda']['decidingCount'](id))) as unknown as u32[];

allCount = 0;
const Counts = fellowshipCounts.map((c, index): Count => {
const counts = fellowshipCounts.map((c, index) => {
allCount += c.toNumber();

return [String(fellowshipTrackIds[index][1]), c.toNumber() as number];
return [String(fellowshipTrackIds[index][1]), c.toNumber()] as [string, number];
});

fellowshipDecidingCounts.push(...Counts);
fellowshipDecidingCounts.push(...counts);
fellowshipDecidingCounts.push(['all', allCount]);
}

Expand All @@ -75,7 +80,7 @@ export default function useDecidingCount(address: string | undefined): DecidingC
return;
}

fetchDecidingCounts();
fetchDecidingCounts().catch(console.error);
}, [api, chain?.genesisHash, fellowshipTrackIds, fellowshipTracks, trackIds]);

return counts;
Expand Down
9 changes: 3 additions & 6 deletions packages/extension-polkagate/src/hooks/useTracks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ import type { Track } from '../fullscreen/governance/utils/types';

import { useMemo } from 'react';

import { useApi, useChain } from '.';
import { useInfo } from '.';

interface TracksType { fellowshipTracks: Track[] | undefined, tracks: Track[] | undefined }

export default function useTracks (address: string | undefined): TracksType {
const api = useApi(address);
const chain = useChain(address);
// const chainName = useChainName(address);
// const [savedTracks, setSavedTracks] = useState<string[]>([]);
const { api, chain } = useInfo(address);

const tracks: TracksType = useMemo(() => {
if (chain?.genesisHash !== api?.genesisHash?.toString()) {
Expand All @@ -29,5 +26,5 @@ export default function useTracks (address: string | undefined): TracksType {
};
}, [api, chain?.genesisHash]);

return tracks;// || savedTracks;
return tracks;
}
Loading