move reuseAddress pref from global prefs to walletInfo

This commit is contained in:
sneurlax 2024-07-03 14:50:52 -05:00 committed by julian-CStack
parent 27536fe642
commit 8fb49ef029
6 changed files with 190 additions and 453 deletions

View file

@ -16,17 +16,11 @@ import '../../../../providers/global/prefs_provider.dart';
import '../../../../themes/stack_colors.dart';
import '../../../../utilities/constants.dart';
import '../../../../utilities/text_styles.dart';
import '../../../../utilities/util.dart';
import '../../../../widgets/background.dart';
import '../../../../widgets/choose_coin_view.dart';
import '../../../../widgets/custom_buttons/app_bar_icon_button.dart';
import '../../../../widgets/custom_buttons/draggable_switch_button.dart';
import '../../../../widgets/desktop/desktop_dialog.dart';
import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
import '../../../../widgets/desktop/primary_button.dart';
import '../../../../widgets/desktop/secondary_button.dart';
import '../../../../widgets/rounded_white_container.dart';
import '../../../../widgets/stack_dialog.dart';
import '../../../stack_privacy_calls.dart';
import 'debug_view.dart';
import 'manage_coin_units/manage_coin_units_view.dart';
@ -188,214 +182,6 @@ class AdvancedSettingsView extends StatelessWidget {
},
),
),
// reuseAddress pref.
const SizedBox(
height: 8,
),
RoundedWhiteContainer(
child: Consumer(
builder: (_, ref, __) {
final reuseAddress =
ref.watch(prefsChangeNotifierProvider.select(
(value) => value.reuseAddress,
));
return RawMaterialButton(
// splashColor: Theme.of(context).extension<StackColors>()!.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 address",
style: STextStyles.titleBold12(context),
textAlign: TextAlign.left,
),
SizedBox(
height: 20,
width: 40,
child: DraggableSwitchButton(
isOn: reuseAddress,
onValueChanged: (newValue) {
if (newValue) {
showDialog(
context: context,
builder: (context) {
final isDesktop = Util.isDesktop;
return isDesktop
? 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(
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:
() {
ref.read(prefsChangeNotifierProvider).reuseAddress =
newValue;
Navigator.of(
context)
.pop(
true);
},
label:
"Continue",
),
),
],
),
],
),
),
],
),
)
: WillPopScope(
onWillPop: () async {
return true;
},
child: 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<
StackColors>()!
.getSecondaryEnabledButtonStyle(
context),
child: Text(
"Cancel",
style: STextStyles
.itemSubtitle12(
context),
),
onPressed: () {
Navigator.of(context)
.pop(false);
},
),
rightButton: TextButton(
style: Theme.of(context)
.extension<
StackColors>()!
.getPrimaryEnabledButtonStyle(
context),
child: Text(
"Continue",
style: STextStyles.button(
context),
),
onPressed: () {
Navigator.of(context)
.pop(true);
},
),
),
);
},
).then((confirmed) {
if (confirmed == true) {
ref
.read(prefsChangeNotifierProvider)
.reuseAddress = true;
} else {
ref
.read(prefsChangeNotifierProvider)
.reuseAddress = false;
}
});
} else {
ref
.read(prefsChangeNotifierProvider)
.reuseAddress = newValue;
}
},
),
),
],
),
),
);
},
),
),
const SizedBox(
height: 8,
),

View file

