From 351137a839b37b2ca0fb5ac7c62ff4fb81bab53c Mon Sep 17 00:00:00 2001 From: gabaldon Date: Thu, 12 Dec 2024 16:05:16 +0100 Subject: [PATCH] feat: adjust stake unstake form --- lib/l10n/app_en.arb | 6 +- lib/l10n/app_es.arb | 5 +- lib/theme/dark_theme.dart | 5 ++ lib/theme/light_theme.dart | 5 ++ lib/widgets/stake_unstake.dart | 2 +- lib/widgets/withdrawal_address.dart | 82 +++++++++++++++++ .../vtt_builder/01_recipient_step.dart | 87 +++++++++++++------ 7 files changed, 161 insertions(+), 31 deletions(-) create mode 100644 lib/widgets/withdrawal_address.dart diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 9c4aa959..b5517cca 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -357,5 +357,9 @@ "welcomeBack": "Welcome back", "deleteWalletSettings": "Settings: Delete wallet", "disableStakeTitle": "You don't have enough balance to stake", - "disableStakeMessage": "The minimun amount to stake is 10,000 WIT" + "disableStakeMessage": "The minimun amount to stake is 10,000 WIT", + "stakeWithdrawalAddressText": "This is the address to create Stake transactions. Make sure this address is authorized to stake.", + "unstakeWithdrawalAddressText": "This is the address used to create Stake transactions.", + "validator": "Validator", + "validatorDescription": "Validator address that authorized staking." } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 41d857c2..3a9d6d91 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -357,5 +357,8 @@ "deleteWalletSettings": "Configuración: Eliminar wallet", "welcomeBack": "Bienvenido de nuevo", "disableStakeTitle": "No tienes suficiente balance para hacer Stake", - "disableStakeMessage": "La cantidad minima para hacer Stake es de 10.000 WIT" + "disableStakeMessage": "La cantidad minima para hacer Stake es de 10.000 WIT", + "withdrawalAddressDescription": "Esta es tu direción para realizar transaction de Stake. Un nodo de Witnet debe autorizar esta address para realizar transactiones de Stake", + "validator": "Validador", + "validatorDescription": "Dirección del validador que autorizó el staking." } \ No newline at end of file diff --git a/lib/theme/dark_theme.dart b/lib/theme/dark_theme.dart index 3c8bac55..800cfa7b 100644 --- a/lib/theme/dark_theme.dart +++ b/lib/theme/dark_theme.dart @@ -79,6 +79,11 @@ InputDecorationTheme inputDecorationTheme = InputDecorationTheme( isDense: true, isCollapsed: false, contentPadding: EdgeInsets.all(16), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: WitnetPallet.darkGrey2, width: 1.0, style: BorderStyle.solid), + borderRadius: BorderRadius.circular(BORDER_RADIUS), + ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: WitnetPallet.darkGrey2, width: 1.0, style: BorderStyle.solid), diff --git a/lib/theme/light_theme.dart b/lib/theme/light_theme.dart index 3b2970d6..346db91a 100644 --- a/lib/theme/light_theme.dart +++ b/lib/theme/light_theme.dart @@ -85,6 +85,11 @@ InputDecorationTheme inputDecorationTheme = InputDecorationTheme( isDense: true, isCollapsed: false, contentPadding: const EdgeInsets.all(16), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: WitnetPallet.black, width: 1.0, style: BorderStyle.solid), + borderRadius: BorderRadius.circular(BORDER_RADIUS), + ), enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: WitnetPallet.black, width: 1.0, style: BorderStyle.solid), diff --git a/lib/widgets/stake_unstake.dart b/lib/widgets/stake_unstake.dart index c0ee601d..901d0ecb 100644 --- a/lib/widgets/stake_unstake.dart +++ b/lib/widgets/stake_unstake.dart @@ -30,7 +30,7 @@ class StakeUnstakeButtons extends StatelessWidget { ApiDatabase db = Locator.instance.get(); Wallet currentWallet = db.walletStorage.currentWallet; late StakedBalanceInfo stakeInfo = currentWallet.stakedNanoWit(); - bool allowStake = MIN_STAKING_AMOUNT_NANOWIT < + bool allowStake = MIN_STAKING_AMOUNT_NANOWIT <= currentWallet.balanceNanoWit().availableNanoWit; Future _goToStakeScreen() async { diff --git a/lib/widgets/withdrawal_address.dart b/lib/widgets/withdrawal_address.dart new file mode 100644 index 00000000..2f54912d --- /dev/null +++ b/lib/widgets/withdrawal_address.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:my_wit_wallet/widgets/copy_button.dart'; +import 'package:my_wit_wallet/widgets/inputs/input_text.dart'; + +import 'package:my_wit_wallet/theme/extended_theme.dart'; +import 'package:my_wit_wallet/util/get_localization.dart'; +import 'package:my_wit_wallet/util/storage/scanned_content.dart'; + +class WithdrawerAddress extends InputText { + WithdrawerAddress({ + required super.focusNode, + required super.styledTextController, + super.prefixIcon, + super.enabled = true, + super.errorText, + super.validator, + super.hint, + super.keyboardType, + super.obscureText = false, + this.route, + super.onChanged, + super.onEditingComplete, + super.onFieldSubmitted, + super.onTapOutside, + super.onTap, + super.onSuffixTap, + super.inputFormatters, + super.decoration, + super.maxLines = 1, + this.setAddressCallback, + }); + + final String? route; + final void Function(String, {bool? validate})? setAddressCallback; + @override + _WithdrawerAddressState createState() => _WithdrawerAddressState(); +} + +class _WithdrawerAddressState extends State { + bool isScanQrFocused = false; + ScannedContent scannedContent = ScannedContent(); + TextSelection? lastSelection; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + Widget build(BuildContext context) { + final theme = Theme.of(context); + final extendedTheme = theme.extension()!; + + widget.styledTextController.setStyle( + extendedTheme.monoLargeText! + .copyWith(color: theme.textTheme.bodyMedium!.color), + extendedTheme.monoLargeText!.copyWith(color: Colors.black), + ); + + return Column( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [ + widget.buildInput( + context: context, + decoration: widget.decoration ?? + InputDecoration( + hintStyle: extendedTheme.monoLargeText! + .copyWith(color: theme.textTheme.bodyMedium!.color), + hintText: localization.recipientAddress, + suffixIcon: Semantics( + label: localization.copyAddressLabel, + child: CopyButton(copyContent: 'copyContent')), + errorText: widget.errorText, + )), + ]); + } +} diff --git a/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/01_recipient_step.dart b/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/01_recipient_step.dart index 1a937f96..156093da 100644 --- a/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/01_recipient_step.dart +++ b/lib/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/01_recipient_step.dart @@ -14,12 +14,15 @@ import 'package:my_wit_wallet/widgets/inputs/input_authorization.dart'; import 'package:my_wit_wallet/widgets/inputs/input_slider.dart'; import 'package:my_wit_wallet/widgets/labeled_form_entry.dart'; import 'package:my_wit_wallet/widgets/layouts/send_transaction_layout.dart'; +import 'package:my_wit_wallet/widgets/select.dart'; import 'package:my_wit_wallet/widgets/snack_bars.dart'; import 'package:my_wit_wallet/widgets/validations/address_input.dart'; import 'package:my_wit_wallet/widgets/validations/authorization_input.dart'; import 'package:my_wit_wallet/widgets/validations/validation_utils.dart'; import 'package:my_wit_wallet/widgets/validations/tx_amount_input.dart'; -import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/timelock_input.dart'; +import 'package:my_wit_wallet/widgets/withdrawal_address.dart'; +import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/timelock_input.dart' + as timelockInput; import 'package:my_wit_wallet/widgets/witnet/transactions/value_transfer/create_dialog_box/vtt_builder/timelock_picker.dart'; import 'package:witnet/schema.dart'; import 'package:my_wit_wallet/bloc/transactions/value_transfer/vtt_create/vtt_create_bloc.dart'; @@ -35,7 +38,7 @@ import 'package:my_wit_wallet/util/storage/database/account.dart'; class RecipientStep extends StatefulWidget { final Function nextAction; final WalletStorage walletStorage; - final VoidCallback goNext; + final timelockInput.VoidCallback goNext; final TransactionType transactionType; final String routeName; @@ -64,6 +67,7 @@ class RecipientStepState extends State AddressInput _address = AddressInput.pure(); TxAmountInput _amount = TxAmountInput.pure(); AuthorizationInput _authorization = AuthorizationInput.pure(); + String _selectedValidator = 'validator1'; final _amountController = StyledTextController(); final _amountFocusNode = FocusNode(); final _addressController = StyledTextController(); @@ -348,7 +352,7 @@ class RecipientStepState extends State showAdvancedSettings ? Padding( padding: EdgeInsets.only(left: 8, right: 8), - child: TimelockInput( + child: timelockInput.TimelockInput( timelockSet: timelockSet, onSelectedDate: _setTimeLock, onClearTimelock: _clearTimeLock, @@ -484,32 +488,57 @@ class RecipientStepState extends State } List _buildWithdrawalAddressInput(ThemeData theme) { + _addressController.text = currentAccount.address; return [ - LabeledFormEntry( - label: localization.withdrawalAddress, - formEntry: InputAddress( - route: widget.routeName, - errorText: _address.error, - styledTextController: _addressController, - focusNode: _addressFocusNode, - keyboardType: TextInputType.text, - inputFormatters: [WitAddressFormatter()], - onChanged: (String value) { - setAddress(value); - }, - onFieldSubmitted: (String value) { - showAuthorization - ? _authorizationFocusNode.requestFocus() - : _amountFocusNode.requestFocus(); - }, - onTap: () { - _addressFocusNode.requestFocus(); - }, - onTapOutside: (event) { - _addressFocusNode.unfocus(); - }, - setAddressCallback: setAddress, - )) + Text( + localization.withdrawalAddress, + style: theme.textTheme.titleMedium, + ), + SizedBox(height: 8), + Text( + isStakeTarnsaction + ? localization.stakeWithdrawalAddressText + : localization.unstakeWithdrawalAddressText, + style: theme.textTheme.bodyMedium), + SizedBox(height: 16), + WithdrawerAddress( + route: widget.routeName, + errorText: _address.error, + styledTextController: _addressController, + focusNode: _addressFocusNode, + keyboardType: TextInputType.text, + inputFormatters: [WitAddressFormatter()], + setAddressCallback: setAddress, + onChanged: (_value) => { + _addressController.text = currentAccount.address, + }, + ), + SizedBox(height: 4), + ]; + } + + List _buildValidatorAddressSelect(ThemeData theme) { + _addressController.text = currentAccount.address; + List validatorAddressesUsedInStakes = [ + SelectItem('validator1', 'validator1'), + SelectItem('validator2', 'validator2') + ]; + return [ + SizedBox(height: 8), + Text( + localization.validator, + style: theme.textTheme.titleMedium, + ), + SizedBox(height: 8), + Text(localization.validatorDescription, + style: theme.textTheme.bodyMedium), + SizedBox(height: 16), + Select( + selectedItem: _selectedValidator, + cropLabel: true, + listItems: validatorAddressesUsedInStakes, + onChanged: (String? label) => + {if (label != null) setState(() => _selectedValidator = label)}), ]; } @@ -568,6 +597,8 @@ class RecipientStepState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ ..._buildAddressInput(theme), + if (isUnstakeTransaction) + ..._buildValidatorAddressSelect(theme), if (showAuthorization) ..._buildAuthorizationInput(theme), ..._buildAmountInput(theme), ],