From efbf805056926326dde644dec3185218a02a9b38 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 5 Jul 2024 18:39:51 -0500 Subject: [PATCH 1/2] remove mobile dialog from desktop page --- .../more_features/more_features_dialog.dart | 141 +++++++----------- 1 file changed, 55 insertions(+), 86 deletions(-) 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 a474fb7bb..156b903a1 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 @@ -36,7 +36,6 @@ import '../../../../../widgets/desktop/desktop_dialog_close_button.dart'; import '../../../../../widgets/desktop/primary_button.dart'; import '../../../../../widgets/desktop/secondary_button.dart'; import '../../../../../widgets/rounded_container.dart'; -import '../../../../../widgets/stack_dialog.dart'; class MoreFeaturesDialog extends ConsumerStatefulWidget { const MoreFeaturesDialog({ @@ -113,102 +112,72 @@ class _MoreFeaturesDialogState extends ConsumerState { context: context, builder: (context) { final isDesktop = Util.isDesktop; - return isDesktop - ? DesktopDialog( - maxWidth: 576, + return DesktopDialog( + maxWidth: 576, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "Warning!", + style: STextStyles.desktopH3(context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Padding( + padding: const EdgeInsets.only( + top: 8, + left: 32, + right: 32, + bottom: 32, + ), child: Column( mainAxisSize: MainAxisSize.min, children: [ + Text( + "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, + ), Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Padding( - padding: const EdgeInsets.only(left: 32), - child: Text( - "Warning!", - style: STextStyles.desktopH3(context), + Expanded( + child: SecondaryButton( + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(false); + }, + label: "Cancel", + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(true); + }, + label: "Continue", ), ), - const DesktopDialogCloseButton(), ], ), - Padding( - padding: const EdgeInsets.only( - top: 8, - left: 32, - right: 32, - bottom: 32, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "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, - ), - Row( - children: [ - Expanded( - child: SecondaryButton( - buttonHeight: ButtonHeight.l, - onPressed: () { - Navigator.of(context).pop(false); - }, - label: "Cancel", - ), - ), - const SizedBox( - width: 16, - ), - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.l, - onPressed: () { - Navigator.of(context).pop(true); - }, - label: "Continue", - ), - ), - ], - ), - ], - ), - ), ], ), - ) - : StackDialog( - title: "Warning!", - message: - "Reusing addresses reduces your privacy and security. Are you sure you want to reuse addresses by default?", - leftButton: TextButton( - style: Theme.of(context) - .extension()! - .getSecondaryEnabledButtonStyle(context), - child: Text( - "Cancel", - style: STextStyles.itemSubtitle12(context), - ), - onPressed: () { - Navigator.of(context).pop(false); - }, - ), - rightButton: TextButton( - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonStyle(context), - child: Text( - "Continue", - style: STextStyles.button(context), - ), - onPressed: () { - Navigator.of(context).pop(true); - }, - ), - ); + ), + ], + ), + ); }, ).then((confirmed) async { if (_switchReuseAddressToggledLock) { From 25121ac9cc644cf651e7085d6bf29c2d1e5e2bbe Mon Sep 17 00:00:00 2001 From: sneurlax Date: Fri, 5 Jul 2024 18:42:15 -0500 Subject: [PATCH 2/2] add address reuse toggle to mobile settings --- .../wallet_settings_wallet_settings_view.dart | 365 ++++++++++++------ 1 file changed, 250 insertions(+), 115 deletions(-) diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart index 37040ab71..02001a277 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart @@ -11,17 +11,21 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import '../../../../providers/db/main_db_provider.dart'; import '../../../../providers/providers.dart'; import '../../../../route_generator.dart'; import '../../../../themes/stack_colors.dart'; import '../../../../utilities/constants.dart'; import '../../../../utilities/text_styles.dart'; +import '../../../../utilities/util.dart'; +import '../../../../wallets/isar/models/wallet_info.dart'; import '../../../../wallets/isar/providers/wallet_info_provider.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/rbf_interface.dart'; import '../../../../wallets/wallet/wallet_mixin_interfaces/spark_interface.dart'; import '../../../../widgets/background.dart'; import '../../../../widgets/custom_buttons/app_bar_icon_button.dart'; +import '../../../../widgets/custom_buttons/draggable_switch_button.dart'; import '../../../../widgets/rounded_white_container.dart'; import '../../../../widgets/stack_dialog.dart'; import '../../../pinpad_views/lock_screen_view.dart'; @@ -31,7 +35,7 @@ import 'rbf_settings_view.dart'; import 'rename_wallet_view.dart'; import 'spark_info.dart'; -class WalletSettingsWalletSettingsView extends ConsumerWidget { +class WalletSettingsWalletSettingsView extends ConsumerStatefulWidget { const WalletSettingsWalletSettingsView({ super.key, required this.walletId, @@ -42,7 +46,88 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { final String walletId; @override - Widget build(BuildContext context, WidgetRef ref) { + ConsumerState createState() => + _WalletSettingsWalletSettingsViewState(); +} + +class _WalletSettingsWalletSettingsViewState + extends ConsumerState { + bool _switchReuseAddressToggledLock = false; // Mutex. + Future _switchReuseAddressToggled(bool newValue) async { + if (newValue) { + await showDialog( + context: context, + builder: (context) { + final isDesktop = Util.isDesktop; + return StackDialog( + title: "Warning!", + message: + "Reusing addresses reduces your privacy and security. Are you sure you want to reuse addresses by default?", + leftButton: TextButton( + style: Theme.of(context) + .extension()! + .getSecondaryEnabledButtonStyle(context), + child: Text( + "Cancel", + style: STextStyles.itemSubtitle12(context), + ), + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + rightButton: TextButton( + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context), + child: Text( + "Continue", + style: STextStyles.button(context), + ), + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ); + }, + ).then((confirmed) async { + if (_switchReuseAddressToggledLock) { + return; + } + _switchReuseAddressToggledLock = true; // Lock mutex. + + try { + if (confirmed == true) { + await ref.read(pWalletInfo(widget.walletId)).updateOtherData( + newEntries: { + WalletInfoKeys.reuseAddress: true, + }, + isar: ref.read(mainDBProvider).isar, + ); + } else { + await ref.read(pWalletInfo(widget.walletId)).updateOtherData( + newEntries: { + WalletInfoKeys.reuseAddress: false, + }, + isar: ref.read(mainDBProvider).isar, + ); + } + } finally { + // ensure _switchReuseAddressToggledLock is set to false no matter what. + _switchReuseAddressToggledLock = false; + } + }); + } else { + await ref.read(pWalletInfo(widget.walletId)).updateOtherData( + newEntries: { + WalletInfoKeys.reuseAddress: false, + }, + isar: ref.read(mainDBProvider).isar, + ); + } + } + + @override + Widget build(BuildContext context) { return Background( child: Scaffold( backgroundColor: Theme.of(context).extension()!.background, @@ -80,7 +165,7 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { onPressed: () { Navigator.of(context).pushNamed( RenameWalletView.routeName, - arguments: walletId, + arguments: widget.walletId, ); }, child: Padding( @@ -102,6 +187,166 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { const SizedBox( height: 8, ), + if (ref.watch(pWallets).getWallet(widget.walletId) + is RbfInterface) + RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onPressed: () { + Navigator.of(context).pushNamed( + RbfSettingsView.routeName, + arguments: widget.walletId, + ); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 20, + ), + child: Row( + children: [ + Text( + "RBF settings", + style: STextStyles.titleBold12(context), + ), + ], + ), + ), + ), + ), + const SizedBox( + height: 8, + ), + RoundedWhiteContainer( + child: Consumer( + builder: (_, ref, __) { + return RawMaterialButton( + // splashColor: Theme.of(context).extension()!.highlight, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + onPressed: null, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Reuse receiving address by default", + style: STextStyles.titleBold12(context), + textAlign: TextAlign.left, + ), + SizedBox( + height: 20, + width: 40, + child: DraggableSwitchButton( + isOn: ref.watch( + pWalletInfo(widget.walletId) + .select((value) => value.otherData), + )[WalletInfoKeys.reuseAddress] as bool? ?? + false, + onValueChanged: (newValue) { + _switchReuseAddressToggled(newValue); + }, + ), + ), + ], + ), + ), + ); + }, + ), + ), + if (ref.watch(pWallets).getWallet(widget.walletId) + is LelantusInterface) + const SizedBox( + height: 8, + ), + if (ref.watch(pWallets).getWallet(widget.walletId) + is LelantusInterface) + RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onPressed: () { + Navigator.of(context).pushNamed( + LelantusSettingsView.routeName, + arguments: widget.walletId, + ); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 20, + ), + child: Row( + children: [ + Text( + "Lelantus settings", + style: STextStyles.titleBold12(context), + ), + ], + ), + ), + ), + ), + if (ref.watch(pWallets).getWallet(widget.walletId) + is SparkInterface) + const SizedBox( + height: 8, + ), + if (ref.watch(pWallets).getWallet(widget.walletId) + is SparkInterface) + RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + onPressed: () { + Navigator.of(context).pushNamed( + SparkInfoView.routeName, + arguments: widget.walletId, + ); + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12.0, + vertical: 20, + ), + child: Row( + children: [ + Text( + "Spark info", + style: STextStyles.titleBold12(context), + ), + ], + ), + ), + ), + ), + if (ref.watch(pWallets).getWallet(widget.walletId) + is RbfInterface) + const SizedBox( + height: 8, + ), RoundedWhiteContainer( padding: const EdgeInsets.all(0), child: RawMaterialButton( @@ -119,7 +364,7 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { context: context, builder: (_) => StackDialog( title: - "Do you want to delete ${ref.read(pWalletName(walletId))}?", + "Do you want to delete ${ref.read(pWalletName(widget.walletId))}?", leftButton: TextButton( style: Theme.of(context) .extension()! @@ -148,7 +393,7 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute, builder: (_) => LockscreenView( - routeOnSuccessArguments: walletId, + routeOnSuccessArguments: widget.walletId, showBackButton: true, routeOnSuccess: DeleteWalletWarningView.routeName, @@ -188,116 +433,6 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { ), ), ), - if (ref.watch(pWallets).getWallet(walletId) - is LelantusInterface) - const SizedBox( - height: 8, - ), - if (ref.watch(pWallets).getWallet(walletId) - is LelantusInterface) - RoundedWhiteContainer( - padding: const EdgeInsets.all(0), - child: RawMaterialButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - ), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onPressed: () { - Navigator.of(context).pushNamed( - LelantusSettingsView.routeName, - arguments: walletId, - ); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 20, - ), - child: Row( - children: [ - Text( - "Lelantus settings", - style: STextStyles.titleBold12(context), - ), - ], - ), - ), - ), - ), - if (ref.watch(pWallets).getWallet(walletId) is SparkInterface) - const SizedBox( - height: 8, - ), - if (ref.watch(pWallets).getWallet(walletId) is SparkInterface) - RoundedWhiteContainer( - padding: const EdgeInsets.all(0), - child: RawMaterialButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - ), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onPressed: () { - Navigator.of(context).pushNamed( - SparkInfoView.routeName, - arguments: walletId, - ); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 20, - ), - child: Row( - children: [ - Text( - "Spark info", - style: STextStyles.titleBold12(context), - ), - ], - ), - ), - ), - ), - if (ref.watch(pWallets).getWallet(walletId) is RbfInterface) - const SizedBox( - height: 8, - ), - if (ref.watch(pWallets).getWallet(walletId) is RbfInterface) - RoundedWhiteContainer( - padding: const EdgeInsets.all(0), - child: RawMaterialButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - ), - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onPressed: () { - Navigator.of(context).pushNamed( - RbfSettingsView.routeName, - arguments: walletId, - ); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12.0, - vertical: 20, - ), - child: Row( - children: [ - Text( - "RBF settings", - style: STextStyles.titleBold12(context), - ), - ], - ), - ), - ), - ), ], ), ),