Skip to content

Commit

Permalink
Implementation of the delegate hp TabPane
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubziebin committed Mar 13, 2024
1 parent a4afa7a commit 9a18905
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,113 @@

from typing import TYPE_CHECKING

from textual.widgets import TabPane
from textual import on
from textual.containers import Horizontal, Vertical
from textual.widgets import Static, TabPane

from clive.__private.ui.widgets.clive_widget import CliveWidget
from clive.__private.core.hive_vests_conversions import hive_to_vests, vests_to_hive
from clive.__private.ui.data_providers.hive_power_data_provider import HivePowerDataProvider
from clive.__private.ui.get_css import get_css_from_relative_path
from clive.__private.ui.operations.bindings import OperationActionBindings
from clive.__private.ui.operations.hive_power_management.common_hive_power.hp_vests_factor import HpVestsFactor
from clive.__private.ui.operations.operation_summary.remove_delegation import RemoveDelegation
from clive.__private.ui.widgets.clive_button import CliveButton
from clive.__private.ui.widgets.clive_checkerboard_table import (
EVEN_CLASS_NAME,
ODD_CLASS_NAME,
CliveCheckerboardTable,
CliveCheckerBoardTableCell,
CliveCheckerboardTableRow,
)
from clive.__private.ui.widgets.currency_selector.currency_selector_hp_vests import CurrencySelectorHpVests
from clive.__private.ui.widgets.inputs.account_name_input import AccountNameInput
from clive.__private.ui.widgets.inputs.clive_validated_input import CliveValidatedInput
from clive.__private.ui.widgets.inputs.hp_vests_amount_input import HPVestsAmountInput
from clive.__private.ui.widgets.section_title import SectionTitle
from clive.models import Asset
from schemas.operations import DelegateVestingSharesOperation

if TYPE_CHECKING:
from rich.text import TextType
from textual.app import ComposeResult

from clive.__private.core.commands.data_retrieval.hive_power_data import HivePowerData
from clive.models.aliased import DynamicGlobalProperties, VestingDelegation

class DelegateHivePower(TabPane, CliveWidget):

class PlaceTaker(Static):
pass


class DelegationsTableHeader(Horizontal):
def compose(self) -> ComposeResult:
yield Static("Delegate", classes=ODD_CLASS_NAME)
yield Static("Shares [HP]", classes=EVEN_CLASS_NAME)
yield Static("Shares [VESTS]", classes=ODD_CLASS_NAME)
yield PlaceTaker()


class Delegation(CliveCheckerboardTableRow):
"""Row of the `DelegationsTable`."""

def __init__(self, delegation: VestingDelegation[Asset.Vests], dgpo: DynamicGlobalProperties) -> None:
"""
Initialize the delegation row.
Args:
----
delegation: delegation data to display.
dgpo: dynamic global properties.
"""
self._amount_in_hp = vests_to_hive(delegation.vesting_shares, dgpo)
super().__init__(
CliveCheckerBoardTableCell(delegation.delegatee),
CliveCheckerBoardTableCell(f"{Asset.pretty_amount(self._amount_in_hp)}"),
CliveCheckerBoardTableCell(f"{Asset.pretty_amount(delegation.vesting_shares)}"),
CliveCheckerBoardTableCell(CliveButton("Remove", id_="remove-delegation-button", variant="error")),
)
self._delegation = delegation

@on(CliveButton.Pressed, "#remove-delegation-button")
def push_operation_summary_screen(self) -> None:
self.app.push_screen(RemoveDelegation(self._delegation, self._amount_in_hp))


class DelegationsTable(CliveCheckerboardTable):
"""Table with delegations."""

def __init__(self) -> None:
super().__init__(
Static("Current delegations", id="delegations-table-title"), DelegationsTableHeader(), dynamic=True
)
self._previous_delegations: list[VestingDelegation[Asset.Vests]] | None = None

def create_dynamic_rows(self, content: HivePowerData) -> list[Delegation]:
self._previous_delegations = content.delegations

