diff --git a/crypto_plugins/flutter_libmonero b/crypto_plugins/flutter_libmonero index e81b1b7c2..e62cfc2ca 160000 --- a/crypto_plugins/flutter_libmonero +++ b/crypto_plugins/flutter_libmonero @@ -1 +1 @@ -Subproject commit e81b1b7c2d8114435a9458ab2e439f4393f626e7 +Subproject commit e62cfc2cae093346bd547ed1379f99c1ed1fe537 diff --git a/lib/models/contact_address_entry_data.dart b/lib/models/contact_address_entry_data.dart index 25677b13d..7c4641302 100644 --- a/lib/models/contact_address_entry_data.dart +++ b/lib/models/contact_address_entry_data.dart @@ -57,7 +57,10 @@ class AddressEntryData extends ChangeNotifier { } bool get isValidAddress { - if (_address == null || coin == null) { + if ( coin == null) { + return true; + } + if (_address == null) { return false; } return AddressUtils.validateAddress(_address!, _coin!); diff --git a/lib/models/exchange/exchange_form_state.dart b/lib/models/exchange/exchange_form_state.dart index 32578ebd9..58562e449 100644 --- a/lib/models/exchange/exchange_form_state.dart +++ b/lib/models/exchange/exchange_form_state.dart @@ -2,9 +2,7 @@ import 'package:decimal/decimal.dart'; import 'package:flutter/foundation.dart'; import 'package:stackwallet/models/exchange/aggregate_currency.dart'; import 'package:stackwallet/models/exchange/response_objects/estimate.dart'; -import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart'; import 'package:stackwallet/services/exchange/exchange.dart'; -import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart'; import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; @@ -325,28 +323,28 @@ class ExchangeFormState extends ChangeNotifier { required bool shouldNotifyListeners, }) async { try { - switch (exchange.name) { - case ChangeNowExchange.exchangeName: - if (!_exchangeSupported( - exchangeName: exchange.name, - sendCurrency: sendCurrency, - receiveCurrency: receiveCurrency, - exchangeRateType: exchangeRateType, - )) { - _exchange = MajesticBankExchange.instance; - } - break; - case MajesticBankExchange.exchangeName: - if (!_exchangeSupported( - exchangeName: exchange.name, - sendCurrency: sendCurrency, - receiveCurrency: receiveCurrency, - exchangeRateType: exchangeRateType, - )) { - _exchange = ChangeNowExchange.instance; - } - break; - } + // switch (exchange.name) { + // case ChangeNowExchange.exchangeName: + // if (!_exchangeSupported( + // exchangeName: exchange.name, + // sendCurrency: sendCurrency, + // receiveCurrency: receiveCurrency, + // exchangeRateType: exchangeRateType, + // )) { + // _exchange = MajesticBankExchange.instance; + // } + // break; + // case MajesticBankExchange.exchangeName: + // if (!_exchangeSupported( + // exchangeName: exchange.name, + // sendCurrency: sendCurrency, + // receiveCurrency: receiveCurrency, + // exchangeRateType: exchangeRateType, + // )) { + // _exchange = ChangeNowExchange.instance; + // } + // break; + // } await _updateRanges(shouldNotifyListeners: false); await _updateEstimate(shouldNotifyListeners: false); diff --git a/lib/pages/coin_control/utxo_details_view.dart b/lib/pages/coin_control/utxo_details_view.dart index c08b856c8..ca7236862 100644 --- a/lib/pages/coin_control/utxo_details_view.dart +++ b/lib/pages/coin_control/utxo_details_view.dart @@ -138,270 +138,228 @@ class _UtxoDetailsViewState extends ConsumerState { ), ), child: StreamBuilder( - stream: streamUTXO, - builder: (context, snapshot) { - if (snapshot.hasData) { - utxo = snapshot.data!; - } - return ConditionalParent( - condition: isDesktop, - builder: (child) { - return DesktopDialog( - maxHeight: double.infinity, - child: Column( + stream: streamUTXO, + builder: (context, snapshot) { + if (snapshot.hasData) { + utxo = snapshot.data!; + } + return ConditionalParent( + condition: isDesktop, + builder: (child) { + return DesktopDialog( + maxHeight: double.infinity, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "Output details", + style: STextStyles.desktopH3(context), + ), + ), + DesktopDialogCloseButton( + onPressedOverride: () { + Navigator.of(context) + .pop(_popWithRefresh ? "refresh" : null); + }, + ), + ], + ), + IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + top: 10, + ), + child: Column( + children: [ + IntrinsicHeight( + child: RoundedContainer( + padding: EdgeInsets.zero, + color: Colors.transparent, + borderColor: Theme.of(context) + .extension()! + .textFieldDefaultBG, + child: child, + ), + ), + const SizedBox( + height: 20, + ), + SecondaryButton( + buttonHeight: ButtonHeight.l, + label: utxo!.isBlocked ? "Unfreeze" : "Freeze", + onPressed: _toggleFreeze, + ), + ], + ), + ), + ), + ], + ), + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (!isDesktop) + const SizedBox( + height: 10, + ), + RoundedContainer( + padding: const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Padding( - padding: const EdgeInsets.only(left: 32), - child: Text( - "Output details", - style: STextStyles.desktopH3(context), + if (isDesktop) + UTXOStatusIcon( + blocked: utxo!.isBlocked, + status: confirmed + ? UTXOStatusIconStatus.confirmed + : UTXOStatusIconStatus.unconfirmed, + background: Theme.of(context) + .extension()! + .popupBG, + selected: false, + width: 32, + height: 32, ), - ), - DesktopDialogCloseButton( - onPressedOverride: () { - Navigator.of(context) - .pop(_popWithRefresh ? "refresh" : null); - }, + if (isDesktop) + const SizedBox( + width: 16, + ), + Text( + "${Format.satoshisToAmount( + utxo!.value, + coin: coin, + ).toStringAsFixed( + coin.decimals, + )} ${coin.ticker}", + style: STextStyles.pageTitleH2(context), ), ], ), - IntrinsicHeight( - child: Padding( - padding: const EdgeInsets.only( - left: 32, - right: 32, - bottom: 32, - top: 10, - ), - child: Column( - children: [ - IntrinsicHeight( - child: RoundedContainer( - padding: EdgeInsets.zero, - color: Colors.transparent, - borderColor: Theme.of(context) + Text( + utxo!.isBlocked + ? "Frozen" + : confirmed + ? "Available" + : "Unconfirmed", + style: STextStyles.w500_14(context).copyWith( + color: utxo!.isBlocked + ? const Color(0xFF7FA2D4) // todo theme + : confirmed + ? Theme.of(context) .extension()! - .textFieldDefaultBG, - child: child, - ), - ), - const SizedBox( - height: 20, - ), - SecondaryButton( - buttonHeight: ButtonHeight.l, - label: utxo!.isBlocked ? "Unfreeze" : "Freeze", - onPressed: _toggleFreeze, - ), - ], - ), + .accentColorGreen + : Theme.of(context) + .extension()! + .accentColorYellow, ), ), ], ), - ); - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (!isDesktop) - const SizedBox( - height: 10, - ), - RoundedContainer( - padding: const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - if (isDesktop) - UTXOStatusIcon( - blocked: utxo!.isBlocked, - status: confirmed - ? UTXOStatusIconStatus.confirmed - : UTXOStatusIconStatus.unconfirmed, - background: Theme.of(context) - .extension()! - .popupBG, - selected: false, - width: 32, - height: 32, - ), - if (isDesktop) - const SizedBox( - width: 16, - ), - Text( - "${Format.satoshisToAmount( - utxo!.value, - coin: coin, - ).toStringAsFixed( - coin.decimals, - )} ${coin.ticker}", - style: STextStyles.pageTitleH2(context), - ), - ], - ), - Text( - utxo!.isBlocked - ? "Frozen" - : confirmed - ? "Available" - : "Unconfirmed", - style: STextStyles.w500_14(context).copyWith( - color: utxo!.isBlocked - ? const Color(0xFF7FA2D4) // todo theme - : confirmed - ? Theme.of(context) - .extension()! - .accentColorGreen - : Theme.of(context) - .extension()! - .accentColorYellow, - ), - ), - ], - ), - ), - const _Div(), - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Label", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - SimpleEditButton( - editValue: utxo!.name, - editLabel: "label", - onValueChanged: (newName) { - MainDB.instance.putUTXO( - utxo!.copyWith( - name: newName, - ), - ); - }, - ), - ], - ), - const SizedBox( - height: 4, - ), - Text( - utxo!.name, - style: STextStyles.w500_14(context), - ), - ], - ), - ), - const _Div(), - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Address", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - isDesktop - ? IconCopyButton( - data: utxo!.address!, - ) - : SimpleCopyButton( - data: utxo!.address!, - ), - ], - ), - const SizedBox( - height: 4, - ), - Text( - utxo!.address!, - style: STextStyles.w500_14(context), - ), - ], - ), - ), - if (label != null && label!.value.isNotEmpty) const _Div(), - if (label != null && label!.value.isNotEmpty) - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Address label", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - isDesktop - ? IconCopyButton( - data: utxo!.address!, - ) - : SimpleCopyButton( - data: label!.value, - ), - ], - ), - const SizedBox( - height: 4, - ), Text( - label!.value, - style: STextStyles.w500_14(context), + "Label", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + SimpleEditButton( + editValue: utxo!.name, + editLabel: "label", + onValueChanged: (newName) { + MainDB.instance.putUTXO( + utxo!.copyWith( + name: newName, + ), + ); + }, ), ], ), - ), - const _Div(), + const SizedBox( + height: 4, + ), + Text( + utxo!.name, + style: STextStyles.w500_14(context), + ), + ], + ), + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Address", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + isDesktop + ? IconCopyButton( + data: utxo!.address!, + ) + : SimpleCopyButton( + data: utxo!.address!, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.address!, + style: STextStyles.w500_14(context), + ), + ], + ), + ), + if (label != null && label!.value.isNotEmpty) const _Div(), + if (label != null && label!.value.isNotEmpty) RoundedContainer( padding: isDesktop ? const EdgeInsets.all(16) @@ -417,7 +375,7 @@ class _UtxoDetailsViewState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "Transaction ID", + "Address label", style: STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension()! @@ -426,10 +384,10 @@ class _UtxoDetailsViewState extends ConsumerState { ), isDesktop ? IconCopyButton( - data: utxo!.address!, + data: label!.value, ) : SimpleCopyButton( - data: utxo!.txid, + data: label!.value, ), ], ), @@ -437,114 +395,155 @@ class _UtxoDetailsViewState extends ConsumerState { height: 4, ), Text( - utxo!.txid, + label!.value, style: STextStyles.w500_14(context), ), ], ), ), - const _Div(), - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context).extension()!.popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Confirmations", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - const SizedBox( - height: 4, - ), - Text( - "${utxo!.getConfirmations(currentHeight)}", - style: STextStyles.w500_14(context), - ), - ], - ), - ), - if (utxo!.isBlocked) const _Div(), - if (utxo!.isBlocked) - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - RoundedContainer( - padding: isDesktop - ? const EdgeInsets.all(16) - : const EdgeInsets.all(12), - color: isDesktop - ? Colors.transparent - : Theme.of(context) + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Transaction ID", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) .extension()! - .popupBG, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - "Freeze reason", - style: - STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, - ), - ), - SimpleEditButton( - editValue: utxo!.blockedReason ?? "", - editLabel: "freeze reason", - onValueChanged: (newReason) { - MainDB.instance.putUTXO( - utxo!.copyWith( - blockedReason: newReason, - ), - ); - }, - ), - ], - ), - const SizedBox( - height: 4, - ), - Text( - utxo!.blockedReason ?? "", - style: STextStyles.w500_14(context), - ), - ], + .textSubtitle1, + ), ), + isDesktop + ? IconCopyButton( + data: utxo!.txid, + ) + : SimpleCopyButton( + data: utxo!.txid, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.txid, + style: STextStyles.w500_14(context), + ), + ], + ), + ), + const _Div(), + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context).extension()!.popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Confirmations", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, ), - if (!isDesktop) const _Div(), - ], - ), - if (!isDesktop) const Spacer(), - if (!isDesktop) - SecondaryButton( - label: utxo!.isBlocked ? "Unfreeze" : "Freeze", - onPressed: _toggleFreeze, - ), - if (!isDesktop) - const SizedBox( - height: 16, - ), - ], - ), - ); - }), + ), + const SizedBox( + height: 4, + ), + Text( + "${utxo!.getConfirmations(currentHeight)}", + style: STextStyles.w500_14(context), + ), + ], + ), + ), + if (utxo!.isBlocked) const _Div(), + if (utxo!.isBlocked) + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + RoundedContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + color: isDesktop + ? Colors.transparent + : Theme.of(context) + .extension()! + .popupBG, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Freeze reason", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension()! + .textSubtitle1, + ), + ), + SimpleEditButton( + editValue: utxo!.blockedReason ?? "", + editLabel: "freeze reason", + onValueChanged: (newReason) { + MainDB.instance.putUTXO( + utxo!.copyWith( + blockedReason: newReason, + ), + ); + }, + ), + ], + ), + const SizedBox( + height: 4, + ), + Text( + utxo!.blockedReason ?? "", + style: STextStyles.w500_14(context), + ), + ], + ), + ), + if (!isDesktop) const _Div(), + ], + ), + if (!isDesktop) const Spacer(), + if (!isDesktop) + SecondaryButton( + label: utxo!.isBlocked ? "Unfreeze" : "Freeze", + onPressed: _toggleFreeze, + ), + if (!isDesktop) + const SizedBox( + height: 16, + ), + ], + ), + ); + }, + ), ); } } 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 1b2376b4c..6980706c3 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 @@ -9,7 +9,6 @@ import 'package:stackwallet/models/isar/exchange_cache/pair.dart'; import 'package:stackwallet/pages/buy_view/sub_widgets/crypto_selection_view.dart'; import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart'; import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart'; -import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -95,11 +94,12 @@ class _ExchangeCurrencySelectionViewState if (widget.pairedTicker == null) { return await _getCurrencies(); } - List currencies = await ExchangeDataLoadingService - .instance.isar.currencies - .where() - .exchangeNameEqualTo(MajesticBankExchange.exchangeName) - .findAll(); + List currencies = []; + // await ExchangeDataLoadingService + // .instance.isar.currencies + // .where() + // .exchangeNameEqualTo(MajesticBankExchange.exchangeName) + // .findAll(); final cn = await ChangeNowExchange.instance.getPairedCurrencies( widget.pairedTicker!, 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 30d40f008..16eb3923f 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 @@ -579,7 +579,7 @@ class _Step4ViewState extends ConsumerState { time, ]); - final txData = results.last + final txData = results.first as Map; if (!wasCancelled) { 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 c0f4312d0..043a10a5e 100644 --- a/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart +++ b/lib/pages/exchange_view/sub_widgets/exchange_provider_options.dart @@ -71,11 +71,12 @@ class _ExchangeProviderOptionsState sendCurrency: sendCurrency, receiveCurrency: receivingCurrency, ); - final showMajesticBank = exchangeSupported( - exchangeName: MajesticBankExchange.exchangeName, - sendCurrency: sendCurrency, - receiveCurrency: receivingCurrency, - ); + final showMajesticBank = false; + // exchangeSupported( + // exchangeName: MajesticBankExchange.exchangeName, + // sendCurrency: sendCurrency, + // receiveCurrency: receivingCurrency, + // ); return RoundedWhiteContainer( padding: isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(12), diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart index 76653bd18..ca853c6a4 100644 --- a/lib/pages/exchange_view/trade_details_view.dart +++ b/lib/pages/exchange_view/trade_details_view.dart @@ -93,7 +93,8 @@ class _TradeDetailsViewState extends ConsumerState { .trades .firstWhere((e) => e.tradeId == tradeId); - if (mounted) { + if (mounted && + trade.exchangeName != MajesticBankExchange.exchangeName) { final exchange = Exchange.fromName(trade.exchangeName); final response = await exchange.updateTrade(trade); diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart index 2b9b12b79..7e9f9b77f 100644 --- a/lib/pages/pinpad_views/lock_screen_view.dart +++ b/lib/pages/pinpad_views/lock_screen_view.dart @@ -14,7 +14,9 @@ import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/biometrics.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.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/widgets/background.dart'; @@ -80,19 +82,47 @@ class _LockscreenViewState extends ConsumerState { if (widget.popOnSuccess) { Navigator.of(context).pop(widget.routeOnSuccessArguments); } else { - unawaited(Navigator.of(context).pushReplacementNamed( - widget.routeOnSuccess, - arguments: widget.routeOnSuccessArguments, - )); - if (widget.routeOnSuccess == HomeView.routeName && - widget.routeOnSuccessArguments is String) { + final loadIntoWallet = widget.routeOnSuccess == HomeView.routeName && + widget.routeOnSuccessArguments is String; + + if (loadIntoWallet) { final walletId = widget.routeOnSuccessArguments as String; - unawaited(Navigator.of(context).pushNamed(WalletView.routeName, - arguments: Tuple2( + + final manager = + ref.read(walletsChangeNotifierProvider).getManager(walletId); + if (manager.coin == Coin.monero || manager.coin == Coin.wownero) { + await showLoading( + opaqueBG: true, + whileFuture: manager.initializeExisting(), + context: context, + message: "Loading ${manager.coin.prettyName} wallet...", + ); + } + } + + if (mounted) { + unawaited( + Navigator.of(context).pushReplacementNamed( + widget.routeOnSuccess, + arguments: widget.routeOnSuccessArguments, + ), + ); + + if (loadIntoWallet) { + final walletId = widget.routeOnSuccessArguments as String; + + unawaited( + Navigator.of(context).pushNamed( + WalletView.routeName, + arguments: Tuple2( walletId, ref .read(walletsChangeNotifierProvider) - .getManagerProvider(walletId)))); + .getManagerProvider(walletId), + ), + ), + ); + } } } } diff --git a/lib/pages/receive_view/addresses/address_tag.dart b/lib/pages/receive_view/addresses/address_tag.dart index df03dc405..56d591301 100644 --- a/lib/pages/receive_view/addresses/address_tag.dart +++ b/lib/pages/receive_view/addresses/address_tag.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_native_splash/cli_commands.dart'; import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; class AddressTag extends StatelessWidget { @@ -16,10 +17,12 @@ class AddressTag extends StatelessWidget { vertical: 5, horizontal: 7, ), - color: Colors.black, + color: Theme.of(context).extension()!.buttonBackPrimary, child: Text( tag.capitalize(), - style: STextStyles.w500_14(context), + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context).extension()!.buttonTextPrimary, + ), ), ); } diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart index 7e308c61f..1dd34f330 100644 --- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart +++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart @@ -62,6 +62,44 @@ class _AddEditNodeViewState extends ConsumerState { late bool saveEnabled; late bool testConnectionEnabled; + Future _xmrHelper(String url, int? port) async { + final uri = Uri.parse(url); + + final String path = uri.path.isEmpty ? "/json_rpc" : uri.path; + + final uriString = "${uri.scheme}://${uri.host}:${port ?? 0}$path"; + + ref.read(nodeFormDataProvider).useSSL = true; + + final response = await testMoneroNodeConnection( + Uri.parse(uriString), + false, + ); + + if (response.cert != null) { + if (mounted) { + final shouldAllowBadCert = await showBadX509CertificateDialog( + response.cert!, + response.url!, + response.port!, + context, + ); + + if (shouldAllowBadCert) { + final response = + await testMoneroNodeConnection(Uri.parse(uriString), true); + ref.read(nodeFormDataProvider).host = url; + return response.success; + } + } + } else { + ref.read(nodeFormDataProvider).host = url; + return response.success; + } + + return false; + } + Future _testConnection({bool showFlushBar = true}) async { final formData = ref.read(nodeFormDataProvider); @@ -86,41 +124,19 @@ class _AddEditNodeViewState extends ConsumerState { case Coin.monero: case Coin.wownero: try { - final uri = Uri.parse(formData.host!); - if (uri.scheme.startsWith("http")) { - final String path = uri.path.isEmpty ? "/json_rpc" : uri.path; + final url = formData.host!; + final uri = Uri.tryParse(url); + if (uri != null) { + if (!uri.hasScheme) { + // try https first + testPassed = await _xmrHelper("https://$url", formData.port); - String uriString = - "${uri.scheme}://${uri.host}:${formData.port ?? 0}$path"; - - if (uri.host == "https") { - ref.read(nodeFormDataProvider).useSSL = true; - } else { - ref.read(nodeFormDataProvider).useSSL = false; - } - - final response = await testMoneroNodeConnection( - Uri.parse(uriString), - false, - ); - - if (response.cert != null) { - if (mounted) { - final shouldAllowBadCert = await showBadX509CertificateDialog( - response.cert!, - response.url!, - response.port!, - context, - ); - - if (shouldAllowBadCert) { - final response = await testMoneroNodeConnection( - Uri.parse(uriString), true); - testPassed = response.success; - } + if (testPassed == false) { + // try http + testPassed = await _xmrHelper("http://$url", formData.port); } } else { - testPassed = response.success; + testPassed = await _xmrHelper(url, formData.port); } } } catch (e, s) { @@ -158,7 +174,7 @@ class _AddEditNodeViewState extends ConsumerState { break; } - if (showFlushBar) { + if (showFlushBar && mounted) { if (testPassed) { unawaited(showFloatingFlushBar( type: FlushBarType.success, @@ -182,7 +198,7 @@ class _AddEditNodeViewState extends ConsumerState { bool? shouldSave; - if (!canConnect) { + if (!canConnect && mounted) { await showDialog( context: context, useSafeArea: true, @@ -975,7 +991,6 @@ class _NodeFormState extends ConsumerState { controller: _usernameController, readOnly: shouldBeReadOnly, enabled: enableField(_usernameController), - keyboardType: TextInputType.number, focusNode: _usernameFocusNode, style: STextStyles.field(context), decoration: standardInputDecoration( @@ -1024,7 +1039,7 @@ class _NodeFormState extends ConsumerState { controller: _passwordController, readOnly: shouldBeReadOnly, enabled: enableField(_passwordController), - keyboardType: TextInputType.number, + obscureText: true, focusNode: _passwordFocusNode, style: STextStyles.field(context), decoration: standardInputDecoration( diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart index 280077819..6521dec0f 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart @@ -282,6 +282,7 @@ abstract class SWB { backupWallet['id'] = manager.walletId; backupWallet['isFavorite'] = manager.isFavorite; backupWallet['mnemonic'] = await manager.mnemonic; + backupWallet['mnemonicPassphrase'] = await manager.mnemonicPassphrase; backupWallet['coinName'] = manager.coin.name; backupWallet['storedChainHeight'] = DB.instance .get(boxName: manager.walletId, key: 'storedChainHeight'); @@ -363,6 +364,7 @@ abstract class SWB { walletId: manager.walletId, restoringStatus: StackRestoringStatus.restoring, mnemonic: mnemonic, + mnemonicPassphrase: mnemonicPassphrase, ); if (_shouldCancelRestore) { @@ -432,6 +434,7 @@ abstract class SWB { address: currentAddress, height: restoreHeight, mnemonic: mnemonic, + mnemonicPassphrase: mnemonicPassphrase, ); } catch (e, s) { Logging.instance.log("$e $s", level: LogLevel.Warning); @@ -440,6 +443,7 @@ abstract class SWB { restoringStatus: StackRestoringStatus.failed, manager: manager, mnemonic: mnemonic, + mnemonicPassphrase: mnemonicPassphrase, ); return false; } diff --git a/lib/pages/stack_privacy_calls.dart b/lib/pages/stack_privacy_calls.dart index 8dc98a23d..e3b0534d1 100644 --- a/lib/pages/stack_privacy_calls.dart +++ b/lib/pages/stack_privacy_calls.dart @@ -148,15 +148,16 @@ class _StackPrivacyCalls extends ConsumerState { ), children: infoToggle ? [ + if (Constants.enableExchange) + const TextSpan( + text: + "Exchange data preloaded for a seamless experience.\n\n"), const TextSpan( text: - "Exchange data preloaded for a seamless experience."), - const TextSpan( - text: - "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."), + "CoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency).\n\n"), TextSpan( text: - "\n\nRecommended for most crypto users.", + "Recommended for most crypto users.", style: isDesktop ? STextStyles .desktopTextExtraExtraSmall600( @@ -170,15 +171,16 @@ class _StackPrivacyCalls extends ConsumerState { ), ] : [ + if (Constants.enableExchange) + const TextSpan( + text: + "Exchange data not preloaded (slower experience).\n\n"), const TextSpan( text: - "Exchange data not preloaded (slower experience)."), - const TextSpan( - text: - "\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."), + "CoinGecko disabled (price changes not shown, no wallet value shown in other currencies).\n\n"), TextSpan( text: - "\n\nRecommended for the privacy conscious.", + "Recommended for the privacy conscious.", style: isDesktop ? STextStyles .desktopTextExtraExtraSmall600( diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index eaea818e9..8d12df5a6 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -44,6 +44,7 @@ import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.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/widgets/background.dart'; @@ -260,11 +261,6 @@ class _WalletViewState extends ConsumerState { void _onExchangePressed(BuildContext context) async { final coin = ref.read(managerProvider).coin; - final currency = ExchangeDataLoadingService.instance.isar.currencies - .where() - .tickerEqualToAnyExchangeNameName(coin.ticker) - .findFirstSync(); - if (coin.isTestNet) { await showDialog( context: context, @@ -273,6 +269,15 @@ class _WalletViewState extends ConsumerState { ), ); } else { + final currency = await showLoading( + whileFuture: ExchangeDataLoadingService.instance.isar.currencies + .where() + .tickerEqualToAnyExchangeNameName(coin.ticker) + .findFirst(), + context: context, + message: "Loading...", + ); + if (mounted) { unawaited( Navigator.of(context).pushNamed( diff --git a/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/stack_privacy_dialog.dart b/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/stack_privacy_dialog.dart index 9045e0006..ecd22237c 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/stack_privacy_dialog.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/stack_privacy_dialog.dart @@ -96,9 +96,10 @@ class _StackPrivacyDialog extends ConsumerState { ), children: infoToggle ? [ - const TextSpan( - text: - "Exchange data preloaded for a seamless experience."), + if (Constants.enableExchange) + const TextSpan( + text: + "Exchange data preloaded for a seamless experience."), const TextSpan( text: "\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."), diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index 4574d0019..0504595ee 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -862,6 +862,9 @@ class EpicCashWallet extends CoinServiceAPI Map? args}) async { try { int realfee = await nativeFee(satoshiAmount); + if (balance.spendable == satoshiAmount) { + satoshiAmount = balance.spendable - realfee; + } Map txData = { "fee": realfee, @@ -906,33 +909,81 @@ class EpicCashWallet extends CoinServiceAPI }); debugPrint(transactionFees); dynamic decodeData; - try { - decodeData = json.decode(transactionFees!); - } catch (e) { - if (ifErrorEstimateFee) { - //Error Not enough funds. Required: 0.56500000, Available: 0.56200000 - if (transactionFees!.contains("Required")) { - var splits = transactionFees!.split(" "); - Decimal required = Decimal.zero; - Decimal available = Decimal.zero; - for (int i = 0; i < splits.length; i++) { - var word = splits[i]; - if (word == "Required:") { - required = Decimal.parse(splits[i + 1].replaceAll(",", "")); - } else if (word == "Available:") { - available = Decimal.parse(splits[i + 1].replaceAll(",", "")); - } + + final available = balance.spendable; + + if (available == satoshiAmount) { + if (transactionFees!.contains("Required")) { + var splits = transactionFees!.split(" "); + Decimal required = Decimal.zero; + Decimal available = Decimal.zero; + for (int i = 0; i < splits.length; i++) { + var word = splits[i]; + if (word == "Required:") { + required = Decimal.parse(splits[i + 1].replaceAll(",", "")); + } else if (word == "Available:") { + available = Decimal.parse(splits[i + 1].replaceAll(",", "")); } - int largestSatoshiFee = - ((required - available) * Decimal.fromInt(100000000)) - .toBigInt() - .toInt(); - Logging.instance.log("largestSatoshiFee $largestSatoshiFee", - level: LogLevel.Info); - return largestSatoshiFee; } + int largestSatoshiFee = + ((required - available) * Decimal.fromInt(100000000)) + .toBigInt() + .toInt(); + var amountSending = satoshiAmount - largestSatoshiFee; + + //Get fees for this new amount + await m.protect(() async { + ReceivePort receivePort = await getIsolate({ + "function": "getTransactionFees", + "wallet": wallet!, + "amount": amountSending, + "minimumConfirmations": MINIMUM_CONFIRMATIONS, + }, name: walletName); + + var message = await receivePort.first; + if (message is String) { + Logging.instance + .log("this is a string $message", level: LogLevel.Error); + stop(receivePort); + throw Exception("getTransactionFees isolate failed"); + } + stop(receivePort); + Logging.instance.log('Closing getTransactionFees!\n $message', + level: LogLevel.Info); + // return message; + transactionFees = message['result'] as String; + }); + } + decodeData = json.decode(transactionFees!); + } else { + try { + decodeData = json.decode(transactionFees!); + } catch (e) { + if (ifErrorEstimateFee) { + //Error Not enough funds. Required: 0.56500000, Available: 0.56200000 + if (transactionFees!.contains("Required")) { + var splits = transactionFees!.split(" "); + Decimal required = Decimal.zero; + Decimal available = Decimal.zero; + for (int i = 0; i < splits.length; i++) { + var word = splits[i]; + if (word == "Required:") { + required = Decimal.parse(splits[i + 1].replaceAll(",", "")); + } else if (word == "Available:") { + available = Decimal.parse(splits[i + 1].replaceAll(",", "")); + } + } + int largestSatoshiFee = + ((required - available) * Decimal.fromInt(100000000)) + .toBigInt() + .toInt(); + Logging.instance.log("largestSatoshiFee $largestSatoshiFee", + level: LogLevel.Info); + return largestSatoshiFee; + } + } + rethrow; } - rethrow; } //TODO: first problem @@ -1799,7 +1850,7 @@ class EpicCashWallet extends CoinServiceAPI // final chunk = { // "timestamp": txTimeArray[0], // "transactions": [txObject], - // }; + // };sendAll // // // result["dateTimeChunks"]. // result["dateTimeChunks"].add(chunk); diff --git a/lib/services/coins/firo/firo_wallet.dart b/lib/services/coins/firo/firo_wallet.dart index cb5b124a1..17af5d914 100644 --- a/lib/services/coins/firo/firo_wallet.dart +++ b/lib/services/coins/firo/firo_wallet.dart @@ -2490,60 +2490,17 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive { }); } - // final int utxosIntValue = utxos.satoshiBalance; - // final Decimal utxosValue = - // Format.satoshisToAmount(utxosIntValue, coin: coin); - - // List balances = List.empty(growable: true); - // - // Decimal lelantusBalance = - // Format.satoshisToAmount(intLelantusBalance, coin: coin); - - // balances.add(lelantusBalance); 0 - // - // balances.add(lelantusBalance * price); 1 - - // Decimal _unconfirmedLelantusBalance = - // Format.satoshisToAmount(unconfirmedLelantusBalance, coin: coin); - - // balances.add(lelantusBalance + utxosValue + _unconfirmedLelantusBalance); 2 - // - // balances.add( - // (lelantusBalance + utxosValue + _unconfirmedLelantusBalance) * price); 3 - - // int availableSats = - // utxos.satoshiBalance - utxos.satoshiBalanceUnconfirmed; - // if (availableSats < 0) { - // availableSats = 0; - // } - // balances.add(Format.satoshisToAmount(availableSats, coin: coin)); 4 + _balancePrivate = Balance( + coin: coin, + total: intLelantusBalance + unconfirmedLelantusBalance, + spendable: intLelantusBalance, + blockedTotal: 0, + pendingSpendable: unconfirmedLelantusBalance, + ); + await updateCachedBalanceSecondary(_balancePrivate!); // wait for updated uxtos to get updated public balance await utxosUpdateFuture; - - // todo: shared total between private and public balances? - _balancePrivate = Balance( - coin: coin, - total: intLelantusBalance + unconfirmedLelantusBalance + balance.total, - spendable: intLelantusBalance, - blockedTotal: 0, - pendingSpendable: unconfirmedLelantusBalance + balance.total, - ); - await updateCachedBalanceSecondary(_balancePrivate!); - // _balance = Balance( - // coin: coin, - // total: utxos.satoshiBalance, - // spendable: availableSats, - // blockedTotal: 0, - // pendingSpendable: utxos.satoshiBalanceUnconfirmed, - // ); - - // Logging.instance.log("balances $balances", level: LogLevel.Info); - // await DB.instance.put( - // boxName: walletId, - // key: 'totalBalance', - // value: balances[2].toString()); - // return balances; } catch (e, s) { Logging.instance.log("Exception rethrown in getFullBalance(): $e\n$s", level: LogLevel.Error); diff --git a/lib/services/exchange/exchange_data_loading_service.dart b/lib/services/exchange/exchange_data_loading_service.dart index ad754cb56..566640adb 100644 --- a/lib/services/exchange/exchange_data_loading_service.dart +++ b/lib/services/exchange/exchange_data_loading_service.dart @@ -273,25 +273,25 @@ class ExchangeDataLoadingService { // } Future loadMajesticBankCurrencies() async { - final exchange = MajesticBankExchange.instance; - final responseCurrencies = await exchange.getAllCurrencies(false); - - if (responseCurrencies.value != null) { - await isar.writeTxn(() async { - final idsToDelete = await isar.currencies - .where() - .exchangeNameEqualTo(MajesticBankExchange.exchangeName) - .idProperty() - .findAll(); - await isar.currencies.deleteAll(idsToDelete); - await isar.currencies.putAll(responseCurrencies.value!); - }); - } else { - Logging.instance.log( - "loadMajesticBankCurrencies: $responseCurrencies", - level: LogLevel.Warning, - ); - } + // final exchange = MajesticBankExchange.instance; + // final responseCurrencies = await exchange.getAllCurrencies(false); + // + // if (responseCurrencies.value != null) { + await isar.writeTxn(() async { + final idsToDelete = await isar.currencies + .where() + .exchangeNameEqualTo(MajesticBankExchange.exchangeName) + .idProperty() + .findAll(); + await isar.currencies.deleteAll(idsToDelete); + // await isar.currencies.putAll(responseCurrencies.value!); + }); + // } else { + // Logging.instance.log( + // "loadMajesticBankCurrencies: $responseCurrencies", + // level: LogLevel.Warning, + // ); + // } } // Future loadMajesticBankPairs() async { diff --git a/lib/services/exchange/majestic_bank/majestic_bank_api.dart b/lib/services/exchange/majestic_bank/majestic_bank_api.dart index 61eb886a4..5641afd55 100644 --- a/lib/services/exchange/majestic_bank/majestic_bank_api.dart +++ b/lib/services/exchange/majestic_bank/majestic_bank_api.dart @@ -14,10 +14,11 @@ import 'package:stackwallet/services/exchange/exchange_response.dart'; import 'package:stackwallet/utilities/logger.dart'; class MajesticBankAPI { - static const String scheme = "https"; - static const String authority = "majesticbank.sc"; - static const String version = "v1"; - static const kMajesticBankRefCode = "rjWugM"; + // ensure no api calls go out to mb + static const String scheme = ""; //"""https"; + static const String authority = ""; //"""majesticbank.sc"; + static const String version = ""; //"""v1"; + static const kMajesticBankRefCode = ""; //"""rjWugM"; MajesticBankAPI._(); @@ -33,6 +34,8 @@ class MajesticBankAPI { } Future _makeGetRequest(Uri uri) async { + return null; + final client = this.client ?? http.Client(); int code = -1; try { diff --git a/lib/services/notifications_service.dart b/lib/services/notifications_service.dart index 5408d6126..47170fd70 100644 --- a/lib/services/notifications_service.dart +++ b/lib/services/notifications_service.dart @@ -7,6 +7,7 @@ import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/notification_model.dart'; import 'package:stackwallet/services/exchange/exchange_response.dart'; +import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart'; import 'package:stackwallet/services/node_service.dart'; import 'package:stackwallet/services/notifications_api.dart'; import 'package:stackwallet/services/trade_service.dart'; @@ -197,57 +198,59 @@ class NotificationsService extends ChangeNotifier { final oldTrade = trades.first; late final ExchangeResponse response; - try { - final exchange = Exchange.fromName(oldTrade.exchangeName); - response = await exchange.updateTrade(oldTrade); - } catch (_) { - return; - } - - if (response.value == null) { - return; - } - - final trade = response.value!; - - // only update if status has changed - if (trade.status != notification.title) { - bool shouldWatchForUpdates = true; - // TODO: make sure we set shouldWatchForUpdates to correct value here - switch (trade.status) { - case "Refunded": - case "refunded": - case "Failed": - case "failed": - case "closed": - case "expired": - case "Finished": - case "finished": - case "Completed": - case "completed": - case "Not found": - shouldWatchForUpdates = false; - break; - default: - shouldWatchForUpdates = true; + if (oldTrade.exchangeName != MajesticBankExchange.exchangeName) { + try { + final exchange = Exchange.fromName(oldTrade.exchangeName); + response = await exchange.updateTrade(oldTrade); + } catch (_) { + return; } - final updatedNotification = notification.copyWith( - title: trade.status, - shouldWatchForUpdates: shouldWatchForUpdates, - ); - - // remove from watch list if shouldWatchForUpdates was changed - if (!shouldWatchForUpdates) { - await _deleteWatchedTradeNotification(notification); + if (response.value == null) { + return; } - // replaces the current notification with the updated one - unawaited(add(updatedNotification, true)); + final trade = response.value!; - // update the trade in db - // over write trade stored in db with updated version - await tradesService.edit(trade: trade, shouldNotifyListeners: true); + // only update if status has changed + if (trade.status != notification.title) { + bool shouldWatchForUpdates = true; + // TODO: make sure we set shouldWatchForUpdates to correct value here + switch (trade.status) { + case "Refunded": + case "refunded": + case "Failed": + case "failed": + case "closed": + case "expired": + case "Finished": + case "finished": + case "Completed": + case "completed": + case "Not found": + shouldWatchForUpdates = false; + break; + default: + shouldWatchForUpdates = true; + } + + final updatedNotification = notification.copyWith( + title: trade.status, + shouldWatchForUpdates: shouldWatchForUpdates, + ); + + // remove from watch list if shouldWatchForUpdates was changed + if (!shouldWatchForUpdates) { + await _deleteWatchedTradeNotification(notification); + } + + // replaces the current notification with the updated one + unawaited(add(updatedNotification, true)); + + // update the trade in db + // over write trade stored in db with updated version + await tradesService.edit(trade: trade, shouldNotifyListeners: true); + } } } } diff --git a/lib/utilities/show_loading.dart b/lib/utilities/show_loading.dart new file mode 100644 index 000000000..4a684d54c --- /dev/null +++ b/lib/utilities/show_loading.dart @@ -0,0 +1,43 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/widgets/custom_loading_overlay.dart'; + +Future showLoading({ + required Future whileFuture, + required BuildContext context, + required String message, + String? subMessage, + bool isDesktop = false, + bool opaqueBG = false, +}) async { + unawaited( + showDialog( + context: context, + barrierDismissible: false, + builder: (_) => WillPopScope( + onWillPop: () async => false, + child: Container( + color: Theme.of(context) + .extension()! + .overlay + .withOpacity(opaqueBG ? 1.0 : 0.6), + child: CustomLoadingOverlay( + message: message, + subMessage: subMessage, + eventBus: null, + ), + ), + ), + ), + ); + + final result = await whileFuture; + + if (context.mounted) { + Navigator.of(context, rootNavigator: isDesktop).pop(); + } + + return result; +} diff --git a/lib/widgets/wallet_card.dart b/lib/widgets/wallet_card.dart index 194033de3..5812a86e4 100644 --- a/lib/widgets/wallet_card.dart +++ b/lib/widgets/wallet_card.dart @@ -33,22 +33,24 @@ class WalletSheetCard extends ConsumerWidget { ), ), onPressed: () async { - final manager = ref - .read(walletsChangeNotifierProvider) - .getManager(walletId); - if (manager.coin == Coin.monero || - manager.coin == Coin.wownero) { + final manager = + ref.read(walletsChangeNotifierProvider).getManager(walletId); + if (manager.coin == Coin.monero || manager.coin == Coin.wownero) { await manager.initializeExisting(); } - if (popPrevious) Navigator.of(context).pop(); - Navigator.of(context).pushNamed( - WalletView.routeName, - arguments: Tuple2( + if (context.mounted) { + if (popPrevious && context.mounted) Navigator.of(context).pop(); + + await Navigator.of(context).pushNamed( + WalletView.routeName, + arguments: Tuple2( walletId, ref .read(walletsChangeNotifierProvider) - .getManagerProvider(walletId)), - ); + .getManagerProvider(walletId), + ), + ); + } }, child: WalletInfoRow( walletId: walletId, diff --git a/pubspec.yaml b/pubspec.yaml index 39a82d906..1ddbe37ca 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.6.5+147 +version: 1.6.7+149 environment: sdk: ">=2.17.0 <3.0.0"