diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index 3676f1192..2cf41f06a 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -45,6 +45,7 @@ import '../../../utilities/wallet_tools.dart'; import '../../../wallets/isar/providers/wallet_info_provider.dart'; import '../../../wallets/wallet/impl/banano_wallet.dart'; import '../../../wallets/wallet/impl/firo_wallet.dart'; +import '../../../wallets/wallet/wallet.dart'; import '../../../wallets/wallet/wallet_mixin_interfaces/view_only_option_interface.dart'; import '../../../widgets/custom_buttons/app_bar_icon_button.dart'; import '../../../widgets/custom_buttons/blue_text_button.dart'; @@ -55,6 +56,7 @@ import '../../../widgets/rounded_white_container.dart'; import '../../coin_control/desktop_coin_control_use_dialog.dart'; import 'sub_widgets/desktop_wallet_features.dart'; import 'sub_widgets/desktop_wallet_summary.dart'; +import 'sub_widgets/firo_desktop_wallet_summary.dart'; import 'sub_widgets/my_wallet.dart'; import 'sub_widgets/network_info_button.dart'; import 'sub_widgets/wallet_keys_button.dart'; @@ -62,11 +64,7 @@ import 'sub_widgets/wallet_options_button.dart'; /// [eventBus] should only be set during testing class DesktopWalletView extends ConsumerStatefulWidget { - const DesktopWalletView({ - super.key, - required this.walletId, - this.eventBus, - }); + const DesktopWalletView({super.key, required this.walletId, this.eventBus}); static const String routeName = "/desktopWalletView"; @@ -138,12 +136,10 @@ class _DesktopWalletViewState extends ConsumerState { eventBus = widget.eventBus != null ? widget.eventBus! : GlobalEventBus.instance; - WidgetsBinding.instance.addPostFrameCallback( - (_) { - ref.read(currentWalletIdProvider.notifier).state = wallet.walletId; - ref.read(desktopUseUTXOs.notifier).state = {}; - }, - ); + WidgetsBinding.instance.addPostFrameCallback((_) { + ref.read(currentWalletIdProvider.notifier).state = wallet.walletId; + ref.read(desktopUseUTXOs.notifier).state = {}; + }); if (!wallet.shouldAutoSync) { // // enable auto sync if it wasn't enabled when loading wallet @@ -171,9 +167,10 @@ class _DesktopWalletViewState extends ConsumerState { final monke = wallet is BananoWallet ? wallet.getMonkeyImageBytes() : null; // if the view only wallet watches a single address there are no keys of any kind - final showKeysButton = !(wallet is ViewOnlyOptionInterface && - wallet.isViewOnly && - wallet.viewOnlyType == ViewOnlyWalletType.addressOnly); + final showKeysButton = + !(wallet is ViewOnlyOptionInterface && + wallet.isViewOnly && + wallet.viewOnlyType == ViewOnlyWalletType.addressOnly); return DesktopScaffold( appBar: DesktopAppBar( @@ -181,59 +178,48 @@ class _DesktopWalletViewState extends ConsumerState { leading: Expanded( child: Row( children: [ - const SizedBox( - width: 32, - ), + const SizedBox(width: 32), AppBarIconButton( size: 32, - color: Theme.of(context) - .extension()! - .textFieldDefaultBG, + color: + Theme.of( + context, + ).extension()!.textFieldDefaultBG, shadows: const [], icon: SvgPicture.asset( Assets.svg.arrowLeft, width: 18, height: 18, - color: Theme.of(context) - .extension()! - .topNavIconPrimary, + color: + Theme.of( + context, + ).extension()!.topNavIconPrimary, ), onPressed: onBackPressed, ), - const SizedBox( - width: 15, - ), + const SizedBox(width: 15), SvgPicture.file( - File( - ref.watch(coinIconProvider(wallet.info.coin)), - ), + File(ref.watch(coinIconProvider(wallet.info.coin))), width: 32, height: 32, ), - const SizedBox( - width: 12, - ), + const SizedBox(width: 12), ConstrainedBox( - constraints: const BoxConstraints( - minWidth: 48, - ), + constraints: const BoxConstraints(minWidth: 48), child: IntrinsicWidth( - child: DesktopWalletNameField( - walletId: widget.walletId, - ), + child: DesktopWalletNameField(walletId: widget.walletId), ), ), if (ref.watch(pWalletInfo(widget.walletId)).isViewOnly) - const SizedBox( - width: 20, - ), + const SizedBox(width: 20), if (ref.watch(pWalletInfo(widget.walletId)).isViewOnly) Text( "(View only)", style: STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textFieldActiveSearchIconLeft, + color: + Theme.of(context) + .extension()! + .textFieldActiveSearchIconLeft, ), ), if (kDebugMode) const Spacer(), @@ -244,12 +230,8 @@ class _DesktopWalletViewState extends ConsumerState { children: [ Row( children: [ - const Text( - "dbgHeight: ", - ), - const SizedBox( - width: 2, - ), + const Text("dbgHeight: "), + const SizedBox(width: 2), Text( ref .watch(pWalletChainHeight(widget.walletId)) @@ -259,12 +241,8 @@ class _DesktopWalletViewState extends ConsumerState { ), Row( children: [ - const Text( - "dbgTxCount: ", - ), - const SizedBox( - width: 2, - ), + const Text("dbgTxCount: "), + const SizedBox(width: 2), Text( wallet.isarTransactionVersion == 2 ? ref @@ -290,16 +268,10 @@ class _DesktopWalletViewState extends ConsumerState { wallet is FiroWallet) Row( children: [ - const Text( - "dbgBal: ", - ), - const SizedBox( - width: 2, - ), + const Text("dbgBal: "), + const SizedBox(width: 2), Text( - WalletDevTools.checkFiroTransactionTally( - wallet, - ), + WalletDevTools.checkFiroTransactionTally(wallet), ), ], ), @@ -307,19 +279,13 @@ class _DesktopWalletViewState extends ConsumerState { wallet is FiroWallet) Row( children: [ - const Text( - "sparkCache: ", - ), - const SizedBox( - width: 2, - ), + const Text("sparkCache: "), + const SizedBox(width: 2), FutureBuilder( future: FiroCacheCoordinator.getSparkCacheSize( wallet.cryptoCurrency.network, ), - builder: (_, snapshot) => Text( - snapshot.data ?? "", - ), + builder: (_, snapshot) => Text(snapshot.data ?? ""), ), ], ), @@ -332,23 +298,12 @@ class _DesktopWalletViewState extends ConsumerState { walletId: widget.walletId, eventBus: eventBus, ), + if (showKeysButton) const SizedBox(width: 2), if (showKeysButton) - const SizedBox( - width: 2, - ), - if (showKeysButton) - WalletKeysButton( - walletId: widget.walletId, - ), - const SizedBox( - width: 2, - ), - WalletOptionsButton( - walletId: widget.walletId, - ), - const SizedBox( - width: 12, - ), + WalletKeysButton(walletId: widget.walletId), + const SizedBox(width: 2), + WalletOptionsButton(walletId: widget.walletId), + const SizedBox(width: 12), ], ), ], @@ -361,43 +316,8 @@ class _DesktopWalletViewState extends ConsumerState { padding: const EdgeInsets.all(24), child: Column( children: [ - RoundedWhiteContainer( - padding: const EdgeInsets.all(20), - child: Row( - children: [ - if (monke != null) - SvgPicture.memory( - Uint8List.fromList(monke!), - width: 60, - height: 60, - ), - if (monke == null) - SvgPicture.file( - File( - ref.watch(coinIconProvider(wallet.info.coin)), - ), - width: 40, - height: 40, - ), - const SizedBox( - width: 10, - ), - DesktopWalletSummary( - walletId: widget.walletId, - initialSyncStatus: wallet.refreshMutex.isLocked - ? WalletSyncStatus.syncing - : WalletSyncStatus.synced, - ), - const Spacer(), - DesktopWalletFeatures( - walletId: widget.walletId, - ), - ], - ), - ), - const SizedBox( - height: 24, - ), + DesktopWalletHeaderRow(wallet, monke), + const SizedBox(height: 24), Row( children: [ SizedBox( @@ -405,15 +325,14 @@ class _DesktopWalletViewState extends ConsumerState { child: Text( "My wallet", style: STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textFieldActiveSearchIconLeft, + color: + Theme.of(context) + .extension()! + .textFieldActiveSearchIconLeft, ), ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -422,25 +341,29 @@ class _DesktopWalletViewState extends ConsumerState { wallet.cryptoCurrency.hasTokenSupport ? "Tokens" : "Recent activity", - style: - STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textFieldActiveSearchIconLeft, + style: STextStyles.desktopTextExtraSmall( + context, + ).copyWith( + color: + Theme.of(context) + .extension()! + .textFieldActiveSearchIconLeft, ), ), CustomTextButton( - text: wallet.cryptoCurrency.hasTokenSupport - ? "Edit" - : "See all", + text: + wallet.cryptoCurrency.hasTokenSupport + ? "Edit" + : "See all", onTap: () async { if (wallet.cryptoCurrency.hasTokenSupport) { final result = await showDialog( context: context, - builder: (context) => EditWalletTokensView( - walletId: widget.walletId, - isDesktopPopup: true, - ), + builder: + (context) => EditWalletTokensView( + walletId: widget.walletId, + isDesktopPopup: true, + ), ); if (result == 42) { @@ -462,34 +385,23 @@ class _DesktopWalletViewState extends ConsumerState { ), ], ), - const SizedBox( - height: 14, - ), + const SizedBox(height: 14), Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: sendReceiveColumnWidth, - child: MyWallet( - walletId: widget.walletId, - ), - ), - const SizedBox( - width: 16, + child: MyWallet(walletId: widget.walletId), ), + const SizedBox(width: 16), Expanded( - child: wallet.cryptoCurrency.hasTokenSupport - ? MyTokensView( - walletId: widget.walletId, - ) - : wallet.isarTransactionVersion == 2 - ? TransactionsV2List( - walletId: widget.walletId, - ) - : TransactionsList( - walletId: widget.walletId, - ), + child: + wallet.cryptoCurrency.hasTokenSupport + ? MyTokensView(walletId: widget.walletId) + : wallet.isarTransactionVersion == 2 + ? TransactionsV2List(walletId: widget.walletId) + : TransactionsList(walletId: widget.walletId), ), ], ), @@ -500,3 +412,84 @@ class _DesktopWalletViewState extends ConsumerState { ); } } + +class DesktopWalletHeaderRow extends ConsumerWidget { + const DesktopWalletHeaderRow(this.wallet, this.monke, {super.key}); + + final Wallet wallet; + final List? monke; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return RoundedWhiteContainer( + padding: const EdgeInsets.all(20), + child: + wallet is FiroWallet && MediaQuery.of(context).size.width < 1600 + ? Column( + children: [ + Row( + children: [ + SvgPicture.file( + File(ref.watch(coinIconProvider(wallet.info.coin))), + width: 40, + height: 40, + ), + const SizedBox(width: 10), + FiroDesktopWalletSummary( + walletId: wallet.walletId, + initialSyncStatus: + wallet.refreshMutex.isLocked + ? WalletSyncStatus.syncing + : WalletSyncStatus.synced, + ), + + const Spacer(), + ], + ), + const SizedBox(height: 10), + Row( + children: [ + DesktopWalletFeatures(walletId: wallet.walletId), + ], + ), + ], + ) + : Row( + children: [ + if (monke != null) + SvgPicture.memory( + Uint8List.fromList(monke!), + width: 60, + height: 60, + ), + if (monke == null) + SvgPicture.file( + File(ref.watch(coinIconProvider(wallet.info.coin))), + width: 40, + height: 40, + ), + const SizedBox(width: 10), + if (wallet is FiroWallet) + FiroDesktopWalletSummary( + walletId: wallet.walletId, + initialSyncStatus: + wallet.refreshMutex.isLocked + ? WalletSyncStatus.syncing + : WalletSyncStatus.synced, + ), + + if (wallet is! FiroWallet) + DesktopWalletSummary( + walletId: wallet.walletId, + initialSyncStatus: + wallet.refreshMutex.isLocked + ? WalletSyncStatus.syncing + : WalletSyncStatus.synced, + ), + const Spacer(), + DesktopWalletFeatures(walletId: wallet.walletId), + ], + ), + ); + } +} diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart index 659f5710a..5f4dcf574 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_balance_toggle_button.dart @@ -17,6 +17,7 @@ import '../../../../themes/stack_colors.dart'; import '../../../../utilities/constants.dart'; import '../../../../utilities/enums/wallet_balance_toggle_state.dart'; import '../../../../utilities/text_styles.dart'; +import '../../../../wallets/isar/providers/wallet_info_provider.dart'; class DesktopBalanceToggleButton extends ConsumerWidget { const DesktopBalanceToggleButton({ @@ -74,15 +75,21 @@ class DesktopBalanceToggleButton extends ConsumerWidget { class DesktopPrivateBalanceToggleButton extends ConsumerWidget { const DesktopPrivateBalanceToggleButton({ super.key, + required this.walletId, this.onPressed, }); + final String walletId; final VoidCallback? onPressed; @override Widget build(BuildContext context, WidgetRef ref) { final currentType = ref.watch(publicPrivateBalanceStateProvider); + final showLelantus = + ref.watch(pWalletBalanceSecondary(walletId)).spendable.raw > + BigInt.zero; + return SizedBox( height: 22, width: 80, @@ -90,21 +97,31 @@ class DesktopPrivateBalanceToggleButton extends ConsumerWidget { color: Theme.of(context).extension()!.buttonBackSecondary, splashColor: Theme.of(context).extension()!.highlight, onPressed: () { - switch (currentType) { - case FiroType.public: - ref.read(publicPrivateBalanceStateProvider.state).state = - FiroType.lelantus; - break; + if (showLelantus) { + switch (currentType) { + case FiroType.public: + ref.read(publicPrivateBalanceStateProvider.state).state = + FiroType.lelantus; + break; + + case FiroType.lelantus: + ref.read(publicPrivateBalanceStateProvider.state).state = + FiroType.spark; + break; - case FiroType.lelantus: + case FiroType.spark: + ref.read(publicPrivateBalanceStateProvider.state).state = + FiroType.public; + break; + } + } else { + if (currentType != FiroType.spark) { ref.read(publicPrivateBalanceStateProvider.state).state = FiroType.spark; - break; - - case FiroType.spark: + } else { ref.read(publicPrivateBalanceStateProvider.state).state = FiroType.public; - break; + } } onPressed?.call(); }, 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 c3a9964d4..0c8b9034c 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 @@ -1107,28 +1107,30 @@ class _DesktopSendState extends ConsumerState { ], ), ), - DropdownMenuItem( - value: FiroType.lelantus, - child: Row( - children: [ - Text( - "Lelantus balance", - style: STextStyles.itemSubtitle12(context), - ), - const SizedBox( - width: 10, - ), - Text( - ref.watch(pAmountFormatter(coin)).format( - ref - .watch(pWalletBalanceSecondary(walletId)) - .spendable, - ), - style: STextStyles.itemSubtitle(context), - ), - ], + if (ref.watch(pWalletBalanceSecondary(walletId)).spendable.raw > + BigInt.zero) + DropdownMenuItem( + value: FiroType.lelantus, + child: Row( + children: [ + Text( + "Lelantus balance", + style: STextStyles.itemSubtitle12(context), + ), + const SizedBox( + width: 10, + ), + Text( + ref.watch(pAmountFormatter(coin)).format( + ref + .watch(pWalletBalanceSecondary(walletId)) + .spendable, + ), + style: STextStyles.itemSubtitle(context), + ), + ], + ), ), - ), DropdownMenuItem( value: FiroType.public, child: Row( diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart index 74512e256..78a36d8d7 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart @@ -9,7 +9,6 @@ */ import 'dart:async'; -import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -27,7 +26,6 @@ import '../../../../providers/global/paynym_api_provider.dart'; import '../../../../providers/providers.dart'; import '../../../../providers/wallet/my_paynym_account_state_provider.dart'; import '../../../../themes/stack_colors.dart'; -import '../../../../themes/theme_providers.dart'; import '../../../../utilities/amount/amount.dart'; import '../../../../utilities/assets.dart'; import '../../../../utilities/constants.dart'; @@ -57,10 +55,7 @@ import '../desktop_wallet_view.dart'; import 'more_features/more_features_dialog.dart'; class DesktopWalletFeatures extends ConsumerStatefulWidget { - const DesktopWalletFeatures({ - super.key, - required this.walletId, - }); + const DesktopWalletFeatures({super.key, required this.walletId}); final String walletId; @@ -80,6 +75,7 @@ class _DesktopWalletFeaturesState extends ConsumerState { } Future _onBuyPressed() async { + Navigator.of(context, rootNavigator: true).pop(); ref.read(currentDesktopMenuItemProvider.state).state = DesktopMenuItemId.buy; ref.read(prevDesktopMenuItemProvider.state).state = DesktopMenuItemId.buy; @@ -88,20 +84,22 @@ class _DesktopWalletFeaturesState extends ConsumerState { Future _onMorePressed() async { await showDialog( context: context, - builder: (_) => MoreFeaturesDialog( - walletId: widget.walletId, - onPaynymPressed: _onPaynymPressed, - onCoinControlPressed: _onCoinControlPressed, - onLelantusCoinsPressed: _onLelantusCoinsPressed, - onSparkCoinsPressedPressed: _onSparkCoinsPressed, - onAnonymizeAllPressed: _onAnonymizeAllPressed, - onWhirlpoolPressed: _onWhirlpoolPressed, - onOrdinalsPressed: _onOrdinalsPressed, - onMonkeyPressed: _onMonkeyPressed, - onFusionPressed: _onFusionPressed, - onChurnPressed: _onChurnPressed, - onNamesPressed: _onNamesPressed, - ), + builder: + (_) => MoreFeaturesDialog( + walletId: widget.walletId, + onPaynymPressed: _onPaynymPressed, + onBuyPressed: _onBuyPressed, + onCoinControlPressed: _onCoinControlPressed, + onLelantusCoinsPressed: _onLelantusCoinsPressed, + onSparkCoinsPressedPressed: _onSparkCoinsPressed, + // onAnonymizeAllPressed: _onAnonymizeAllPressed, + onWhirlpoolPressed: _onWhirlpoolPressed, + onOrdinalsPressed: _onOrdinalsPressed, + onMonkeyPressed: _onMonkeyPressed, + onFusionPressed: _onFusionPressed, + onChurnPressed: _onChurnPressed, + onNamesPressed: _onNamesPressed, + ), ); } @@ -112,82 +110,74 @@ class _DesktopWalletFeaturesState extends ConsumerState { void _onCoinControlPressed() { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).pushNamed( - DesktopCoinControlView.routeName, - arguments: widget.walletId, - ); + Navigator.of( + context, + ).pushNamed(DesktopCoinControlView.routeName, arguments: widget.walletId); } void _onLelantusCoinsPressed() { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).pushNamed( - LelantusCoinsView.routeName, - arguments: widget.walletId, - ); + Navigator.of( + context, + ).pushNamed(LelantusCoinsView.routeName, arguments: widget.walletId); } void _onSparkCoinsPressed() { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).pushNamed( - SparkCoinsView.routeName, - arguments: widget.walletId, - ); + Navigator.of( + context, + ).pushNamed(SparkCoinsView.routeName, arguments: widget.walletId); } Future _onAnonymizeAllPressed() async { - Navigator.of(context, rootNavigator: true).pop(); await showDialog( context: context, barrierDismissible: false, - builder: (context) => DesktopDialog( - maxWidth: 500, - maxHeight: double.infinity, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 20), - child: Column( - children: [ - Text( - "Attention!", - style: STextStyles.desktopH2(context), - ), - const SizedBox(height: 16), - Text( - "You're about to anonymize all of your public funds.", - style: STextStyles.desktopTextSmall(context), - ), - const SizedBox(height: 32), - Row( - mainAxisAlignment: MainAxisAlignment.center, + builder: + (context) => DesktopDialog( + maxWidth: 500, + maxHeight: double.infinity, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 20), + child: Column( children: [ - SecondaryButton( - width: 200, - buttonHeight: ButtonHeight.l, - label: "Cancel", - onPressed: () { - Navigator.of(context).pop(); - }, + Text("Attention!", style: STextStyles.desktopH2(context)), + const SizedBox(height: 16), + Text( + "You're about to anonymize all of your public funds.", + style: STextStyles.desktopTextSmall(context), ), - const SizedBox(width: 20), - PrimaryButton( - width: 200, - buttonHeight: ButtonHeight.l, - label: "Continue", - onPressed: () { - Navigator.of(context).pop(); - - unawaited( - _attemptAnonymize(), - ); - }, + const SizedBox(height: 32), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SecondaryButton( + width: 200, + buttonHeight: ButtonHeight.l, + label: "Cancel", + onPressed: () { + Navigator.of(context).pop(); + }, + ), + const SizedBox(width: 20), + PrimaryButton( + width: 200, + buttonHeight: ButtonHeight.l, + label: "Continue", + onPressed: () { + Navigator.of(context).pop(); + + unawaited(_attemptAnonymize()); + }, + ), + ], ), ], ), - ], + ), ), - ), - ), ); } @@ -196,13 +186,14 @@ class _DesktopWalletFeaturesState extends ConsumerState { unawaited( showDialog( context: context, - builder: (context) => WillPopScope( - child: const CustomLoadingOverlay( - message: "Anonymizing balance", - eventBus: null, - ), - onWillPop: () async => shouldPop, - ), + builder: + (context) => WillPopScope( + child: const CustomLoadingOverlay( + message: "Anonymizing balance", + eventBus: null, + ), + onWillPop: () async => shouldPop, + ), ), ); final firoWallet = @@ -213,9 +204,9 @@ class _DesktopWalletFeaturesState extends ConsumerState { shouldPop = true; if (context.mounted) { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).popUntil( - ModalRoute.withName(DesktopWalletView.routeName), - ); + Navigator.of( + context, + ).popUntil(ModalRoute.withName(DesktopWalletView.routeName)); unawaited( showFloatingFlushBar( type: FlushBarType.info, @@ -233,9 +224,9 @@ class _DesktopWalletFeaturesState extends ConsumerState { shouldPop = true; if (mounted) { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).popUntil( - ModalRoute.withName(DesktopWalletView.routeName), - ); + Navigator.of( + context, + ).popUntil(ModalRoute.withName(DesktopWalletView.routeName)); unawaited( showFloatingFlushBar( type: FlushBarType.success, @@ -248,53 +239,51 @@ class _DesktopWalletFeaturesState extends ConsumerState { shouldPop = true; if (mounted) { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).popUntil( - ModalRoute.withName(DesktopWalletView.routeName), - ); + Navigator.of( + context, + ).popUntil(ModalRoute.withName(DesktopWalletView.routeName)); await showDialog( context: context, - builder: (_) => DesktopDialog( - maxWidth: 400, - maxHeight: 300, - child: Padding( - padding: const EdgeInsets.all(24), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Anonymize all failed", - style: STextStyles.desktopH3(context), - ), - const Spacer( - flex: 1, - ), - Text( - "Reason: $e", - style: STextStyles.desktopTextSmall(context), - ), - const Spacer( - flex: 2, - ), - Row( + builder: + (_) => DesktopDialog( + maxWidth: 400, + maxHeight: 300, + child: Padding( + padding: const EdgeInsets.all(24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Spacer(), - const SizedBox( - width: 16, + Text( + "Anonymize all failed", + style: STextStyles.desktopH3(context), ), - Expanded( - child: PrimaryButton( - label: "Ok", - buttonHeight: ButtonHeight.l, - onPressed: - Navigator.of(context, rootNavigator: true).pop, - ), + const Spacer(flex: 1), + Text( + "Reason: $e", + style: STextStyles.desktopTextSmall(context), + ), + const Spacer(flex: 2), + Row( + children: [ + const Spacer(), + const SizedBox(width: 16), + Expanded( + child: PrimaryButton( + label: "Ok", + buttonHeight: ButtonHeight.l, + onPressed: + Navigator.of( + context, + rootNavigator: true, + ).pop, + ), + ), + ], ), ], ), - ], + ), ), - ), - ), ); } } @@ -307,9 +296,7 @@ class _DesktopWalletFeaturesState extends ConsumerState { showDialog( context: context, builder: (context) { - return const LoadingIndicator( - width: 100, - ); + return const LoadingIndicator(width: 100); }, ), ); @@ -328,20 +315,18 @@ class _DesktopWalletFeaturesState extends ConsumerState { // check if account exists and for matching code to see if claimed if (account.value != null && account.value!.nonSegwitPaymentCode.claimed - // && - // account.value!.segwit - ) { + // && + // account.value!.segwit + ) { ref.read(myPaynymAccountStateProvider.state).state = account.value!; - await Navigator.of(context).pushNamed( - PaynymHomeView.routeName, - arguments: widget.walletId, - ); + await Navigator.of( + context, + ).pushNamed(PaynymHomeView.routeName, arguments: widget.walletId); } else { - await Navigator.of(context).pushNamed( - PaynymClaimView.routeName, - arguments: widget.walletId, - ); + await Navigator.of( + context, + ).pushNamed(PaynymClaimView.routeName, arguments: widget.walletId); } } } @@ -349,46 +334,41 @@ class _DesktopWalletFeaturesState extends ConsumerState { Future _onMonkeyPressed() async { Navigator.of(context, rootNavigator: true).pop(); - await (Navigator.of(context).pushNamed( - MonkeyView.routeName, - arguments: widget.walletId, - )); + await (Navigator.of( + context, + ).pushNamed(MonkeyView.routeName, arguments: widget.walletId)); } void _onOrdinalsPressed() { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).pushNamed( - DesktopOrdinalsView.routeName, - arguments: widget.walletId, - ); + Navigator.of( + context, + ).pushNamed(DesktopOrdinalsView.routeName, arguments: widget.walletId); } void _onFusionPressed() { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).pushNamed( - DesktopCashFusionView.routeName, - arguments: widget.walletId, - ); + Navigator.of( + context, + ).pushNamed(DesktopCashFusionView.routeName, arguments: widget.walletId); } void _onChurnPressed() { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).pushNamed( - DesktopChurningView.routeName, - arguments: widget.walletId, - ); + Navigator.of( + context, + ).pushNamed(DesktopChurningView.routeName, arguments: widget.walletId); } void _onNamesPressed() { Navigator.of(context, rootNavigator: true).pop(); - Navigator.of(context).pushNamed( - NamecoinNamesHomeView.routeName, - arguments: widget.walletId, - ); + Navigator.of( + context, + ).pushNamed(NamecoinNamesHomeView.routeName, arguments: widget.walletId); } @override @@ -399,7 +379,8 @@ class _DesktopWalletFeaturesState extends ConsumerState { final prefs = ref.watch(prefsChangeNotifierProvider); final showExchange = prefs.enableExchange; - final showMore = wallet is PaynymInterface || + final showMore = + wallet is PaynymInterface || (wallet is CoinControlInterface && ref.watch( prefsChangeNotifierProvider.select( @@ -415,54 +396,46 @@ class _DesktopWalletFeaturesState extends ConsumerState { final isViewOnly = wallet is ViewOnlyOptionInterface && wallet.isViewOnly; return Row( + mainAxisSize: MainAxisSize.min, children: [ - if (!isViewOnly && - Constants.enableExchange && - AppConfig.hasFeature(AppFeature.swap) && - showExchange) + if (!isViewOnly && wallet.info.coin is Firo) SecondaryButton( - label: "Swap", - width: buttonWidth, + label: "Anonymize funds", + width: buttonWidth * 2, buttonHeight: ButtonHeight.l, icon: SvgPicture.asset( - Assets.svg.arrowRotate, + Assets.svg.recycle, height: 20, width: 20, - color: Theme.of(context) - .extension()! - .buttonTextSecondary, + color: + Theme.of( + context, + ).extension()!.buttonTextSecondary, ), - onPressed: () => _onSwapPressed(), + onPressed: () => _onAnonymizeAllPressed(), ), - if (Constants.enableExchange && - AppConfig.hasFeature(AppFeature.buy) && - showExchange) - const SizedBox( - width: 16, - ), - if (Constants.enableExchange && - AppConfig.hasFeature(AppFeature.buy) && + if (!isViewOnly && wallet.info.coin is Firo) const SizedBox(width: 16), + if (!isViewOnly && + Constants.enableExchange && + AppConfig.hasFeature(AppFeature.swap) && showExchange) SecondaryButton( - label: "Buy", + label: "Swap", width: buttonWidth, buttonHeight: ButtonHeight.l, - icon: SvgPicture.file( - File( - ref.watch(themeProvider.select((value) => value.assets.buy)), - ), + icon: SvgPicture.asset( + Assets.svg.arrowRotate, height: 20, width: 20, - color: Theme.of(context) - .extension()! - .buttonTextSecondary, + color: + Theme.of( + context, + ).extension()!.buttonTextSecondary, ), - onPressed: () => _onBuyPressed(), - ), - if (showMore) - const SizedBox( - width: 16, + onPressed: () => _onSwapPressed(), ), + + if (showMore) const SizedBox(width: 16), if (showMore) SecondaryButton( label: "More", @@ -472,9 +445,10 @@ class _DesktopWalletFeaturesState extends ConsumerState { Assets.svg.bars, height: 20, width: 20, - color: Theme.of(context) - .extension()! - .buttonTextSecondary, + color: + Theme.of( + context, + ).extension()!.buttonTextSecondary, ), onPressed: () => _onMorePressed(), ), diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart index c4a719510..fdc0f99b7 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart @@ -23,6 +23,8 @@ import '../../../../utilities/amount/amount_formatter.dart'; import '../../../../utilities/enums/wallet_balance_toggle_state.dart'; import '../../../../utilities/text_styles.dart'; import '../../../../wallets/crypto_currency/coins/firo.dart'; +import '../../../../wallets/crypto_currency/crypto_currency.dart' + show CryptoCurrency; import '../../../../wallets/isar/providers/eth/current_token_wallet_provider.dart'; import '../../../../wallets/isar/providers/eth/token_balance_provider.dart'; import '../../../../wallets/isar/providers/wallet_info_provider.dart'; @@ -48,10 +50,15 @@ class DesktopWalletSummary extends ConsumerStatefulWidget { class _WDesktopWalletSummaryState extends ConsumerState { late final String walletId; + late final CryptoCurrency coin; + late final bool isFiro; + @override void initState() { - walletId = widget.walletId; super.initState(); + walletId = widget.walletId; + coin = ref.read(pWalletCoin(widget.walletId)); + isFiro = coin is Firo; } @override @@ -59,36 +66,40 @@ class _WDesktopWalletSummaryState extends ConsumerState { debugPrint("BUILD: $runtimeType"); final externalCalls = ref.watch( - prefsChangeNotifierProvider.select( - (value) => value.externalCalls, - ), + prefsChangeNotifierProvider.select((value) => value.externalCalls), ); - final coin = ref.watch(pWalletCoin(widget.walletId)); - final isFiro = coin is Firo; + final locale = ref.watch( localeServiceChangeNotifierProvider.select((value) => value.locale), ); - final baseCurrency = ref - .watch(prefsChangeNotifierProvider.select((value) => value.currency)); + final baseCurrency = ref.watch( + prefsChangeNotifierProvider.select((value) => value.currency), + ); - final tokenContract = widget.isToken - ? ref.watch(pCurrentTokenWallet.select((value) => value!.tokenContract)) - : null; + final tokenContract = + widget.isToken + ? ref.watch( + pCurrentTokenWallet.select((value) => value!.tokenContract), + ) + : null; - final priceTuple = widget.isToken - ? ref.watch( - priceAnd24hChangeNotifierProvider - .select((value) => value.getTokenPrice(tokenContract!.address)), - ) - : ref.watch( - priceAnd24hChangeNotifierProvider - .select((value) => value.getPrice(coin)), - ); + final priceTuple = + widget.isToken + ? ref.watch( + priceAnd24hChangeNotifierProvider.select( + (value) => value.getTokenPrice(tokenContract!.address), + ), + ) + : ref.watch( + priceAnd24hChangeNotifierProvider.select( + (value) => value.getPrice(coin), + ), + ); final _showAvailable = ref.watch(walletBalanceToggleStateProvider.state).state == - WalletBalanceToggleState.available; + WalletBalanceToggleState.available; final Amount balanceToShow; if (isFiro) { @@ -109,13 +120,15 @@ class _WDesktopWalletSummaryState extends ConsumerState { break; } } else { - final Balance balance = widget.isToken - ? ref.watch( - pTokenBalance( - (walletId: walletId, contractAddress: tokenContract!.address), - ), - ) - : ref.watch(pWalletBalance(walletId)); + final Balance balance = + widget.isToken + ? ref.watch( + pTokenBalance(( + walletId: walletId, + contractAddress: tokenContract!.address, + )), + ) + : ref.watch(pWalletBalance(walletId)); balanceToShow = _showAvailable ? balance.spendable : balance.total; } @@ -139,45 +152,40 @@ class _WDesktopWalletSummaryState extends ConsumerState { ), if (externalCalls) SelectableText( - "${Amount.fromDecimal( - priceTuple.item1 * balanceToShow.decimal, - fractionDigits: 2, - ).fiatString( - locale: locale, - )} $baseCurrency", + "${Amount.fromDecimal(priceTuple.item1 * balanceToShow.decimal, fractionDigits: 2).fiatString(locale: locale)} $baseCurrency", style: STextStyles.desktopTextExtraSmall(context).copyWith( - color: Theme.of(context) - .extension()! - .textSubtitle1, + color: + Theme.of( + context, + ).extension()!.textSubtitle1, ), ), - if (coin is Firo) - const Row( - children: [ - DesktopPrivateBalanceToggleButton(), - SizedBox( - width: 8, - ), - DesktopBalanceToggleButton(), - ], - ) + // if (coin is Firo) + // Row( + // children: [ + // DesktopPrivateBalanceToggleButton( + // walletId: walletId, + // ), + // const SizedBox( + // width: 8, + // ), + // const DesktopBalanceToggleButton(), + // ], + // ), ], ), - const SizedBox( - width: 8, - ), + const SizedBox(width: 8), WalletRefreshButton( walletId: walletId, initialSyncStatus: widget.initialSyncStatus, - tokenContractAddress: widget.isToken - ? ref.watch(pCurrentTokenWallet)!.tokenContract.address - : null, + tokenContractAddress: + widget.isToken + ? ref.watch(pCurrentTokenWallet)!.tokenContract.address + : null, ), - if (coin is! Firo) - const SizedBox( - width: 8, - ), - if (coin is! Firo) const DesktopBalanceToggleButton(), + + const SizedBox(width: 8), + const DesktopBalanceToggleButton(), ], ); }, diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/firo_desktop_wallet_summary.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/firo_desktop_wallet_summary.dart new file mode 100644 index 000000000..73f384f82 --- /dev/null +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/firo_desktop_wallet_summary.dart @@ -0,0 +1,245 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'package:decimal/decimal.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import '../../../../pages/wallet_view/sub_widgets/wallet_refresh_button.dart'; +import '../../../../providers/providers.dart'; +import '../../../../providers/wallet/public_private_balance_state_provider.dart'; +import '../../../../providers/wallet/wallet_balance_toggle_state_provider.dart'; +import '../../../../services/event_bus/events/global/wallet_sync_status_changed_event.dart'; +import '../../../../themes/stack_colors.dart'; +import '../../../../utilities/amount/amount.dart'; +import '../../../../utilities/amount/amount_formatter.dart'; +import '../../../../utilities/assets.dart'; +import '../../../../utilities/enums/wallet_balance_toggle_state.dart'; +import '../../../../utilities/extensions/extensions.dart'; +import '../../../../utilities/text_styles.dart'; +import '../../../../wallets/crypto_currency/coins/firo.dart'; +import '../../../../wallets/isar/providers/wallet_info_provider.dart'; +import 'desktop_balance_toggle_button.dart'; + +class FiroDesktopWalletSummary extends ConsumerStatefulWidget { + const FiroDesktopWalletSummary({ + super.key, + required this.walletId, + required this.initialSyncStatus, + }); + + final String walletId; + final WalletSyncStatus initialSyncStatus; + + @override + ConsumerState createState() => + _WFiroDesktopWalletSummaryState(); +} + +class _WFiroDesktopWalletSummaryState + extends ConsumerState { + late final String walletId; + + late final Firo coin; + late final bool isFiro; + + @override + void initState() { + super.initState(); + walletId = widget.walletId; + coin = ref.read(pWalletCoin(widget.walletId)) as Firo; + } + + @override + Widget build(BuildContext context) { + debugPrint("BUILD: $runtimeType"); + + Decimal? price; + if (ref.watch( + prefsChangeNotifierProvider.select((value) => value.externalCalls), + )) { + final priceTuple = ref.watch( + priceAnd24hChangeNotifierProvider.select( + (value) => value.getPrice(coin), + ), + ); + price = priceTuple.item1; + } + + final _showAvailable = + ref.watch(walletBalanceToggleStateProvider.state).state == + WalletBalanceToggleState.available; + + final balance0 = ref.watch(pWalletBalanceTertiary(walletId)); + final balanceToShowSpark = + _showAvailable ? balance0.spendable : balance0.total; + + final balance1 = ref.watch(pWalletBalanceSecondary(walletId)); + final balanceToShowLelantus = + _showAvailable ? balance1.spendable : balance1.total; + + final balance2 = ref.watch(pWalletBalance(walletId)); + final balanceToShowPublic = + _showAvailable ? balance2.spendable : balance2.total; + + return Consumer( + builder: (context, ref, __) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Table( + columnWidths: { + 0: const IntrinsicColumnWidth(), + 1: const IntrinsicColumnWidth(), + if (price != null) 2: const IntrinsicColumnWidth(), + }, + children: [ + TableRow( + children: [ + const _Prefix(type: FiroType.spark), + _Balance(coin: coin, amount: balanceToShowSpark), + if (price != null) + _Price( + coin: coin, + amount: balanceToShowSpark, + price: price, + ), + ], + ), + if (balanceToShowLelantus.raw > BigInt.zero) + TableRow( + children: [ + const _Prefix(type: FiroType.lelantus), + _Balance(coin: coin, amount: balanceToShowLelantus), + if (price != null) + _Price( + coin: coin, + amount: balanceToShowLelantus, + price: price, + ), + ], + ), + TableRow( + children: [ + const _Prefix(type: FiroType.public), + _Balance(coin: coin, amount: balanceToShowPublic), + if (price != null) + _Price( + coin: coin, + amount: balanceToShowPublic, + price: price, + ), + ], + ), + ], + ), + + const SizedBox(width: 8), + WalletRefreshButton( + walletId: walletId, + initialSyncStatus: widget.initialSyncStatus, + ), + const SizedBox(width: 8), + const DesktopBalanceToggleButton(), + ], + ); + }, + ); + } +} + +class _Prefix extends StatelessWidget { + const _Prefix({super.key, required this.type}); + + final FiroType type; + + String get asset { + switch (type) { + case FiroType.public: + return Assets.png.glasses; + case FiroType.lelantus: + return Assets.png.glasses; + case FiroType.spark: + return Assets.svg.spark; + } + } + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox( + width: 20, + height: 20, + child: + asset.endsWith(".png") + ? Image(image: AssetImage(asset)) + : SvgPicture.asset(asset), + ), + const SizedBox(width: 6), + + SelectableText( + type.name.capitalize(), + style: STextStyles.w500_24(context), + ), + ], + ), + ); + } +} + +class _Balance extends ConsumerWidget { + const _Balance({super.key, required this.coin, required this.amount}); + + final Firo coin; + final Amount amount; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return SelectableText( + ref.watch(pAmountFormatter(coin)).format(amount, ethContract: null), + style: STextStyles.desktopH3(context), + textAlign: TextAlign.end, + ); + } +} + +class _Price extends ConsumerWidget { + const _Price({ + super.key, + required this.coin, + required this.amount, + required this.price, + }); + + final Firo coin; + final Amount amount; + final Decimal price; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Padding( + padding: const EdgeInsets.only(left: 16), + child: SelectableText( + "${Amount.fromDecimal(price * amount.decimal, fractionDigits: 2).fiatString(locale: ref.watch(localeServiceChangeNotifierProvider.select((value) => value.locale)))} " + "${ref.watch(prefsChangeNotifierProvider.select((value) => value.currency))}", + style: STextStyles.desktopTextExtraSmall(context).copyWith( + color: Theme.of(context).extension()!.textSubtitle1, + ), + + textAlign: TextAlign.end, + ), + ); + } +} diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart index ef452c09b..1ee0447b3 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart @@ -22,7 +22,9 @@ import '../../../../../providers/db/main_db_provider.dart'; import '../../../../../providers/global/prefs_provider.dart'; import '../../../../../providers/global/wallets_provider.dart'; import '../../../../../themes/stack_colors.dart'; +import '../../../../../themes/theme_providers.dart'; import '../../../../../utilities/assets.dart'; +import '../../../../../utilities/constants.dart'; import '../../../../../utilities/logger.dart'; import '../../../../../utilities/show_loading.dart'; import '../../../../../utilities/text_styles.dart'; @@ -54,10 +56,11 @@ class MoreFeaturesDialog extends ConsumerStatefulWidget { super.key, required this.walletId, required this.onPaynymPressed, + required this.onBuyPressed, required this.onCoinControlPressed, required this.onLelantusCoinsPressed, required this.onSparkCoinsPressedPressed, - required this.onAnonymizeAllPressed, + // required this.onAnonymizeAllPressed, required this.onWhirlpoolPressed, required this.onOrdinalsPressed, required this.onMonkeyPressed, @@ -68,10 +71,11 @@ class MoreFeaturesDialog extends ConsumerStatefulWidget { final String walletId; final VoidCallback? onPaynymPressed; + final VoidCallback? onBuyPressed; final VoidCallback? onCoinControlPressed; final VoidCallback? onLelantusCoinsPressed; final VoidCallback? onSparkCoinsPressedPressed; - final VoidCallback? onAnonymizeAllPressed; + // final VoidCallback? onAnonymizeAllPressed; final VoidCallback? onWhirlpoolPressed; final VoidCallback? onOrdinalsPressed; final VoidCallback? onMonkeyPressed; @@ -92,12 +96,12 @@ class _MoreFeaturesDialogState extends ConsumerState { try { // Toggle enableLelantusScanning in wallet info. - await ref.read(pWalletInfo(widget.walletId)).updateOtherData( - newEntries: { - WalletInfoKeys.enableLelantusScanning: newValue, - }, - isar: ref.read(mainDBProvider).isar, - ); + await ref + .read(pWalletInfo(widget.walletId)) + .updateOtherData( + newEntries: {WalletInfoKeys.enableLelantusScanning: newValue}, + isar: ref.read(mainDBProvider).isar, + ); if (newValue) { await _doRescanMaybe(); @@ -117,12 +121,12 @@ class _MoreFeaturesDialogState extends ConsumerState { try { // Toggle enableOptInRbf in wallet info. - await ref.read(pWalletInfo(widget.walletId)).updateOtherData( - newEntries: { - WalletInfoKeys.enableOptInRbf: newValue, - }, - isar: ref.read(mainDBProvider).isar, - ); + await ref + .read(pWalletInfo(widget.walletId)) + .updateOtherData( + newEntries: {WalletInfoKeys.enableOptInRbf: newValue}, + isar: ref.read(mainDBProvider).isar, + ); } finally { // ensure _switchRbfToggledLock is set to false no matter what _switchRbfToggledLock = false; @@ -138,17 +142,13 @@ class _MoreFeaturesDialogState extends ConsumerState { child: Column( children: [ const DesktopDialogCloseButton(), - const SizedBox( - height: 5, - ), + const SizedBox(height: 5), Text( "Rescan may be required", style: STextStyles.desktopH2(context), textAlign: TextAlign.left, ), - const SizedBox( - height: 16, - ), + const SizedBox(height: 16), const Spacer(), Text( "A blockchain rescan may be required to fully recover all lelantus history." @@ -160,11 +160,7 @@ class _MoreFeaturesDialogState extends ConsumerState { ), const Spacer(), Padding( - padding: const EdgeInsets.only( - left: 32, - right: 32, - bottom: 32, - ), + padding: const EdgeInsets.only(left: 32, right: 32, bottom: 32), child: Row( children: [ Expanded( @@ -175,9 +171,7 @@ class _MoreFeaturesDialogState extends ConsumerState { }, ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Expanded( child: PrimaryButton( label: "Later", @@ -200,9 +194,10 @@ class _MoreFeaturesDialogState extends ConsumerState { Exception? e; if (mounted) { await showLoading( - whileFuture: ref.read(pWallets).getWallet(widget.walletId).recover( - isRescan: true, - ), + whileFuture: ref + .read(pWallets) + .getWallet(widget.walletId) + .recover(isRescan: true), context: context, message: "Rescanning blockchain", subMessage: @@ -223,22 +218,26 @@ class _MoreFeaturesDialogState extends ConsumerState { context: context, useSafeArea: false, barrierDismissible: true, - builder: (context) => StackDialog( - title: "Rescan failed", - message: e.toString(), - rightButton: TextButton( - style: Theme.of(context) - .extension()! - .getSecondaryEnabledButtonStyle(context), - child: Text( - "Ok", - style: STextStyles.itemSubtitle12(context), + builder: + (context) => StackDialog( + title: "Rescan failed", + message: e.toString(), + rightButton: TextButton( + style: Theme.of(context) + .extension()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Ok", + style: STextStyles.itemSubtitle12(context), + ), + onPressed: () { + Navigator.of( + context, + rootNavigator: Util.isDesktop, + ).pop(); + }, + ), ), - onPressed: () { - Navigator.of(context, rootNavigator: Util.isDesktop).pop(); - }, - ), - ), ); } } finally { @@ -293,9 +292,7 @@ class _MoreFeaturesDialogState extends ConsumerState { "Reusing addresses reduces your privacy and security. Are you sure you want to reuse addresses by default?", style: STextStyles.desktopTextSmall(context), ), - const SizedBox( - height: 43, - ), + const SizedBox(height: 43), Row( children: [ Expanded( @@ -307,9 +304,7 @@ class _MoreFeaturesDialogState extends ConsumerState { label: "Cancel", ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Expanded( child: PrimaryButton( buttonHeight: ButtonHeight.l, @@ -343,12 +338,12 @@ class _MoreFeaturesDialogState extends ConsumerState { } Future _updateAddressReuse(bool shouldReuse) async { - await ref.read(pWalletInfo(widget.walletId)).updateOtherData( - newEntries: { - WalletInfoKeys.reuseAddress: shouldReuse, - }, - isar: ref.read(mainDBProvider).isar, - ); + await ref + .read(pWalletInfo(widget.walletId)) + .updateOtherData( + newEntries: {WalletInfoKeys.reuseAddress: shouldReuse}, + isar: ref.read(mainDBProvider).isar, + ); if (_switchController.isOn != null) { if (_switchController.isOn!.call() != shouldReuse) { @@ -366,19 +361,16 @@ class _MoreFeaturesDialogState extends ConsumerState { @override Widget build(BuildContext context) { final wallet = ref.watch( - pWallets.select( - (value) => value.getWallet(widget.walletId), - ), + pWallets.select((value) => value.getWallet(widget.walletId)), ); final coinControlPrefEnabled = ref.watch( - prefsChangeNotifierProvider.select( - (value) => value.enableCoinControl, - ), + prefsChangeNotifierProvider.select((value) => value.enableCoinControl), ); final isViewOnly = wallet is ViewOnlyOptionInterface && wallet.isViewOnly; - final isViewOnlyNoAddressGen = wallet is ViewOnlyOptionInterface && + final isViewOnlyNoAddressGen = + wallet is ViewOnlyOptionInterface && wallet.isViewOnly && wallet.viewOnlyType == ViewOnlyWalletType.addressOnly; @@ -391,9 +383,7 @@ class _MoreFeaturesDialogState extends ConsumerState { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( - padding: const EdgeInsets.only( - left: 32, - ), + padding: const EdgeInsets.only(left: 32), child: Text( "More features", style: STextStyles.desktopH3(context), @@ -402,13 +392,25 @@ class _MoreFeaturesDialogState extends ConsumerState { const DesktopDialogCloseButton(), ], ), - if (!isViewOnly && wallet.info.coin is Firo) + if (Constants.enableExchange && + AppConfig.hasFeature(AppFeature.buy) && + ref.watch(prefsChangeNotifierProvider).enableExchange) _MoreFeaturesItem( - label: "Anonymize funds", - detail: "Anonymize funds", - iconAsset: Assets.svg.recycle, - onPressed: () async => widget.onAnonymizeAllPressed?.call(), + label: "Buy", + detail: "Buy cryptocurrency", + isSvgFile: true, + iconAsset: ref.watch( + themeProvider.select((value) => value.assets.buy), + ), + onPressed: () async => widget.onBuyPressed?.call(), ), + // if (!isViewOnly && wallet.info.coin is Firo) + // _MoreFeaturesItem( + // label: "Anonymize funds", + // detail: "Anonymize funds", + // iconAsset: Assets.svg.recycle, + // onPressed: () async => widget.onAnonymizeAllPressed?.call(), + // ), // TODO: [prio=med] // if (manager.hasWhirlpoolSupport) // _MoreFeaturesItem( @@ -425,8 +427,11 @@ class _MoreFeaturesDialogState extends ConsumerState { onPressed: () async => widget.onCoinControlPressed?.call(), ), if (wallet is FiroWallet && - ref.watch(prefsChangeNotifierProvider - .select((s) => s.advancedFiroFeatures))) + ref.watch( + prefsChangeNotifierProvider.select( + (s) => s.advancedFiroFeatures, + ), + )) _MoreFeaturesItem( label: "Lelantus Coins", detail: "View wallet lelantus coins", @@ -434,8 +439,11 @@ class _MoreFeaturesDialogState extends ConsumerState { onPressed: () async => widget.onLelantusCoinsPressed?.call(), ), if (wallet is FiroWallet && - ref.watch(prefsChangeNotifierProvider - .select((s) => s.advancedFiroFeatures))) + ref.watch( + prefsChangeNotifierProvider.select( + (s) => s.advancedFiroFeatures, + ), + )) _MoreFeaturesItem( label: "Spark Coins", detail: "View wallet spark coins", @@ -497,17 +505,18 @@ class _MoreFeaturesDialogState extends ConsumerState { height: 20, width: 40, child: DraggableSwitchButton( - isOn: ref.watch( - pWalletInfo(widget.walletId) - .select((value) => value.otherData), - )[WalletInfoKeys.enableLelantusScanning] as bool? ?? + isOn: + ref.watch( + pWalletInfo( + widget.walletId, + ).select((value) => value.otherData), + )[WalletInfoKeys.enableLelantusScanning] + as bool? ?? false, onValueChanged: _switchToggled, ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -529,17 +538,18 @@ class _MoreFeaturesDialogState extends ConsumerState { height: 20, width: 40, child: DraggableSwitchButton( - isOn: ref.watch( - pWalletInfo(widget.walletId) - .select((value) => value.otherData), - )[WalletInfoKeys.enableOptInRbf] as bool? ?? + isOn: + ref.watch( + pWalletInfo( + widget.walletId, + ).select((value) => value.otherData), + )[WalletInfoKeys.enableOptInRbf] + as bool? ?? false, onValueChanged: _switchRbfToggled, ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -564,18 +574,19 @@ class _MoreFeaturesDialogState extends ConsumerState { width: 40, child: IgnorePointer( child: DraggableSwitchButton( - isOn: ref.watch( - pWalletInfo(widget.walletId) - .select((value) => value.otherData), - )[WalletInfoKeys.reuseAddress] as bool? ?? + isOn: + ref.watch( + pWalletInfo( + widget.walletId, + ).select((value) => value.otherData), + )[WalletInfoKeys.reuseAddress] + as bool? ?? false, controller: _switchController, ), ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -588,9 +599,7 @@ class _MoreFeaturesDialogState extends ConsumerState { ], ), ), - const SizedBox( - height: 28, - ), + const SizedBox(height: 28), ], ), ); @@ -603,6 +612,7 @@ class _MoreFeaturesItem extends StatefulWidget { required this.label, required this.detail, required this.iconAsset, + this.isSvgFile = false, this.onPressed, }); @@ -612,6 +622,7 @@ class _MoreFeaturesItem extends StatefulWidget { final String label; final String detail; final String iconAsset; + final bool isSvgFile; final Future Function()? onPressed; @override @@ -644,26 +655,33 @@ class _MoreFeaturesItemState extends State<_MoreFeaturesItem> { height: _MoreFeaturesItem.iconSizeBG, radiusMultiplier: _MoreFeaturesItem.iconSizeBG, child: Center( - child: SvgPicture.asset( - widget.iconAsset, - width: _MoreFeaturesItem.iconSize, - height: _MoreFeaturesItem.iconSize, - color: Theme.of(context) - .extension()! - .settingsIconIcon, - ), + child: + widget.isSvgFile + ? SvgPicture.file( + File(widget.iconAsset), + width: _MoreFeaturesItem.iconSize, + height: _MoreFeaturesItem.iconSize, + color: + Theme.of( + context, + ).extension()!.settingsIconIcon, + ) + : SvgPicture.asset( + widget.iconAsset, + width: _MoreFeaturesItem.iconSize, + height: _MoreFeaturesItem.iconSize, + color: + Theme.of( + context, + ).extension()!.settingsIconIcon, + ), ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - widget.label, - style: STextStyles.w600_20(context), - ), + Text(widget.label, style: STextStyles.w600_20(context)), Text( widget.detail, style: STextStyles.desktopTextExtraExtraSmall(context), @@ -677,11 +695,7 @@ class _MoreFeaturesItemState extends State<_MoreFeaturesItem> { } class _MoreFeaturesItemBase extends StatelessWidget { - const _MoreFeaturesItemBase({ - super.key, - required this.child, - this.onPressed, - }); + const _MoreFeaturesItemBase({super.key, required this.child, this.onPressed}); final Widget child; final VoidCallback? onPressed; @@ -689,10 +703,7 @@ class _MoreFeaturesItemBase extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.symmetric( - vertical: 6, - horizontal: 32, - ), + padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 32), child: RoundedContainer( color: Colors.transparent, borderColor: @@ -755,22 +766,18 @@ class _MoreFeaturesClearSparkCacheItemState Assets.svg.x, width: _MoreFeaturesItem.iconSize, height: _MoreFeaturesItem.iconSize, - color: Theme.of(context) - .extension()! - .settingsIconIcon, + color: + Theme.of( + context, + ).extension()!.settingsIconIcon, ), ), ), - const SizedBox( - width: 16, - ), + const SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - label, - style: STextStyles.w600_20(context), - ), + Text(label, style: STextStyles.w600_20(context)), FutureBuilder( future: FiroCacheCoordinator.getSparkCacheSize( widget.cryptoCurrency.network, diff --git a/pubspec.lock b/pubspec.lock index 21f8eb65a..b611f6f20 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -824,8 +824,8 @@ packages: dependency: "direct main" description: path: "." - ref: dd1e2a31bab034c97f8ea5745d1aa0b70c245490 - resolved-ref: dd1e2a31bab034c97f8ea5745d1aa0b70c245490 + ref: a5b90f613a7d0e77ec1089a7d95552cae4a58be6 + resolved-ref: a5b90f613a7d0e77ec1089a7d95552cae4a58be6 url: "https://github.com/cypherstack/flutter_libsparkmobile.git" source: git version: "0.0.2" @@ -2327,5 +2327,5 @@ packages: source: hosted version: "0.2.3" sdks: - dart: ">=3.7.0-0 <4.0.0" - flutter: ">=3.27.3" + dart: ">=3.7.0 <4.0.0" + flutter: ">=3.29.0" diff --git a/scripts/app_config/templates/pubspec.template b/scripts/app_config/templates/pubspec.template index fe59c1674..c52440856 100644 --- a/scripts/app_config/templates/pubspec.template +++ b/scripts/app_config/templates/pubspec.template @@ -33,7 +33,7 @@ dependencies: flutter_libsparkmobile: git: url: https://github.com/cypherstack/flutter_libsparkmobile.git - ref: dd1e2a31bab034c97f8ea5745d1aa0b70c245490 + ref: a5b90f613a7d0e77ec1089a7d95552cae4a58be6 # cs_monero compat (unpublished) compat: