mirror of
https://github.com/pezkuwichain/pezkuwi-apps.git
synced 2026-05-07 13:07:58 +00:00
75 lines
2.4 KiB
TypeScript
75 lines
2.4 KiB
TypeScript
// Copyright 2017-2026 @pezkuwi/react-hooks authors & contributors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
import type { ApiPromise } from '@pezkuwi/api';
|
|
import type { BlockNumber, Votes } from '@pezkuwi/types/interfaces';
|
|
import type { BN } from '@pezkuwi/util';
|
|
import type { CollectiveType } from './types.js';
|
|
|
|
import { useMemo } from 'react';
|
|
|
|
import { isFunction } from '@pezkuwi/util';
|
|
|
|
import { createNamedHook } from './createNamedHook.js';
|
|
import { useApi } from './useApi.js';
|
|
import { useBestNumber } from './useBestNumber.js';
|
|
|
|
interface State {
|
|
hasFailed: boolean;
|
|
hasPassed: boolean;
|
|
isCloseable: boolean;
|
|
isVoteable: boolean;
|
|
remainingBlocks: BN | null;
|
|
}
|
|
|
|
const DEFAULT_STATUS = { hasFailed: false, hasPassed: false, isCloseable: false, isVoteable: false, remainingBlocks: null };
|
|
|
|
function getStatus (api: ApiPromise, bestNumber: BlockNumber, votes: Votes, numMembers: number, section: CollectiveType): State {
|
|
const [instance] = api.registry.getModuleInstances(api.runtimeVersion.specName.toString(), section) || [section];
|
|
const modLocation = isFunction(api.tx[instance as 'technicalCommittee']?.close)
|
|
? instance
|
|
: null;
|
|
|
|
if (!votes.end || !modLocation) {
|
|
return {
|
|
hasFailed: false,
|
|
hasPassed: false,
|
|
isCloseable: false,
|
|
isVoteable: true,
|
|
remainingBlocks: null
|
|
};
|
|
}
|
|
|
|
const isEnd = bestNumber.gte(votes.end);
|
|
// let approved = yes_votes >= voting.threshold;
|
|
const hasPassed = votes.threshold.lten(votes.ayes.length);
|
|
// let disapproved = seats.saturating_sub(no_votes) < voting.threshold;
|
|
const hasFailed = votes.threshold.gtn(Math.abs(numMembers - votes.nays.length));
|
|
|
|
return {
|
|
hasFailed,
|
|
hasPassed,
|
|
isCloseable: api.tx[modLocation].close.meta.args.length === 4 // current-generation
|
|
? isEnd || hasPassed || hasFailed
|
|
: isEnd,
|
|
isVoteable: !isEnd,
|
|
remainingBlocks: isEnd
|
|
? null
|
|
: votes.end.sub(bestNumber)
|
|
};
|
|
}
|
|
|
|
function useVotingStatusImpl (votes: Votes | null | undefined, numMembers: number, section: CollectiveType): State {
|
|
const { api } = useApi();
|
|
const bestNumber = useBestNumber();
|
|
|
|
return useMemo(
|
|
() => bestNumber && votes
|
|
? getStatus(api, bestNumber, votes, numMembers, section)
|
|
: DEFAULT_STATUS,
|
|
[api, bestNumber, numMembers, section, votes]
|
|
);
|
|
}
|
|
|
|
export const useVotingStatus = createNamedHook('useVotingStatus', useVotingStatusImpl);
|