return [Delegation(delegation, content.gdpo) for delegation in content.delegations]

def get_no_content_available_widget(self) -> Static:
return Static("You have no delegations", id="no-delegations-info")

@property
def check_if_should_be_updated(self) -> bool:
return self._previous_delegations != self.provider.content.delegations

@property
def is_anything_to_display(self) -> bool:
return len(self.provider.content.delegations) != 0

@property
def provider(self) -> HivePowerDataProvider:
return self.screen.query_one(HivePowerDataProvider)


class DelegateHivePower(TabPane, OperationActionBindings):
"""TabPane with all content about delegate hp."""

DEFAULT_CSS = get_css_from_relative_path(__file__)

def __init__(self, title: TextType):
"""
Initialize a TabPane.
Expand All @@ -22,3 +118,45 @@ def __init__(self, title: TextType):
title: Title of the TabPane (will be displayed in a tab label).
"""
super().__init__(title=title)
self._delegate_input = AccountNameInput("Delegate")
self._shares_input = HPVestsAmountInput()

def compose(self) -> ComposeResult:
yield HpVestsFactor(self.provider)
yield SectionTitle("Delegate your shares")
with Vertical(id="inputs-container"):
yield self._delegate_input
yield self._shares_input
yield DelegationsTable()

def _create_operation(self) -> DelegateVestingSharesOperation | None:
if not CliveValidatedInput.validate_many(self._delegate_input, self._shares_input):
return None

asset = self._shares_input.value_or_error

if isinstance(asset, Asset.Hive):
# If the user has passed an amount in `HP` - convert it to `VESTS`. The operation is performed using VESTS.
asset = hive_to_vests(asset, self.provider.content.gdpo)
return DelegateVestingSharesOperation(
delegator=self.working_account, delegatee=self._delegate_input.value_or_error, vesting_shares=asset
)

@on(CurrencySelectorHpVests.Changed)
def shares_type_changed(self) -> None:
"""Clear input when shares type was changed and hide factor display when vests selected."""
self._shares_input.input.clear()

hp_vests_factor = self.query_one(HpVestsFactor)
if self._shares_input.selected_asset_type is Asset.Vests:
hp_vests_factor.display = False
return
hp_vests_factor.display = True

@property
def provider(self) -> HivePowerDataProvider:
return self.screen.query_one(HivePowerDataProvider)

@property
def working_account(self) -> str:
return self.app.world.profile_data.working_account.name
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#inputs-container {
background: $panel;
padding: 2 4;
height: auto;
}

HPVestsAmountInput {
margin-top: 1;
}

HpVestsFactor {
margin-bottom: 1;
}

DelegationsTable {
height: auto;

#delegations-table-title {
text-style: bold;
margin-top: 1;
background: $primary;
width: 1fr;
height: 1;
text-align: center;
}

DelegationsTableHeader {
height: auto;
}

Static {
text-style: bold;
width: 1fr;
text-align: center;
}

#no-delegations-info {
margin-top: 1;
background: $primary;
height: 1;
}

Delegation {
width: 1fr;
height: auto;

#remove-delegation-button {
width: 1fr;
}
}
}
2 changes: 2 additions & 0 deletions clive/models/aliased.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
ListDeclineVotingRightsRequestsFundament,
OwnerHistoriesFundament,
SavingsWithdrawalsFundament,
VestingDelegationsFundament,
WithdrawVestingRoutesFundament,
WitnessesFundament,
)
Expand Down Expand Up @@ -67,6 +68,7 @@
FindProposals = SchemasFindProposals
FindAccounts = SchemasFindAccounts
WithdrawRouteSchema = WithdrawVestingRoutesFundament
VestingDelegation = VestingDelegationsFundament

ChangeRecoveryAccountRequest = ListChangeRecoveryAccountRequestsFundament
DeclineVotingRightsRequest = ListDeclineVotingRightsRequestsFundament
Expand Down

0 comments on commit 9a18905

Please sign in to comment.