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

Feat: add participation loaders #3297

Merged
merged 10 commits into from
May 24, 2022
2 changes: 1 addition & 1 deletion packages/shared/components/popups/GovernanceManager.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@
if (!isSoftwareProfile) {
transferState.set(null)
}

activeFlow = getActiveFlow()
isPerformingParticipation.set(false)
participationAction.set(undefined)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/lib/participation/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function participate(
onSuccess(response: Event<ParticipateResponsePayload>) {
response.payload.forEach((message) => saveNewMessage(accountId, message))

addNewPendingParticipation(response.payload, accountId, action)
addNewPendingParticipation(response.payload, accountId, action, participations)

const eventIds = participations.map((participation) => participation.eventId)
updateParticipationHistoryFromPayload(response.payload, accountId, action, eventIds)
Expand Down
10 changes: 6 additions & 4 deletions packages/shared/lib/participation/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { transferState, wallet } from '../wallet'
import { ASSEMBLY_EVENT_ID, SHIMMER_EVENT_ID, TREASURY_VOTE_EVENT_ID } from './constants'
import {
ParticipateResponsePayload,
Participation,
ParticipationAction,
ParticipationEvent,
ParticipationEventState,
Expand Down Expand Up @@ -189,15 +190,17 @@ export const shimmerStakingRemainingTime: Readable<number> = derived(
export const addNewPendingParticipation = (
payload: ParticipateResponsePayload,
accountId: string,
action: ParticipationAction
action: ParticipationAction,
participations?: Participation[]
): void => {
const _pendingParticipation = {
accountId,
action,
participations,
}

pendingParticipations.update((participations) => [
...participations,
pendingParticipations.update((_participations) => [
..._participations,
...payload.map((tx) => Object.assign({}, _pendingParticipation, { messageId: tx.id })),
])
}
Expand Down Expand Up @@ -259,7 +262,6 @@ export const resetPerformingParticipation = (): void => {
}
isPerformingParticipation.set(false)
participationAction.set(undefined)
isChangingParticipation.set(false)
}

export const participationHistory = persistent<ParticipationHistoryItem[]>('participationHistory', [])
1 change: 1 addition & 0 deletions packages/shared/lib/participation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export type PendingParticipation = {
messageId: string
accountId: string
action: ParticipationAction
participations?: Participation[]
}

/**
Expand Down
1 change: 1 addition & 0 deletions packages/shared/lib/walletApiListeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export const initialiseListeners = (): void => {
(get(isChangingParticipation) &&
getPendingParticipation(message.id)?.action !== ParticipationAction.Unvote)
) {
isChangingParticipation.set(false)
displayParticipationNotification(getPendingParticipation(message.id))
}
if (get(popupState).type === 'stakingManager') {
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,8 @@
"notStaked": "Not staked",
"stakedFunds": "Staked funds",
"unstakedFunds": "Unstaked funds",
"voting": "Voting",
"unvoting": "Unvoting",
"accountColor": "Wallet color",
"myAssets": "My assets",
"option": "Option",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,43 @@
import { openPopup } from '@lib/popup'
import { formatUnitBestMatch } from '@lib/units'
import { selectedAccountStore } from '@lib/wallet'
import { DashboardPane, GovernanceInfoTooltip, Icon, Text, Tooltip } from 'shared/components'
import { DashboardPane, GovernanceInfoTooltip, Icon, Spinner, Text, Tooltip } from 'shared/components'
import { showAppNotification } from 'shared/lib/notifications'
import {
isChangingParticipation,
participationAction,
pendingParticipations,
} from 'shared/lib/participation/stores'
import { ParticipationAction } from 'shared/lib/participation/types'
import { isSyncing } from 'shared/lib/wallet'

export let event: ParticipationEvent
export let nextVote: VotingEventAnswer = null

$: cannotVote = getAccountParticipationAbility($selectedAccountStore) === AccountParticipationAbility.HasDustAmount

const tooltip = {
statusTimeline: { anchor: null as HTMLElement, show: false },
partiallyVoted: { anchor: null as HTMLElement, show: false },
}

$: eventAnswers = event?.information?.payload?.questions[0]?.answers ?? []
$: results = event?.status?.questions?.[0]?.answers?.filter(
(answer) => answer?.value !== 0 && answer?.value !== 255
)
$: cannotVote = getAccountParticipationAbility($selectedAccountStore) === AccountParticipationAbility.HasDustAmount
$: disableVoting =
$isChangingParticipation || $pendingParticipations?.length > 0 || !!$participationAction || $isSyncing

let disableVotingMessages: {
show?: boolean
busy?: boolean
message?: string
}[]
$: disableVoting,
eventAnswers,
$isSyncing,
$currentAccountTreasuryVoteValue,
$pendingParticipations,
updateDisableVotingMessages()

const isSelected = (castedAnswerValue: string, answerValue: string): boolean => castedAnswerValue === answerValue

Expand Down Expand Up @@ -90,6 +111,70 @@
break
}
}

function updateDisableVotingMessages(): void {
if (!disableVoting) return
else {
disableVotingMessages = []
const pendingParticipation = $pendingParticipations?.[0]
eventAnswers.forEach((eventAnswer) => {
if ($isSyncing) {
disableVotingMessages.push({
show: true,
busy: true,
message: localize('general.syncing'),
})
} else if (
$participationAction === ParticipationAction.Stake ||
$participationAction === ParticipationAction.Unstake
) {
const locale =
$participationAction === ParticipationAction.Stake ? 'general.staking' : 'general.unstaking'
disableVotingMessages.push({
show: true,
busy: true,
message: localize(locale),
})
} else if (
pendingParticipation?.action === ParticipationAction.Vote ||
pendingParticipation?.action === ParticipationAction.Unvote
) {
const pendingParticipationAnswers =
pendingParticipation?.participations?.map((participations) => participations?.answers) ?? []
if (pendingParticipation?.action === ParticipationAction.Vote) {
if (
pendingParticipationAnswers.some((participation) =>
participation.includes(eventAnswer?.value)
)
) {
disableVotingMessages.push({
show: true,
busy: true,
message: localize('general.voting'),
})
} else {
disableVotingMessages.push({
show: false,
})
}
} else {
if (isSelected($currentAccountTreasuryVoteValue, eventAnswer?.value)) {
disableVotingMessages.push({
show: true,
busy: true,
message: localize('general.unvoting'),
})
} else {
disableVotingMessages.push({
show: false,
})
}
}
}
})
disableVotingMessages = disableVotingMessages
}
}
</script>

<DashboardPane classes="w-full h-full p-6 col-span-2 row-span-2 flex flex-col">
Expand Down Expand Up @@ -133,14 +218,14 @@
{/if}
</div>
<div class="flex flex-col w-full space-y-16 overflow-y-auto flex-auto h-1 space-y-2.5 -mr-2 pr-2 scroll-secondary">
{#each event?.information?.payload?.questions[0]?.answers ?? [] as answer}
{#each event?.information?.payload?.questions[0]?.answers ?? [] as answer, answerIndex}
<button
on:click={() => handleAnswerClick(answer)}
class:winner={isWinnerAnswer(answer?.value)}
class:active={isSelected($currentAccountTreasuryVoteValue, answer?.value)}
class:partial={isSelected($currentAccountTreasuryVoteValue, answer?.value) &&
$hasCurrentAccountReceivedFundsSinceLastTreasuryVote}
disabled={!canParticipate(event?.status?.status)}
disabled={disableVoting || !canParticipate(event?.status?.status)}
class="relative py-5 px-6 bg-gray-50 dark:bg-gray-900 dark:bg-opacity-50 hover:bg-gray-100 dark:hover:bg-gray-900 dark:hover:bg-opaciity-100 rounded-xl border border-solid border-gray-200 dark:border-transparent"
>
<div class="flex justify-between w-full items-center">
Expand Down Expand Up @@ -200,8 +285,18 @@
</Text>
</div>
{#if canParticipate(event?.status?.status)}
{#if isSelected($currentAccountTreasuryVoteValue, answer?.value) && $hasCurrentAccountReceivedFundsSinceLastTreasuryVote}
<div class="flex flex-row space-x-2 items-center">
{#if disableVoting}
{#if disableVotingMessages?.[answerIndex]?.show}
<div class="p-2 bg-gray-300 dark:bg-gray-700 rounded-lg flex-shrink-0">
<Spinner
busy={disableVotingMessages?.[answerIndex]?.busy}
message={disableVotingMessages?.[answerIndex]?.message}
classes="mx-2 justify-center"
/>
</div>
{/if}
{:else if isSelected($currentAccountTreasuryVoteValue, answer?.value) && $hasCurrentAccountReceivedFundsSinceLastTreasuryVote}
<div class="flex flex-row space-x-2 items-center flex-shrink-0">
<Text type="p" overrideColor classes="text-yellow-600"
>{localize('views.governance.manageVote')}</Text
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@
stakedAmount,
unstakedAmount,
} from 'shared/lib/participation/account'
import { assemblyStakingEventState, shimmerStakingEventState } from 'shared/lib/participation/stores'
import {
assemblyStakingEventState,
isChangingParticipation,
shimmerStakingEventState,
} from 'shared/lib/participation/stores'
import { participationAction } from 'shared/lib/participation/stores'
import { AccountParticipationAbility, ParticipationAction } from 'shared/lib/participation/types'
import { openPopup } from 'shared/lib/popup'
import { NodePlugin } from 'shared/lib/typings/node'
import { formatUnitBestMatch, formatUnitPrecision } from 'shared/lib/units'
import { isSyncing, selectedAccountStore } from 'shared/lib/wallet'

$: showSpinner = !!$participationAction || $isSyncing
$: showSpinner = !!$participationAction || $isSyncing || $isChangingParticipation

$: canParticipateInEvent =
isParticipationPossible($assemblyStakingEventState) || isParticipationPossible($shimmerStakingEventState)
Expand Down Expand Up @@ -76,14 +80,19 @@
}

function getSpinnerMessage(): string {
if (
$participationAction === ParticipationAction.Stake ||
$participationAction === ParticipationAction.Unstake
) {
const locale = $participationAction === ParticipationAction.Stake ? 'general.staking' : 'general.unstaking'
return localize(locale)
} else if ($isSyncing) {
return localize('general.syncingAccounts')
if ($isSyncing) {
return localize('general.syncing')
} else {
switch ($participationAction) {
case ParticipationAction.Stake:
return localize('general.staking')
case ParticipationAction.Unstake:
return localize('general.unstaking')
case ParticipationAction.Vote:
return localize('general.voting')
case ParticipationAction.Unvote:
return localize('general.unvoting')
}
}
}
</script>
Expand Down