diff --git a/packages/desktop/views/dashboard/governance/components/ProposalQuestion.svelte b/packages/desktop/views/dashboard/governance/components/ProposalQuestion.svelte index cacb6edc86..ca4874b36a 100644 --- a/packages/desktop/views/dashboard/governance/components/ProposalQuestion.svelte +++ b/packages/desktop/views/dashboard/governance/components/ProposalQuestion.svelte @@ -5,7 +5,11 @@ import { Icon, IconName, Text, TooltipIcon } from '@bloomwalletio/ui' import { ABSTAIN_VOTE_VALUE } from '@contexts/governance/constants' - import { getPercentagesFromAnswerStatuses, IProposalAnswerPercentages } from '@contexts/governance' + import { + getPercentagesFromAnswerStatuses, + getProjectedPercentages, + IProposalAnswerPercentages, + } from '@contexts/governance' import { selectedProposal } from '@contexts/governance/stores' export let onQuestionClick: (questionIndex: number) => void @@ -18,12 +22,15 @@ export let selectedAnswerValue: number = undefined export let votedAnswerValue: number = undefined export let isLoading: boolean = false + export let projected: boolean = false let percentages: IProposalAnswerPercentages = {} let winnerAnswerIndex: number $: answers = [...(question?.answers ?? []), { value: 0, text: 'Abstain', additionalInfo: '' }] - $: percentages = getPercentagesFromAnswerStatuses(answerStatuses) + $: percentages = projected + ? getProjectedPercentages(answerStatuses) + : getPercentagesFromAnswerStatuses(answerStatuses) $: disabled = $selectedProposal?.status === EventStatus.Upcoming || $selectedProposal?.status === EventStatus.Ended || diff --git a/packages/desktop/views/dashboard/governance/components/proposal-details/ProposalQuestionListPane.svelte b/packages/desktop/views/dashboard/governance/components/proposal-details/ProposalQuestionListPane.svelte index b56fdc68d4..a9db06ea26 100644 --- a/packages/desktop/views/dashboard/governance/components/proposal-details/ProposalQuestionListPane.svelte +++ b/packages/desktop/views/dashboard/governance/components/proposal-details/ProposalQuestionListPane.svelte @@ -5,7 +5,7 @@ VotingEventPayload, TrackedParticipationOverview, } from '@iota/sdk/out/types' - import { Alert, Button } from '@bloomwalletio/ui' + import { Alert, Button, Text, Toggle, TooltipIcon } from '@bloomwalletio/ui' import { getVotingEvent } from '@contexts/governance/actions' import { ABSTAIN_VOTE_VALUE } from '@contexts/governance/constants' import { @@ -37,6 +37,7 @@ let openedQuestionIndex: number = -1 let isUpdatingVotedAnswerValues: boolean = false let lastAction: 'vote' | 'stopVote' + let projected: boolean = false $: selectedProposalOverview = $participationOverviewForSelectedAccount?.participations?.[$selectedProposal?.id] $: trackedParticipations = Object.values(selectedProposalOverview ?? {}) @@ -179,7 +180,15 @@ }) - + + {@const isVotable = [EventStatus.Commencing, EventStatus.Holding].includes($selectedProposal?.status)} + {#if isVotable} +
+ + {localize('views.governance.details.projection.label')} + +
+ {/if} {/each} {/if} {#if $selectedProposal?.status === EventStatus.Upcoming} - {:else if [EventStatus.Commencing, EventStatus.Holding].includes($selectedProposal?.status)} + {:else if isVotable} {@const isLoaded = questions && overviewLoaded && statusLoaded} {@const isStoppingVote = lastAction === 'stopVote' && hasGovernanceTransactionInProgress} {@const isStopVotingDisabled = !isLoaded || !isVotingForProposal || isUpdatingVotedAnswerValues} diff --git a/packages/shared/src/lib/contexts/governance/utils/getProjectedPercentages.ts b/packages/shared/src/lib/contexts/governance/utils/getProjectedPercentages.ts new file mode 100644 index 0000000000..07e4e46543 --- /dev/null +++ b/packages/shared/src/lib/contexts/governance/utils/getProjectedPercentages.ts @@ -0,0 +1,44 @@ +import { get } from 'svelte/store' +import { IProposal, IProposalAnswerPercentages, selectedProposal } from '..' +import { AnswerStatus } from '@iota/sdk' +import { networkStatus } from '@core/network/stores/network-status.store' +import { round } from '@core/utils/number' + +export function getProjectedPercentages( + answerStatuses: AnswerStatus[], + proposal: IProposal = get(selectedProposal) +): IProposalAnswerPercentages { + if (!proposal) { + return {} + } + + const answerStatusesWithProjection = answerStatuses.map((answerStatus) => { + return { ...answerStatus, projected: getProjectedVotesFromAnswerStatus(answerStatus, proposal) } + }) + + const totalVotes = answerStatusesWithProjection?.reduce((acc, answerStatus) => acc + answerStatus.projected, 0) ?? 0 + if (totalVotes === 0 || Number.isNaN(totalVotes)) { + return {} + } + + let percentages: IProposalAnswerPercentages = {} + answerStatusesWithProjection.forEach((answerStatus) => { + if (answerStatus.value !== undefined) { + const divisionResult = answerStatus.projected / totalVotes + percentages = { + ...percentages, + [answerStatus.value]: Number.isNaN(divisionResult) ? '0%' : `${round(divisionResult * 100, 1)}%`, + } + } + }) + + return percentages +} + +function getProjectedVotesFromAnswerStatus(answerStatus: AnswerStatus, proposal: IProposal): number { + const { accumulated, current } = answerStatus + const endingMilestone = proposal.milestones?.ended ?? 0 + const currentMilestone = get(networkStatus)?.currentMilestone ?? 0 + + return Math.max(accumulated, accumulated + current * (endingMilestone - currentMilestone)) +} diff --git a/packages/shared/src/lib/contexts/governance/utils/index.ts b/packages/shared/src/lib/contexts/governance/utils/index.ts index 0f869782e9..24ce2398a1 100644 --- a/packages/shared/src/lib/contexts/governance/utils/index.ts +++ b/packages/shared/src/lib/contexts/governance/utils/index.ts @@ -9,6 +9,7 @@ export * from './getNumberOfVotedProposals' export * from './getNumberOfVotingProposals' export * from './getParticipationsForProposal' export * from './getPercentagesFromAnswerStatuses' +export * from './getProjectedPercentages' export * from './getProposalStatusForMilestone' export * from './isAccountVoting' export * from './isParticipationOutput' diff --git a/packages/shared/src/locales/en.json b/packages/shared/src/locales/en.json index b7e92aefbe..d92055e4b2 100644 --- a/packages/shared/src/locales/en.json +++ b/packages/shared/src/locales/en.json @@ -688,7 +688,11 @@ "nodeUrl": "Node URL" }, "fetching": "Fetching proposal data", - "hintVote": "You can not vote on a proposal that is in the announcement phase, voting will open in {time}." + "hintVote": "You can not vote on a proposal that is in the announcement phase, voting will open in {time}.", + "projection": { + "label": "Projected votes", + "tooltip": "The projection is based on current voting weight and remaining milestones." + } } }, "updateStronghold": {