From d5f401132bd7476f2046ff5b9ef950847797bc12 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 10 Feb 2023 12:07:57 -0600 Subject: [PATCH] Desktop paynym ui and some bug fixes --- lib/pages/paynym/paynym_home_view.dart | 1 + .../subwidgets/desktop_paynym_details.dart | 11 +- .../send_view/confirm_transaction_view.dart | 159 ++--- lib/pages/send_view/send_view.dart | 38 -- .../paynym/desktop_paynym_send_dialog.dart | 197 ++++++ .../wallet_view/sub_widgets/desktop_send.dart | 613 ++++++++---------- 6 files changed, 557 insertions(+), 462 deletions(-) create mode 100644 lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart diff --git a/lib/pages/paynym/paynym_home_view.dart b/lib/pages/paynym/paynym_home_view.dart index 9292b8acb..b989ba9c5 100644 --- a/lib/pages/paynym/paynym_home_view.dart +++ b/lib/pages/paynym/paynym_home_view.dart @@ -559,6 +559,7 @@ class _PaynymHomeViewState extends ConsumerState { height: isDesktop ? 56 : 48, width: isDesktop ? 490 : null, child: Toggle( + key: UniqueKey(), onColor: Theme.of(context).extension()!.popupBG, onText: "Following (${ref.watch(myPaynymAccountStateProvider.state).state?.following.length ?? 0})", diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart index 2f7f05e9a..ad01b1f7e 100644 --- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart +++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart @@ -11,6 +11,7 @@ import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart'; import 'package:stackwallet/pages/paynym/subwidgets/paynym_bot.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; +import 'package:stackwallet/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -102,8 +103,6 @@ class _PaynymDetailsPopupState extends ConsumerState { builder: (context) => ConfirmPaynymConnectDialog( nymName: widget.accountLite.nymName, onConfirmPressed: () { - // - print("CONFIRM NOTIF TX: $preparedTx"); Navigator.of(context, rootNavigator: true).pop(); unawaited( showDialog( @@ -148,7 +147,13 @@ class _PaynymDetailsPopupState extends ConsumerState { } Future _onSend() async { - print("sned"); + await showDialog( + context: context, + builder: (context) => DesktopPaynymSendDialog( + walletId: widget.walletId, + accountLite: widget.accountLite, + ), + ); } @override diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index f56911a63..8ad9f90fc 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -586,7 +586,9 @@ class _ConfirmTransactionViewState crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Send to", + widget.isPaynymTransaction + ? "PayNym recipient" + : "Send to", style: STextStyles.desktopTextExtraExtraSmall( context), ), @@ -594,7 +596,11 @@ class _ConfirmTransactionViewState height: 2, ), Text( - "${transactionInfo["address"] ?? "ERROR"}", + widget.isPaynymTransaction + ? (transactionInfo["paynymAccountLite"] + as PaynymAccountLite) + .nymName + : "${transactionInfo["address"] ?? "ERROR"}", style: STextStyles.desktopTextExtraExtraSmall( context) .copyWith( @@ -606,6 +612,64 @@ class _ConfirmTransactionViewState ], ), ), + if (widget.isPaynymTransaction) + Container( + height: 1, + color: Theme.of(context) + .extension()! + .background, + ), + if (widget.isPaynymTransaction) + Padding( + padding: const EdgeInsets.all(12), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Transaction fee", + style: STextStyles.desktopTextExtraExtraSmall( + context), + ), + const SizedBox( + height: 2, + ), + Builder( + builder: (context) { + final coin = ref + .watch(walletsChangeNotifierProvider + .select((value) => + value.getManager(walletId))) + .coin; + + final fee = Format.satoshisToAmount( + transactionInfo["fee"] as int, + coin: coin, + ); + + return Text( + "${Format.localizedStringAsFixed( + value: fee, + locale: ref.watch( + localeServiceChangeNotifierProvider + .select((value) => value.locale)), + decimalPlaces: + Constants.decimalPlacesForCoin(coin), + )} ${coin.ticker}", + style: + STextStyles.desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension()! + .textDark, + ), + ); + }, + ), + ], + ), + ), // Container( // height: 1, // color: Theme.of(context) @@ -725,7 +789,7 @@ class _ConfirmTransactionViewState ], ), ), - if (isDesktop) + if (isDesktop && !widget.isPaynymTransaction) Padding( padding: const EdgeInsets.only( left: 32, @@ -735,22 +799,23 @@ class _ConfirmTransactionViewState style: STextStyles.desktopTextExtraExtraSmall(context), ), ), - if (isDesktop) + if (isDesktop && !widget.isPaynymTransaction) Padding( - padding: const EdgeInsets.only( - top: 10, - left: 32, - right: 32, + padding: const EdgeInsets.only( + top: 10, + left: 32, + right: 32, + ), + child: RoundedContainer( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 18, ), - child: RoundedContainer( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 18, - ), - color: Theme.of(context) - .extension()! - .textFieldDefaultBG, - child: Builder(builder: (context) { + color: Theme.of(context) + .extension()! + .textFieldDefaultBG, + child: Builder( + builder: (context) { final coin = ref .watch(walletsChangeNotifierProvider .select((value) => value.getManager(walletId))) @@ -770,64 +835,10 @@ class _ConfirmTransactionViewState )} ${coin.ticker}", style: STextStyles.itemSubtitle(context), ); - }), - ) - // DropdownButtonHideUnderline( - // child: DropdownButton2( - // offset: const Offset(0, -10), - // isExpanded: true, - // - // dropdownElevation: 0, - // value: _fee, - // items: [ - // ..._dropDownItems.map( - // (e) { - // String message = _fee.toString(); - // - // return DropdownMenuItem( - // value: e, - // child: Text(message), - // ); - // }, - // ), - // ], - // onChanged: (value) { - // if (value is int) { - // setState(() { - // _fee = value; - // }); - // } - // }, - // icon: SvgPicture.asset( - // Assets.svg.chevronDown, - // width: 12, - // height: 6, - // color: - // Theme.of(context).extension()!.textDark3, - // ), - // buttonPadding: const EdgeInsets.symmetric( - // horizontal: 16, - // vertical: 8, - // ), - // buttonDecoration: BoxDecoration( - // color: Theme.of(context) - // .extension()! - // .textFieldDefaultBG, - // borderRadius: BorderRadius.circular( - // Constants.size.circularBorderRadius, - // ), - // ), - // dropdownDecoration: BoxDecoration( - // color: Theme.of(context) - // .extension()! - // .textFieldDefaultBG, - // borderRadius: BorderRadius.circular( - // Constants.size.circularBorderRadius, - // ), - // ), - // ), - // ), + }, ), + ), + ), if (!isDesktop) const Spacer(), SizedBox( height: isDesktop ? 23 : 12, diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart index eab3d0638..fb05f3a38 100644 --- a/lib/pages/send_view/send_view.dart +++ b/lib/pages/send_view/send_view.dart @@ -297,44 +297,6 @@ class _SendViewState extends ConsumerState { final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - // // TODO: remove the need for this!! - // final bool isOwnAddress = - // await manager.isOwnAddress(_address!); - // if (isOwnAddress && coin != Coin.dogecoinTestNet) { - // await showDialog( - // context: context, - // useSafeArea: false, - // barrierDismissible: true, - // builder: (context) { - // return StackDialog( - // title: "Transaction failed", - // message: - // "Sending to self is currently disabled", - // rightButton: TextButton( - // style: Theme.of(context) - // .extension()! - // .getSecondaryEnabledButtonColor( - // context), - // child: Text( - // "Ok", - // style: STextStyles.button( - // context) - // .copyWith( - // color: Theme.of(context) - // .extension< - // StackColors>()! - // .accentColorDark), - // ), - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ); - // }, - // ); - // return; - // } - final amount = Format.decimalAmountToSatoshis(_amountToSend!, coin); int availableBalance; if ((coin == Coin.firo || coin == Coin.firoTestNet)) { diff --git a/lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart b/lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart new file mode 100644 index 000000000..df24e69c3 --- /dev/null +++ b/lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart @@ -0,0 +1,197 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; +import 'package:stackwallet/models/send_view_auto_fill_data.dart'; +import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart'; +import 'package:stackwallet/providers/global/locale_provider.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; +import 'package:stackwallet/providers/global/price_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart'; +import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/barcode_scanner_interface.dart'; +import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; + +class DesktopPaynymSendDialog extends ConsumerStatefulWidget { + const DesktopPaynymSendDialog({ + Key? key, + required this.walletId, + this.autoFillData, + this.clipboard = const ClipboardWrapper(), + this.barcodeScanner = const BarcodeScannerWrapper(), + this.accountLite, + }) : super(key: key); + + final String walletId; + final SendViewAutoFillData? autoFillData; + final ClipboardInterface clipboard; + final BarcodeScannerInterface barcodeScanner; + final PaynymAccountLite? accountLite; + + @override + ConsumerState createState() => + _DesktopPaynymSendDialogState(); +} + +class _DesktopPaynymSendDialogState + extends ConsumerState { + @override + Widget build(BuildContext context) { + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + final String locale = ref.watch( + localeServiceChangeNotifierProvider.select((value) => value.locale)); + + final coin = manager.coin; + + final isFiro = coin == Coin.firo || coin == Coin.firoTestNet; + + return DesktopDialog( + maxHeight: double.infinity, + maxWidth: 580, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "Send ${manager.coin.ticker.toUpperCase()}", + style: STextStyles.desktopH3(context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 32), + child: RoundedWhiteContainer( + borderColor: + Theme.of(context).extension()!.background, + // Theme.of(context).extension()!.textSubtitle4, + child: Row( + children: [ + SvgPicture.asset( + Assets.svg.iconFor(coin: coin), + width: 36, + height: 36, + ), + const SizedBox( + width: 12, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + manager.walletName, + style: STextStyles.titleBold12(context), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + const SizedBox( + height: 2, + ), + Text( + isFiro + ? "${ref.watch(publicPrivateBalanceStateProvider.state).state} balance" + : "Available balance", + style: STextStyles.baseXS(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + ], + ), + const Spacer(), + Container( + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "${Format.localizedStringAsFixed( + value: !isFiro + ? manager.balance.getSpendable() + : ref + .watch( + publicPrivateBalanceStateProvider + .state) + .state == + "Private" + ? (manager.wallet as FiroWallet) + .availablePrivateBalance() + : (manager.wallet as FiroWallet) + .availablePublicBalance(), + locale: locale, + decimalPlaces: 8, + )} ${coin.ticker}", + style: STextStyles.titleBold12(context), + textAlign: TextAlign.right, + ), + const SizedBox( + height: 2, + ), + Text( + "${Format.localizedStringAsFixed( + value: (!isFiro + ? manager.balance.getSpendable() + : ref + .watch( + publicPrivateBalanceStateProvider + .state) + .state == + "Private" + ? (manager.wallet as FiroWallet) + .availablePrivateBalance() + : (manager.wallet as FiroWallet) + .availablePublicBalance()) * + ref.watch( + priceAnd24hChangeNotifierProvider.select( + (value) => value.getPrice(coin).item1)), + locale: locale, + decimalPlaces: 2, + )} ${ref.watch(prefsChangeNotifierProvider.select((value) => value.currency))}", + style: STextStyles.baseXS(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + textAlign: TextAlign.right, + ) + ], + ), + ), + ], + ), + ), + ), + const SizedBox( + height: 20, + ), + Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + ), + child: DesktopSend( + walletId: manager.walletId, + accountLite: widget.accountLite, + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart index cc63c67a8..09ed16610 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:bip47/bip47.dart'; import 'package:decimal/decimal.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; @@ -7,6 +8,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:stackwallet/models/contact_address_entry.dart'; +import 'package:stackwallet/models/paynym/paynym_account_lite.dart'; import 'package:stackwallet/models/send_view_auto_fill_data.dart'; import 'package:stackwallet/pages/send_view/confirm_transaction_view.dart'; import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dialog.dart'; @@ -20,6 +22,7 @@ import 'package:stackwallet/providers/ui/preview_tx_button_state_provider.dart'; import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart'; import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/services/coins/manager.dart'; +import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/address_utils.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/barcode_scanner_interface.dart'; @@ -51,12 +54,14 @@ class DesktopSend extends ConsumerStatefulWidget { this.autoFillData, this.clipboard = const ClipboardWrapper(), this.barcodeScanner = const BarcodeScannerWrapper(), + this.accountLite, }) : super(key: key); final String walletId; final SendViewAutoFillData? autoFillData; final ClipboardInterface clipboard; final BarcodeScannerInterface barcodeScanner; + final PaynymAccountLite? accountLite; @override ConsumerState createState() => _DesktopSendState(); @@ -93,78 +98,12 @@ class _DesktopSendState extends ConsumerState { bool _cryptoAmountChangeLock = false; late VoidCallback onCryptoAmountChanged; + bool get isPaynymSend => widget.accountLite != null; + Future previewSend() async { final manager = ref.read(walletsChangeNotifierProvider).getManager(walletId); - // // TODO: remove the need for this!! - // final bool isOwnAddress = await manager.isOwnAddress(_address!); - // if (isOwnAddress) { - // await showDialog( - // context: context, - // useSafeArea: false, - // barrierDismissible: true, - // builder: (context) { - // return DesktopDialog( - // maxWidth: 400, - // maxHeight: double.infinity, - // child: Padding( - // padding: const EdgeInsets.only( - // left: 32, - // bottom: 32, - // ), - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Text( - // "Transaction failed", - // style: STextStyles.desktopH3(context), - // ), - // const DesktopDialogCloseButton(), - // ], - // ), - // const SizedBox( - // height: 12, - // ), - // Text( - // "Sending to self is currently disabled", - // textAlign: TextAlign.left, - // style: STextStyles.desktopTextExtraExtraSmall(context) - // .copyWith( - // fontSize: 18, - // ), - // ), - // const SizedBox( - // height: 40, - // ), - // Row( - // children: [ - // Expanded( - // child: SecondaryButton( - // buttonHeight: ButtonHeight.l, - // label: "Ok", - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // ), - // ), - // const SizedBox( - // width: 32, - // ), - // ], - // ), - // ], - // ), - // ), - // ); - // }, - // ); - // return; - // } - final amount = Format.decimalAmountToSatoshis(_amountToSend!, coin); int availableBalance; if ((coin == Coin.firo || coin == Coin.firoTestNet)) { @@ -304,7 +243,19 @@ class _DesktopSendState extends ConsumerState { Map txData; - if ((coin == Coin.firo || coin == Coin.firoTestNet) && + if (isPaynymSend) { + final wallet = manager.wallet as PaynymWalletInterface; + final paymentCode = PaymentCode.fromPaymentCode( + widget.accountLite!.code, + wallet.networkType, + ); + final feeRate = ref.read(feeRateTypeStateProvider); + txData = await wallet.preparePaymentCodeSend( + paymentCode: paymentCode, + satoshiAmount: amount, + args: {"feeRate": feeRate}, + ); + } else if ((coin == Coin.firo || coin == Coin.firoTestNet) && ref.read(publicPrivateBalanceStateProvider.state).state != "Private") { txData = await (manager.wallet as FiroWallet).prepareSendPublic( @@ -321,8 +272,13 @@ class _DesktopSendState extends ConsumerState { } if (!wasCancelled && mounted) { - txData["note"] = _note ?? ""; - txData["address"] = _address; + if (isPaynymSend) { + txData["paynymAccountLite"] = widget.accountLite!; + txData["note"] = _note ?? "PayNym send"; + } else { + txData["address"] = _address; + txData["note"] = _note ?? ""; + } // pop building dialog Navigator.of( context, @@ -338,6 +294,7 @@ class _DesktopSendState extends ConsumerState { child: ConfirmTransactionView( transactionInfo: txData, walletId: walletId, + isPaynymTransaction: isPaynymSend, routeOnSuccessName: DesktopHomeView.routeName, ), ), @@ -439,9 +396,9 @@ class _DesktopSendState extends ConsumerState { _cachedAmountToSend == _amountToSend) { return; } - _cachedAmountToSend = _amountToSend; Logging.instance.log("it changed $_amountToSend $_cachedAmountToSend", level: LogLevel.Info); + _cachedAmountToSend = _amountToSend; final price = ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin).item1; @@ -457,6 +414,7 @@ class _DesktopSendState extends ConsumerState { } } else { _amountToSend = null; + _cachedAmountToSend = null; baseAmountController.text = ""; } @@ -475,87 +433,19 @@ class _DesktopSendState extends ConsumerState { } void _updatePreviewButtonState(String? address, Decimal? amount) { - final isValidAddress = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId) - .validateAddress(address ?? ""); - ref.read(previewTxButtonStateProvider.state).state = - (isValidAddress && amount != null && amount > Decimal.zero); + if (isPaynymSend) { + ref.read(previewTxButtonStateProvider.state).state = + (amount != null && amount > Decimal.zero); + } else { + final isValidAddress = ref + .read(walletsChangeNotifierProvider) + .getManager(walletId) + .validateAddress(address ?? ""); + ref.read(previewTxButtonStateProvider.state).state = + (isValidAddress && amount != null && amount > Decimal.zero); + } } - // late Future _calculateFeesFuture; - - // Map cachedFees = {}; - // Map cachedFiroPrivateFees = {}; - // Map cachedFiroPublicFees = {}; - - // Future calculateFees(int amount) async { - // if (amount <= 0) { - // return "0"; - // } - // - // if (coin == Coin.firo || coin == Coin.firoTestNet) { - // if (ref.read(publicPrivateBalanceStateProvider.state).state == - // "Private") { - // if (cachedFiroPrivateFees[amount] != null) { - // return cachedFiroPrivateFees[amount]!; - // } - // } else { - // if (cachedFiroPublicFees[amount] != null) { - // return cachedFiroPublicFees[amount]!; - // } - // } - // } else if (cachedFees[amount] != null) { - // return cachedFees[amount]!; - // } - // - // final manager = - // ref.read(walletsChangeNotifierProvider).getManager(walletId); - // final feeObject = await manager.fees; - // - // late final int feeRate; - // - // switch (ref.read(feeRateTypeStateProvider.state).state) { - // case FeeRateType.fast: - // feeRate = feeObject.fast; - // break; - // case FeeRateType.average: - // feeRate = feeObject.medium; - // break; - // case FeeRateType.slow: - // feeRate = feeObject.slow; - // break; - // } - // - // int fee; - // - // if (coin == Coin.firo || coin == Coin.firoTestNet) { - // if (ref.read(publicPrivateBalanceStateProvider.state).state == - // "Private") { - // fee = await manager.estimateFeeFor(amount, feeRate); - // - // cachedFiroPrivateFees[amount] = Format.satoshisToAmount(fee) - // .toStringAsFixed(Constants.decimalPlaces); - // - // return cachedFiroPrivateFees[amount]!; - // } else { - // fee = await (manager.wallet as FiroWallet) - // .estimateFeeForPublic(amount, feeRate); - // - // cachedFiroPublicFees[amount] = Format.satoshisToAmount(fee) - // .toStringAsFixed(Constants.decimalPlaces); - // - // return cachedFiroPublicFees[amount]!; - // } - // } else { - // fee = await manager.estimateFeeFor(amount, feeRate); - // cachedFees[amount] = - // Format.satoshisToAmount(fee).toStringAsFixed(Constants.decimalPlaces); - // - // return cachedFees[amount]!; - // } - // } - Future _firoBalanceFuture( ChangeNotifierProvider provider, String locale, @@ -773,7 +663,10 @@ class _DesktopSendState extends ConsumerState { @override void initState() { - ref.refresh(feeSheetSessionCacheProvider); + WidgetsBinding.instance.addPostFrameCallback((_) { + ref.refresh(feeSheetSessionCacheProvider); + ref.read(previewTxButtonStateProvider.state).state = false; + }); // _calculateFeesFuture = calculateFees(0); _data = widget.autoFillData; @@ -799,6 +692,10 @@ class _DesktopSendState extends ConsumerState { _addressToggleFlag = true; } + if (isPaynymSend) { + sendToController.text = widget.accountLite!.nymName; + } + _cryptoFocus.addListener(() { if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) { if (_amountToSend == null) { @@ -845,21 +742,6 @@ class _DesktopSendState extends ConsumerState { final String locale = ref.watch( localeServiceChangeNotifierProvider.select((value) => value.locale)); - // if (coin == Coin.firo || coin == Coin.firoTestNet) { - // ref.listen(publicPrivateBalanceStateProvider, (previous, next) { - // if (_amountToSend == null) { - // setState(() { - // _calculateFeesFuture = calculateFees(0); - // }); - // } else { - // setState(() { - // _calculateFeesFuture = - // calculateFees(Format.decimalAmountToSatoshis(_amountToSend!)); - // }); - // } - // }); - // } - return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -975,6 +857,36 @@ class _DesktopSendState extends ConsumerState { const SizedBox( height: 20, ), + if (isPaynymSend) + Text( + "Send to PayNym address", + style: STextStyles.smallMed12(context), + textAlign: TextAlign.left, + ), + if (isPaynymSend) + const SizedBox( + height: 10, + ), + if (isPaynymSend) + TextField( + key: const Key("sendViewPaynymAddressFieldKey"), + controller: sendToController, + enabled: false, + readOnly: true, + style: STextStyles.desktopTextFieldLabel(context).copyWith( + fontSize: 16, + ), + decoration: const InputDecoration( + contentPadding: EdgeInsets.symmetric( + vertical: 18, + horizontal: 16, + ), + ), + ), + if (isPaynymSend) + const SizedBox( + height: 20, + ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -1020,6 +932,7 @@ class _DesktopSendState extends ConsumerState { ? newValue : oldValue), ], + onChanged: (newValue) {}, decoration: InputDecoration( contentPadding: const EdgeInsets.only( top: 22, @@ -1108,199 +1021,204 @@ class _DesktopSendState extends ConsumerState { const SizedBox( height: 20, ), - Text( - "Send to", - style: STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textFieldActiveSearchIconRight, - ), - textAlign: TextAlign.left, - ), - const SizedBox( - height: 10, - ), - ClipRRect( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - child: TextField( - minLines: 1, - maxLines: 5, - key: const Key("sendViewAddressFieldKey"), - controller: sendToController, - readOnly: false, - autocorrect: false, - enableSuggestions: false, - // inputFormatters: [ - // FilteringTextInputFormatter.allow( - // RegExp("[a-zA-Z0-9]{34}")), - // ], - toolbarOptions: const ToolbarOptions( - copy: false, - cut: false, - paste: true, - selectAll: false, - ), - onChanged: (newValue) { - _address = newValue; - _updatePreviewButtonState(_address, _amountToSend); - - setState(() { - _addressToggleFlag = newValue.isNotEmpty; - }); - }, - focusNode: _addressFocusNode, + if (!isPaynymSend) + Text( + "Send to", style: STextStyles.desktopTextExtraSmall(context).copyWith( color: Theme.of(context) .extension()! - .textFieldActiveText, - height: 1.8, + .textFieldActiveSearchIconRight, ), - decoration: standardInputDecoration( - "Enter ${coin.ticker} address", - _addressFocusNode, - context, - desktopMed: true, - ).copyWith( - contentPadding: const EdgeInsets.only( - left: 16, - top: 11, - bottom: 12, - right: 5, + textAlign: TextAlign.left, + ), + if (!isPaynymSend) + const SizedBox( + height: 10, + ), + if (!isPaynymSend) + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + minLines: 1, + maxLines: 5, + key: const Key("sendViewAddressFieldKey"), + controller: sendToController, + readOnly: false, + autocorrect: false, + enableSuggestions: false, + // inputFormatters: [ + // FilteringTextInputFormatter.allow( + // RegExp("[a-zA-Z0-9]{34}")), + // ], + toolbarOptions: const ToolbarOptions( + copy: false, + cut: false, + paste: true, + selectAll: false, ), - suffixIcon: Padding( - padding: sendToController.text.isEmpty - ? const EdgeInsets.only(right: 8) - : const EdgeInsets.only(right: 0), - child: UnconstrainedBox( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - _addressToggleFlag - ? TextFieldIconButton( - key: const Key( - "sendViewClearAddressFieldButtonKey"), - onTap: () { - sendToController.text = ""; - _address = ""; - _updatePreviewButtonState( - _address, _amountToSend); - setState(() { - _addressToggleFlag = false; - }); - }, - child: const XIcon(), - ) - : TextFieldIconButton( - key: const Key( - "sendViewPasteAddressFieldButtonKey"), - onTap: pasteAddress, - child: sendToController.text.isEmpty - ? const ClipboardIcon() - : const XIcon(), - ), - if (sendToController.text.isEmpty) - TextFieldIconButton( - key: const Key("sendViewAddressBookButtonKey"), - onTap: () async { - final entry = - await showDialog( - context: context, - builder: (context) => DesktopDialog( - maxWidth: 696, - maxHeight: 600, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.only( - left: 32, - ), - child: Text( - "Address book", - style: - STextStyles.desktopH3(context), - ), - ), - const DesktopDialogCloseButton(), - ], - ), - Expanded( - child: AddressBookAddressChooser( - coin: coin, - ), - ), - ], - ), + onChanged: (newValue) { + _address = newValue; + _updatePreviewButtonState(_address, _amountToSend); + + setState(() { + _addressToggleFlag = newValue.isNotEmpty; + }); + }, + focusNode: _addressFocusNode, + style: STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context) + .extension()! + .textFieldActiveText, + height: 1.8, + ), + decoration: standardInputDecoration( + "Enter ${coin.ticker} address", + _addressFocusNode, + context, + desktopMed: true, + ).copyWith( + contentPadding: const EdgeInsets.only( + left: 16, + top: 11, + bottom: 12, + right: 5, + ), + suffixIcon: Padding( + padding: sendToController.text.isEmpty + ? const EdgeInsets.only(right: 8) + : const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + _addressToggleFlag + ? TextFieldIconButton( + key: const Key( + "sendViewClearAddressFieldButtonKey"), + onTap: () { + sendToController.text = ""; + _address = ""; + _updatePreviewButtonState( + _address, _amountToSend); + setState(() { + _addressToggleFlag = false; + }); + }, + child: const XIcon(), + ) + : TextFieldIconButton( + key: const Key( + "sendViewPasteAddressFieldButtonKey"), + onTap: pasteAddress, + child: sendToController.text.isEmpty + ? const ClipboardIcon() + : const XIcon(), ), - ); - - if (entry != null) { - sendToController.text = - entry.other ?? entry.label; - - _address = entry.address; - - _updatePreviewButtonState( - _address, - _amountToSend, + if (sendToController.text.isEmpty) + TextFieldIconButton( + key: const Key("sendViewAddressBookButtonKey"), + onTap: () async { + final entry = + await showDialog( + context: context, + builder: (context) => DesktopDialog( + maxWidth: 696, + maxHeight: 600, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + ), + child: Text( + "Address book", + style: STextStyles.desktopH3( + context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Expanded( + child: AddressBookAddressChooser( + coin: coin, + ), + ), + ], + ), + ), ); - setState(() { - _addressToggleFlag = true; - }); - } - }, - child: const AddressBookIcon(), - ), - // if (sendToController.text.isEmpty) - // TextFieldIconButton( - // key: const Key("sendViewScanQrButtonKey"), - // onTap: scanQr, - // child: const QrCodeIcon(), - // ) - ], + if (entry != null) { + sendToController.text = + entry.other ?? entry.label; + + _address = entry.address; + + _updatePreviewButtonState( + _address, + _amountToSend, + ); + + setState(() { + _addressToggleFlag = true; + }); + } + }, + child: const AddressBookIcon(), + ), + // if (sendToController.text.isEmpty) + // TextFieldIconButton( + // key: const Key("sendViewScanQrButtonKey"), + // onTap: scanQr, + // child: const QrCodeIcon(), + // ) + ], + ), ), ), ), ), ), - ), - Builder( - builder: (_) { - final error = _updateInvalidAddressText( - _address ?? "", - ref.read(walletsChangeNotifierProvider).getManager(walletId), - ); + if (!isPaynymSend) + Builder( + builder: (_) { + final error = _updateInvalidAddressText( + _address ?? "", + ref.read(walletsChangeNotifierProvider).getManager(walletId), + ); - if (error == null || error.isEmpty) { - return Container(); - } else { - return Align( - alignment: Alignment.topLeft, - child: Padding( - padding: const EdgeInsets.only( - left: 12.0, - top: 4.0, - ), - child: Text( - error, - textAlign: TextAlign.left, - style: STextStyles.label(context).copyWith( - color: - Theme.of(context).extension()!.textError, + if (error == null || error.isEmpty) { + return Container(); + } else { + return Align( + alignment: Alignment.topLeft, + child: Padding( + padding: const EdgeInsets.only( + left: 12.0, + top: 4.0, + ), + child: Text( + error, + textAlign: TextAlign.left, + style: STextStyles.label(context).copyWith( + color: Theme.of(context) + .extension()! + .textError, + ), ), ), - ), - ); - } - }, - ), + ); + } + }, + ), // const SizedBox( // height: 20, // ), @@ -1368,9 +1286,10 @@ class _DesktopSendState extends ConsumerState { // ), // ), // ), - const SizedBox( - height: 20, - ), + if (!isPaynymSend) + const SizedBox( + height: 20, + ), if (coin != Coin.epicCash) Text( "Transaction fee (estimated)",