From 15d42834aaf6b6dbc99c2b7353e273faf2960549 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 07:11:44 -0600 Subject: [PATCH 01/12] mobile coin control navigation and amount label fixes --- lib/pages/coin_control/coin_control_view.dart | 40 ++++++++++--------- lib/pages/coin_control/utxo_card.dart | 6 ++- lib/route_generator.dart | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/lib/pages/coin_control/coin_control_view.dart b/lib/pages/coin_control/coin_control_view.dart index d1228f9c7..c322696db 100644 --- a/lib/pages/coin_control/coin_control_view.dart +++ b/lib/pages/coin_control/coin_control_view.dart @@ -49,7 +49,7 @@ class CoinControlView extends ConsumerStatefulWidget { final String walletId; final CoinControlViewType type; - final int? requestedTotal; + final Amount? requestedTotal; final Set? selectedUTXOs; @override @@ -673,7 +673,7 @@ class _CoinControlViewState extends ConsumerState { ), Builder( builder: (context) { - int selectedSum = + final int selectedSumInt = _selectedAvailable.isEmpty ? 0 : _selectedAvailable @@ -682,15 +682,19 @@ class _CoinControlViewState extends ConsumerState { (value, element) => value += element, ); + final selectedSum = + selectedSumInt.toAmountAsRaw( + fractionDigits: coin.decimals, + ); return Text( - "${selectedSum.toAmountAsRaw(fractionDigits: coin.decimals).localizedStringAsFixed( - locale: ref.watch( - localeServiceChangeNotifierProvider - .select( - (value) => value.locale, - ), - ), - )} ${coin.ticker}", + "${selectedSum.localizedStringAsFixed( + locale: ref.watch( + localeServiceChangeNotifierProvider + .select( + (value) => value.locale, + ), + ), + )} ${coin.ticker}", style: widget.requestedTotal == null ? STextStyles.w600_14(context) : STextStyles.w600_14(context).copyWith( @@ -731,14 +735,14 @@ class _CoinControlViewState extends ConsumerState { style: STextStyles.w600_14(context), ), Text( - "${widget.requestedTotal!.toAmountAsRaw(fractionDigits: coin.decimals).localizedStringAsFixed( - locale: ref.watch( - localeServiceChangeNotifierProvider - .select( - (value) => value.locale, - ), - ), - )} ${coin.ticker}", + "${widget.requestedTotal!.localizedStringAsFixed( + locale: ref.watch( + localeServiceChangeNotifierProvider + .select( + (value) => value.locale, + ), + ), + )} ${coin.ticker}", style: STextStyles.w600_14(context), ), ], diff --git a/lib/pages/coin_control/utxo_card.dart b/lib/pages/coin_control/utxo_card.dart index d0cba1f39..309936ee6 100644 --- a/lib/pages/coin_control/utxo_card.dart +++ b/lib/pages/coin_control/utxo_card.dart @@ -124,13 +124,15 @@ class _UtxoCardState extends ConsumerState { mainAxisSize: MainAxisSize.min, children: [ Text( - "${utxo.value.toAmountAsRaw(fractionDigits: coin.decimals).localizedStringAsFixed( + "${utxo.value.toAmountAsRaw( + fractionDigits: coin.decimals, + ).localizedStringAsFixed( locale: ref.watch( localeServiceChangeNotifierProvider.select( (value) => value.locale, ), ), - )}} ${coin.ticker}", + )} ${coin.ticker}", style: STextStyles.w600_14(context), ), const SizedBox( diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 340b7803d..41043f3bb 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -337,7 +337,7 @@ class RouteGenerator { ), ); } else if (args - is Tuple4?>) { + is Tuple4?>) { return getRoute( shouldUseMaterialRoute: useMaterialPageRoute, builder: (_) => CoinControlView( From 7eec4b9f2f7a9aad188960fa15d48aad44f338b2 Mon Sep 17 00:00:00 2001 From: Diego Salazar Date: Tue, 11 Apr 2023 17:44:13 -0600 Subject: [PATCH 02/12] Bump version (1.7.0, build 156) --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index e20b3e5ad..5d532412a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Stack Wallet # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.7.0+153 +version: 1.7.0+156 environment: sdk: ">=2.17.0 <3.0.0" From cdfeb95fdf2d217858a0d4e094157ff6411ca5a2 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 07:42:07 -0600 Subject: [PATCH 03/12] exchange form localisation number parsing fix --- lib/pages/exchange_view/exchange_form.dart | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart index 3d4dcfcde..e7b2f79af 100644 --- a/lib/pages/exchange_view/exchange_form.dart +++ b/lib/pages/exchange_view/exchange_form.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:intl/intl.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/models/exchange/aggregate_currency.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; @@ -109,7 +110,7 @@ class _ExchangeFormState extends ConsumerState { _sendFieldOnChangedTimer?.cancel(); _sendFieldOnChangedTimer = Timer(_valueCheckInterval, () async { - final newFromAmount = Decimal.tryParse(value); + final newFromAmount = _localizedStringToNum(value); await ref .read(exchangeFormStateProvider) @@ -123,7 +124,7 @@ class _ExchangeFormState extends ConsumerState { _receiveFieldOnChangedTimer?.cancel(); _receiveFieldOnChangedTimer = Timer(_valueCheckInterval, () async { - final newToAmount = Decimal.tryParse(value); + final newToAmount = _localizedStringToNum(value); await ref .read(exchangeFormStateProvider) @@ -131,6 +132,20 @@ class _ExchangeFormState extends ConsumerState { }); } + Decimal? _localizedStringToNum(String? value) { + if (value == null) { + return null; + } + try { + final numFromLocalised = NumberFormat.decimalPattern( + ref.read(localeServiceChangeNotifierProvider).locale) + .parse(value); + return Decimal.tryParse(numFromLocalised.toString()); + } catch (_) { + return null; + } + } + Future _getAggregateCurrency(Currency currency) async { final rateType = ref.read(exchangeFormStateProvider).exchangeRateType; final currencies = await ExchangeDataLoadingService.instance.isar.currencies From eb9f76ad022267e4ff726136a23e1dabbf719e9d Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 08:04:22 -0600 Subject: [PATCH 04/12] desktop loading token wallet wallet white screen nav fix --- lib/widgets/wallet_card.dart | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/widgets/wallet_card.dart b/lib/widgets/wallet_card.dart index 5e1ed21fd..399ae6211 100644 --- a/lib/widgets/wallet_card.dart +++ b/lib/widgets/wallet_card.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart'; import 'package:stackwallet/pages/token_view/token_view.dart'; import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart'; @@ -10,6 +11,7 @@ import 'package:stackwallet/providers/db/main_db_provider.dart'; import 'package:stackwallet/providers/global/secure_store_provider.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart'; +import 'package:stackwallet/services/coins/manager.dart'; import 'package:stackwallet/services/ethereum/ethereum_token_service.dart'; import 'package:stackwallet/services/transaction_notification_tracker.dart'; import 'package:stackwallet/utilities/constants.dart'; @@ -35,6 +37,24 @@ class SimpleWalletCard extends ConsumerWidget { final bool popPrevious; final NavigatorState? desktopNavigatorState; + Future _loadTokenWallet( + BuildContext context, + WidgetRef ref, + Manager manager, + EthContract contract, + ) async { + ref.read(tokenServiceStateProvider.state).state = EthTokenWallet( + token: contract, + secureStore: ref.read(secureStoreProvider), + ethWallet: manager.wallet as EthereumWallet, + tracker: TransactionNotificationTracker( + walletId: walletId, + ), + ); + + await ref.read(tokenServiceProvider)!.initialize(); + } + void _openWallet(BuildContext context, WidgetRef ref) async { final nav = Navigator.of(context); @@ -70,24 +90,18 @@ class SimpleWalletCard extends ConsumerWidget { if (contractAddress != null) { final contract = ref.read(mainDBProvider).getEthContractSync(contractAddress!)!; - ref.read(tokenServiceStateProvider.state).state = EthTokenWallet( - token: contract, - secureStore: ref.read(secureStoreProvider), - ethWallet: manager.wallet as EthereumWallet, - tracker: TransactionNotificationTracker( - walletId: walletId, - ), - ); await showLoading( - whileFuture: ref.read(tokenServiceProvider)!.initialize(), + whileFuture: _loadTokenWallet(context, ref, manager, contract), context: context, opaqueBG: true, message: "Loading ${contract.name}", ); - // pop loading - nav.pop(); + if (desktopNavigatorState == null) { + // pop loading + nav.pop(); + } if (desktopNavigatorState != null) { await desktopNavigatorState!.pushNamed( From 1e71e3d61581d13b2525c5a2eff5dcf6c9636d2a Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 08:09:04 -0600 Subject: [PATCH 05/12] epic amount type cast error fix --- lib/services/coins/epiccash/epiccash_wallet.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index 7a39ebb9b..a67f7e183 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -479,7 +479,7 @@ class EpicCashWallet extends CoinServiceAPI "minimumConfirmations": MINIMUM_CONFIRMATIONS, "message": "", "amount": (txData['recipientAmt'] as Amount).raw.toInt(), - "address": (txData['addresss'] as Amount).raw.toInt(), + "address": txData['addresss'] as String, }, name: walletName); message = await receivePort.first; @@ -497,7 +497,7 @@ class EpicCashWallet extends CoinServiceAPI "function": "createTransaction", "wallet": wallet!, "amount": (txData['recipientAmt'] as Amount).raw.toInt(), - "address": (txData['addresss'] as Amount).raw.toInt(), + "address": txData['addresss'] as String, "secretKeyIndex": 0, "epicboxConfig": epicboxConfig.toString(), "minimumConfirmations": MINIMUM_CONFIRMATIONS, From 20f6754de538608b0df743d6238dac2e84405eac Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 08:14:54 -0600 Subject: [PATCH 06/12] epic cancel tx button padding fix desktop --- .../transaction_details_view.dart | 137 ++++++++++-------- 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index ed5e78c64..01a9a69e1 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -1391,77 +1391,88 @@ class _TransactionDetailsViewState false && _transaction.isCancelled == false && _transaction.type == TransactionType.outgoing) - ? SizedBox( - width: MediaQuery.of(context).size.width - 32, - child: TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - Theme.of(context).extension()!.textError, - ), + ? ConditionalParent( + condition: isDesktop, + builder: (child) => Padding( + padding: const EdgeInsets.symmetric( + horizontal: 32, + vertical: 16, ), - onPressed: () async { - final Manager manager = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId); + child: child, + ), + child: SizedBox( + width: MediaQuery.of(context).size.width - 32, + child: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + Theme.of(context).extension()!.textError, + ), + ), + onPressed: () async { + final Manager manager = ref + .read(walletsChangeNotifierProvider) + .getManager(walletId); - if (manager.wallet is EpicCashWallet) { - final String? id = _transaction.slateId; - if (id == null) { + if (manager.wallet is EpicCashWallet) { + final String? id = _transaction.slateId; + if (id == null) { + unawaited(showFloatingFlushBar( + type: FlushBarType.warning, + message: "Could not find Epic transaction ID", + context: context, + )); + return; + } + + unawaited(showDialog( + barrierDismissible: false, + context: context, + builder: (_) => + const CancellingTransactionProgressDialog(), + )); + + final result = await (manager.wallet as EpicCashWallet) + .cancelPendingTransactionAndPost(id); + if (mounted) { + // pop progress dialog + Navigator.of(context).pop(); + + if (result.isEmpty) { + await showDialog( + context: context, + builder: (_) => StackOkDialog( + title: "Transaction cancelled", + onOkPressed: (_) { + manager.refresh(); + Navigator.of(context).popUntil( + ModalRoute.withName( + WalletView.routeName)); + }, + ), + ); + } else { + await showDialog( + context: context, + builder: (_) => StackOkDialog( + title: "Failed to cancel transaction", + message: result, + ), + ); + } + } + } else { unawaited(showFloatingFlushBar( type: FlushBarType.warning, - message: "Could not find Epic transaction ID", + message: "ERROR: Wallet type is not Epic Cash", context: context, )); return; } - - unawaited(showDialog( - barrierDismissible: false, - context: context, - builder: (_) => - const CancellingTransactionProgressDialog(), - )); - - final result = await (manager.wallet as EpicCashWallet) - .cancelPendingTransactionAndPost(id); - if (mounted) { - // pop progress dialog - Navigator.of(context).pop(); - - if (result.isEmpty) { - await showDialog( - context: context, - builder: (_) => StackOkDialog( - title: "Transaction cancelled", - onOkPressed: (_) { - manager.refresh(); - Navigator.of(context).popUntil( - ModalRoute.withName(WalletView.routeName)); - }, - ), - ); - } else { - await showDialog( - context: context, - builder: (_) => StackOkDialog( - title: "Failed to cancel transaction", - message: result, - ), - ); - } - } - } else { - unawaited(showFloatingFlushBar( - type: FlushBarType.warning, - message: "ERROR: Wallet type is not Epic Cash", - context: context, - )); - return; - } - }, - child: Text( - "Cancel Transaction", - style: STextStyles.button(context), + }, + child: Text( + "Cancel Transaction", + style: STextStyles.button(context), + ), ), ), ) From fbe4767e5c57fc83752d5ce5b581e270ef2896cb Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 08:41:35 -0600 Subject: [PATCH 07/12] chans loading indicator --- lib/widgets/loading_indicator.dart | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/widgets/loading_indicator.dart b/lib/widgets/loading_indicator.dart index 8725af439..150397669 100644 --- a/lib/widgets/loading_indicator.dart +++ b/lib/widgets/loading_indicator.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:lottie/lottie.dart'; import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/theme/color_theme.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; class LoadingIndicator extends StatelessWidget { const LoadingIndicator({ @@ -14,17 +16,28 @@ class LoadingIndicator extends StatelessWidget { @override Widget build(BuildContext context) { + final isChan = Theme.of(context).extension()!.themeType == + ThemeType.chan || + Theme.of(context).extension()!.themeType == + ThemeType.darkChans; + return Container( color: Colors.transparent, child: Center( child: SizedBox( width: width, height: height, - child: Lottie.asset( - Assets.lottie.test2, - animate: true, - repeat: true, - ), + child: isChan + ? Image( + image: AssetImage( + Assets.gif.stacyPlain, + ), + ) + : Lottie.asset( + Assets.lottie.test2, + animate: true, + repeat: true, + ), ), ), ); From a85c79b36788e3f410c3d3d186815b61017021a4 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 08:44:08 -0600 Subject: [PATCH 08/12] disable eth send all button --- .../wallet_view/sub_widgets/desktop_send.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 b4b10fa95..664fe0103 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 @@ -994,10 +994,11 @@ class _DesktopSendState extends ConsumerState { ), textAlign: TextAlign.left, ), - CustomTextButton( - text: "Send all ${coin.ticker}", - onTap: sendAllTapped, - ), + if (coin != Coin.ethereum) + CustomTextButton( + text: "Send all ${coin.ticker}", + onTap: sendAllTapped, + ), ], ), const SizedBox( From a344366648215b74581abcb64b6c1955703bca66 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 11:27:31 -0600 Subject: [PATCH 09/12] balance display total fix --- .../subwidgets/desktop_choose_from_stack.dart | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart index 76bd0168a..9a5b52223 100644 --- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart +++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/providers/providers.dart'; +import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -212,7 +214,7 @@ class _DesktopChooseFromStackState ], ), const Spacer(), - BalanceDisplay( + _BalanceDisplay( walletId: walletIds[index], ), const SizedBox( @@ -265,8 +267,8 @@ class _DesktopChooseFromStackState } } -class BalanceDisplay extends ConsumerWidget { - const BalanceDisplay({ +class _BalanceDisplay extends ConsumerWidget { + const _BalanceDisplay({ Key? key, required this.walletId, }) : super(key: key); @@ -280,8 +282,14 @@ class BalanceDisplay extends ConsumerWidget { final locale = ref.watch( localeServiceChangeNotifierProvider.select((value) => value.locale)); + Amount total = manager.balance.total; + if (manager.coin == Coin.firo || manager.coin == Coin.firoTestNet) { + final firoWallet = manager.wallet as FiroWallet; + total += firoWallet.balancePrivate.total; + } + return Text( - "${manager.balance.spendable.localizedStringAsFixed(locale: locale)} " + "${total.localizedStringAsFixed(locale: locale)} " "${manager.coin.ticker}", style: STextStyles.desktopTextExtraSmall(context).copyWith( color: Theme.of(context).extension()!.textSubtitle1, From 35dc0e06c2a6b5bebbead5d0faab9d3300b4b6bd Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 11:29:33 -0600 Subject: [PATCH 10/12] clean up unneeded label --- .../exchange_currency_selection_view.dart | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart index c0d027ff4..ffe7d0492 100644 --- a/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart +++ b/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart @@ -320,14 +320,7 @@ class _ExchangeCurrencySelectionViewState ), ), const SizedBox( - height: 10, - ), - Text( - "Popular coins", - style: STextStyles.smallMed12(context), - ), - const SizedBox( - height: 12, + height: 20, ), Flexible( child: Builder( From 2359674946d49451055721531ad1ef81d498b978 Mon Sep 17 00:00:00 2001 From: julian Date: Wed, 12 Apr 2023 15:15:58 -0600 Subject: [PATCH 11/12] quickfix for swapping between exchanges --- .../exchange_provider_options.dart | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart index c00e7dfe8..f770278f3 100644 --- a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart +++ b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart @@ -13,6 +13,7 @@ import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; +import 'package:stackwallet/utilities/show_loading.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/util.dart'; @@ -94,11 +95,17 @@ class _ExchangeProviderOptionsState onTap: () { if (ref.read(exchangeFormStateProvider).exchange.name != ChangeNowExchange.exchangeName) { - ref.read(exchangeFormStateProvider).updateExchange( - exchange: ChangeNowExchange.instance, - shouldUpdateData: true, - shouldNotifyListeners: true, - ); + showLoading( + whileFuture: + ref.read(exchangeFormStateProvider).updateExchange( + exchange: ChangeNowExchange.instance, + shouldUpdateData: true, + shouldNotifyListeners: true, + ), + context: context, + message: "Updating rates", + isDesktop: isDesktop, + ); } }, child: Container( @@ -333,11 +340,17 @@ class _ExchangeProviderOptionsState onTap: () { if (ref.read(exchangeFormStateProvider).exchange.name != MajesticBankExchange.exchangeName) { - ref.read(exchangeFormStateProvider).updateExchange( - exchange: MajesticBankExchange.instance, - shouldUpdateData: true, - shouldNotifyListeners: true, - ); + showLoading( + whileFuture: + ref.read(exchangeFormStateProvider).updateExchange( + exchange: MajesticBankExchange.instance, + shouldUpdateData: true, + shouldNotifyListeners: true, + ), + context: context, + isDesktop: isDesktop, + message: "Updating rates", + ); } }, child: Container( From 8be96701daa494a956d0f5156dafa1f701ebf580 Mon Sep 17 00:00:00 2001 From: julian-CStack Date: Wed, 12 Apr 2023 17:36:14 -0600 Subject: [PATCH 12/12] WIP select firo balance for swap --- .../exchange_step_views/step_4_view.dart | 395 +++++++++++------- 1 file changed, 239 insertions(+), 156 deletions(-) diff --git a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart index 4a86254c4..b7bdf9e46 100644 --- a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart +++ b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart @@ -15,18 +15,22 @@ import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dia import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/route_generator.dart'; +import 'package:stackwallet/services/coins/firo/firo_wallet.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart'; +import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; +import 'package:tuple/tuple.dart'; class Step4View extends ConsumerStatefulWidget { const Step4View({ @@ -120,6 +124,213 @@ class _Step4ViewState extends ConsumerState { } } + Future _showSendFromFiroBalanceSelectSheet(String walletId) async { + final firoWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(walletId) + .wallet as FiroWallet; + final locale = ref.read(localeServiceChangeNotifierProvider).locale; + + return await showModalBottomSheet( + context: context, + backgroundColor: + Theme.of(context).extension()!.backgroundAppBar, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular( + Constants.size.circularBorderRadius * 3, + ), + ), + ), + builder: (context) { + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox( + height: 32, + ), + Text( + "Select Firo balance", + style: STextStyles.pageTitleH2(context), + ), + const SizedBox( + height: 32, + ), + SecondaryButton( + label: + "${firoWallet.balancePrivate.spendable.localizedStringAsFixed( + locale: locale, + )} (private)", + onPressed: () => Navigator.of(context).pop(false), + ), + const SizedBox( + height: 16, + ), + SecondaryButton( + label: "${firoWallet.balance.spendable.localizedStringAsFixed( + locale: locale, + )} (public)", + onPressed: () => Navigator.of(context).pop(true), + ), + const SizedBox( + height: 32, + ), + ], + ), + ); + }, + ); + } + + Future _confirmSend(Tuple2 tuple) async { + final bool firoPublicSend; + if (tuple.item2 == Coin.firo) { + final result = await _showSendFromFiroBalanceSelectSheet(tuple.item1); + if (result == null) { + return; + } else { + firoPublicSend = result; + } + } else { + firoPublicSend = false; + } + + final manager = + ref.read(walletsChangeNotifierProvider).getManager(tuple.item1); + + final Amount amount = model.sendAmount.toAmount( + fractionDigits: manager.coin.decimals, + ); + final address = model.trade!.payInAddress; + + bool wasCancelled = false; + try { + if (!mounted) return; + + unawaited( + showDialog( + context: context, + useSafeArea: false, + barrierDismissible: false, + builder: (context) { + return BuildingTransactionDialog( + coin: manager.coin, + onCancel: () { + wasCancelled = true; + }, + ); + }, + ), + ); + + final time = Future.delayed( + const Duration( + milliseconds: 2500, + ), + ); + + Future> txDataFuture; + + if (firoPublicSend) { + txDataFuture = (manager.wallet as FiroWallet).prepareSendPublic( + address: address, + amount: amount, + args: { + "feeRate": FeeRateType.average, + // ref.read(feeRateTypeStateProvider) + }, + ); + } else { + txDataFuture = manager.prepareSend( + address: address, + amount: amount, + args: { + "feeRate": FeeRateType.average, + // ref.read(feeRateTypeStateProvider) + }, + ); + } + + final results = await Future.wait([ + txDataFuture, + time, + ]); + + final txData = results.first as Map; + + if (!wasCancelled) { + // pop building dialog + + if (mounted) { + Navigator.of(context).pop(); + } + + txData["note"] = + "${model.trade!.payInCurrency.toUpperCase()}/${model.trade!.payOutCurrency.toUpperCase()} exchange"; + txData["address"] = address; + + if (mounted) { + unawaited( + Navigator.of(context).push( + RouteGenerator.getRoute( + shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute, + builder: (_) => ConfirmChangeNowSendView( + transactionInfo: txData, + walletId: tuple.item1, + routeOnSuccessName: HomeView.routeName, + trade: model.trade!, + ), + settings: const RouteSettings( + name: ConfirmChangeNowSendView.routeName, + ), + ), + ), + ); + } + } + } catch (e) { + if (mounted && !wasCancelled) { + // pop building dialog + Navigator.of(context).pop(); + + unawaited( + showDialog( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return StackDialog( + title: "Transaction failed", + message: e.toString(), + rightButton: TextButton( + style: Theme.of(context) + .extension()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Ok", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension()! + .buttonTextSecondary, + ), + ), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ); + }, + ), + ); + } + } + } + @override Widget build(BuildContext context) { final bool isWalletCoin = @@ -244,11 +455,15 @@ class _Step4ViewState extends ConsumerState { text: model.sendAmount.toString()); await clipboard.setData(data); - unawaited(showFloatingFlushBar( - type: FlushBarType.info, - message: "Copied to clipboard", - context: context, - )); + if (mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + } }, child: Row( children: [ @@ -302,11 +517,15 @@ class _Step4ViewState extends ConsumerState { final data = ClipboardData( text: model.trade!.payInAddress); await clipboard.setData(data); - unawaited(showFloatingFlushBar( - type: FlushBarType.info, - message: "Copied to clipboard", - context: context, - )); + if (mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + } }, child: Row( children: [ @@ -365,11 +584,15 @@ class _Step4ViewState extends ConsumerState { final data = ClipboardData( text: model.trade!.tradeId); await clipboard.setData(data); - unawaited(showFloatingFlushBar( - type: FlushBarType.info, - message: "Copied to clipboard", - context: context, - )); + if (mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + } }, child: SvgPicture.asset( Assets.svg.copy, @@ -521,147 +744,7 @@ class _Step4ViewState extends ConsumerState { model.sendTicker.toLowerCase() == tuple.item2.ticker.toLowerCase() ? () async { - final manager = ref - .read( - walletsChangeNotifierProvider) - .getManager(tuple.item1); - - final Amount amount = - model.sendAmount.toAmount( - fractionDigits: - manager.coin.decimals, - ); - final address = - model.trade!.payInAddress; - - try { - bool wasCancelled = false; - - unawaited( - showDialog( - context: context, - useSafeArea: false, - barrierDismissible: false, - builder: (context) { - return BuildingTransactionDialog( - coin: manager.coin, - onCancel: () { - wasCancelled = true; - - Navigator.of(context) - .pop(); - }, - ); - }, - ), - ); - - final time = - Future.delayed( - const Duration( - milliseconds: 2500, - ), - ); - - final txDataFuture = - manager.prepareSend( - address: address, - amount: amount, - args: { - "feeRate": - FeeRateType.average, - // ref.read(feeRateTypeStateProvider) - }, - ); - - final results = - await Future.wait([ - txDataFuture, - time, - ]); - - final txData = results.first - as Map; - - if (!wasCancelled) { - // pop building dialog - - if (mounted) { - Navigator.of(context).pop(); - } - - txData["note"] = - "${model.trade!.payInCurrency.toUpperCase()}/${model.trade!.payOutCurrency.toUpperCase()} exchange"; - txData["address"] = address; - - if (mounted) { - unawaited( - Navigator.of(context) - .push( - RouteGenerator.getRoute( - shouldUseMaterialRoute: - RouteGenerator - .useMaterialPageRoute, - builder: (_) => - ConfirmChangeNowSendView( - transactionInfo: txData, - walletId: tuple.item1, - routeOnSuccessName: - HomeView.routeName, - trade: model.trade!, - ), - settings: - const RouteSettings( - name: - ConfirmChangeNowSendView - .routeName, - ), - ), - )); - } - } - } catch (e) { - // if (mounted) { - // pop building dialog - Navigator.of(context).pop(); - - unawaited(showDialog( - context: context, - useSafeArea: false, - barrierDismissible: true, - builder: (context) { - return StackDialog( - title: "Transaction failed", - message: e.toString(), - rightButton: TextButton( - style: Theme.of(context) - .extension< - StackColors>()! - .getSecondaryEnabledButtonStyle( - context), - child: Text( - "Ok", - style: - STextStyles.button( - context) - .copyWith( - color: Theme.of( - context) - .extension< - StackColors>()! - .buttonTextSecondary, - ), - ), - onPressed: () { - Navigator.of(context) - .pop(); - }, - ), - ); - }, - )); - // } - } + await _confirmSend(tuple); } : () { Navigator.of(context).push(