@ -19,6 +19,7 @@ import '../../../../../providers/global/wallets_provider.dart';
import '../../../../../themes/stack_colors.dart';
import '../../../../../utilities/assets.dart';
import '../../../../../utilities/text_styles.dart';
import '../../../../../utilities/util.dart';
import '../../../../../wallets/crypto_currency/crypto_currency.dart';
import '../../../../../wallets/isar/models/wallet_info.dart';
import '../../../../../wallets/isar/providers/wallet_info_provider.dart';
@ -32,7 +33,10 @@ import '../../../../../wallets/wallet/wallet_mixin_interfaces/spark_interface.da
import '../../../../../widgets/custom_buttons/draggable_switch_button.dart';
import '../../../../../widgets/desktop/desktop_dialog.dart';
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({
@ -102,6 +106,147 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> {
}
}
bool _switchReuseAddressToggledLock = false; // Mutex.
Future<void> _switchReuseAddressToggled(bool newValue) async {
if (newValue) {
await showDialog(
context: context,
builder: (context) {
final isDesktop = Util.isDesktop;
return isDesktop
? 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(
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<StackColors>()!
.getSecondaryEnabledButtonStyle(context),
child: Text(
"Cancel",
style: STextStyles.itemSubtitle12(context),
),
onPressed: () {
Navigator.of(context).pop(false);
},
),
rightButton: TextButton(
style: Theme.of(context)
.extension<StackColors>()!
.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) {
final wallet = ref.watch(
@ -253,6 +398,38 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> {
],
),
),
// reuseAddress preference.
_MoreFeaturesItemBase(
child: Row(
children: [
const SizedBox(width: 3),
SizedBox(
height: 20,
width: 40,
child: DraggableSwitchButton(
isOn: ref.watch(
pWalletInfo(widget.walletId)
.select((value) => value.otherData),
)[WalletInfoKeys.reuseAddress] as bool? ??
false,
onValueChanged: _switchReuseAddressToggled,
),
),
const SizedBox(
width: 16,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Reuse addresses by default",
style: STextStyles.w600_20(context),
),
],
),
],
),
),
const SizedBox(
height: 28,
),

View file

@ -17,14 +17,9 @@ import '../../../../providers/global/prefs_provider.dart';
import '../../../../themes/stack_colors.dart';
import '../../../../utilities/assets.dart';
import '../../../../utilities/text_styles.dart';
import '../../../../utilities/util.dart';
import '../../../../widgets/custom_buttons/draggable_switch_button.dart';
import '../../../../widgets/desktop/desktop_dialog.dart';
import '../../../../widgets/desktop/desktop_dialog_close_button.dart';
import '../../../../widgets/desktop/primary_button.dart';
import '../../../../widgets/desktop/secondary_button.dart';
import '../../../../widgets/rounded_white_container.dart';
import '../../../../widgets/stack_dialog.dart';
import 'debug_info_dialog.dart';
import 'desktop_manage_block_explorers_dialog.dart';
import 'stack_privacy_dialog.dart';
@ -42,11 +37,6 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
@override
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
final reuseAddress = ref.watch(prefsChangeNotifierProvider.select(
(value) => value.reuseAddress,
));
return SingleChildScrollView(
child: Column(
children: [
@ -171,206 +161,6 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
],
),
),
// reuseAddress pref.
const Padding(
padding: EdgeInsets.all(10.0),
child: Divider(
thickness: 0.5,
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Reuse addresses",
style: STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
textAlign: TextAlign.left,
),
SizedBox(
height: 20,
width: 40,
child: DraggableSwitchButton(
isOn: reuseAddress,
onValueChanged: (newValue) {
if (newValue) {
showDialog(
context: context,
builder: (context) {
final isDesktop = Util.isDesktop;
return isDesktop
? 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(
children: [
Expanded(
child:
SecondaryButton(
buttonHeight:
ButtonHeight
.l,
onPressed:
() {
Navigator.of(
context)
.pop();
},
label:
"Cancel",
),
),
const SizedBox(
width: 16,
),
Expanded(
child:
PrimaryButton(
buttonHeight:
ButtonHeight
.l,
onPressed:
() {
ref.read(prefsChangeNotifierProvider).reuseAddress =
newValue;
Navigator.of(
context)
.pop();
},
label:
"Continue",
),
),
],
),
],
),
),
],
),
)
: WillPopScope(
onWillPop: () async {
return true;
},
child: 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<
StackColors>()!
.getSecondaryEnabledButtonStyle(
context),
child: Text(
"Cancel",
style: STextStyles
.itemSubtitle12(
context),
),
onPressed: () {
Navigator.of(context)
.pop();
},
),
rightButton: TextButton(
style: Theme.of(context)
.extension<
StackColors>()!
.getPrimaryEnabledButtonStyle(
context),
child: Text(
"Continue",
style: STextStyles.button(
context),
),
onPressed: () {
ref
.read(
prefsChangeNotifierProvider)
.reuseAddress = newValue;
Navigator.of(context)
.pop();
},
),
),
);
},
).then((confirmed) {
if (confirmed == true) {
ref
.read(prefsChangeNotifierProvider)
.reuseAddress = true;
} else {
ref
.read(prefsChangeNotifierProvider)
.reuseAddress = false;
}
});
} else {
ref
.read(
prefsChangeNotifierProvider,
)
.reuseAddress = newValue;
}
},
),
),
],
),
),
const Padding(
padding: EdgeInsets.all(10.0),
child: Divider(

View file

@ -1131,30 +1131,4 @@ class Prefs extends ChangeNotifier {
) as bool? ??
false;
}
// Reuse addresses (ie., don't generate new addresses by default).
bool _reuseAddress = false;
bool get reuseAddress => _reuseAddress;
set reuseAddress(bool reuseAddress) {
if (_reuseAddress != reuseAddress) {
DB.instance.put<dynamic>(
boxName: DB.boxNamePrefs,
key: "reuseAddress",
value: reuseAddress,
);
_reuseAddress = reuseAddress;
notifyListeners();
}
}
Future<bool> _getReuseAddress() async {
return await DB.instance.get<dynamic>(
boxName: DB.boxNamePrefs,
key: "reuseAddress",
) as bool? ??
true;
}
}

View file

@ -511,4 +511,5 @@ abstract class WalletInfoKeys {
static const String firoSparkCacheSetTimestampCache =
"firoSparkCacheSetTimestampCacheKey";
static const String enableOptInRbf = "enableOptInRbfKey";
static const String reuseAddress = "reuseAddressKey";
}

View file

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
@ -23,6 +24,7 @@ import '../../../utilities/logger.dart';
import '../../../utilities/paynym_is_api.dart';
import '../../crypto_currency/coins/firo.dart';
import '../../crypto_currency/interfaces/electrumx_currency_interface.dart';
import '../../isar/models/wallet_info.dart';
import '../../models/tx_data.dart';
import '../impl/bitcoin_wallet.dart';
import '../impl/firo_wallet.dart';
@ -1333,9 +1335,16 @@ mixin ElectrumXInterface<T extends ElectrumXCurrencyInterface>
needsGenerate = txCount > 0 || currentReceiving.derivationIndex < 0;
}
// If the reuseAddress flag is set, don't generate a new address.
if (prefs.reuseAddress) {
return;
// If reuseAddress is set, don't generate an address by default.
final WalletInfo info = mainDB.isar.walletInfo
.where()
.walletIdEqualTo(walletId)
.findFirstSync()!;
if (info.otherDataJsonString != null) {
final otherData = jsonDecode(info.otherDataJsonString!);
if (otherData[WalletInfoKeys.reuseAddress] as bool? ?? false) {
return;
}
}
if (needsGenerate) {