Skip to content

Commit

Permalink
feat: adds votes percentage projection toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
jeeanribeiro committed Feb 27, 2024
1 parent d7e52e9 commit 7b5ae85
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 ?? {})
Expand Down Expand Up @@ -179,7 +180,15 @@
})
</script>

<Pane classes="w-3/5 h-full p-6 pr-3 flex flex-col justify-between">
<Pane classes="w-3/5 h-full p-6 pr-3 flex flex-col justify-between gap-4">
{@const isVotable = [EventStatus.Commencing, EventStatus.Holding].includes($selectedProposal?.status)}
{#if isVotable}
<div class="flex justify-end items-center gap-2 px-5">
<TooltipIcon tooltip={localize('views.governance.details.projection.tooltip')} />
<Text>{localize('views.governance.details.projection.label')}</Text>
<Toggle label="" bind:checked={projected} />
</div>
{/if}
<proposal-questions
class="relative flex flex-1 flex-col space-y-5 overflow-y-scroll pr-3"
bind:this={proposalQuestions}
Expand All @@ -196,13 +205,14 @@
answerStatuses={$selectedParticipationEventStatus?.questions[questionIndex]?.answers}
{onQuestionClick}
{onAnswerClick}
{projected}
/>
{/each}
{/if}
</proposal-questions>
{#if $selectedProposal?.status === EventStatus.Upcoming}
<Alert variant="info" text={alertText} />
{: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}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 ?? 0) / 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))
}
1 change: 1 addition & 0 deletions packages/shared/src/lib/contexts/governance/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
6 changes: 5 additions & 1 deletion packages/shared/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down

0 comments on commit 7b5ae85

Please sign in to comment.