feat: add toggle supported handles

This commit is contained in:
Serhii 2025-06-23 14:07:23 +03:00
parent 8dc3bb649d
commit a298a28f56
12 changed files with 305 additions and 97 deletions

View file

@ -38,6 +38,7 @@ import 'package:cake_wallet/src/screens/address_book/edit_contact_page.dart';
import 'package:cake_wallet/src/screens/address_book/edit_new_contact_group_page.dart'; import 'package:cake_wallet/src/screens/address_book/edit_new_contact_group_page.dart';
import 'package:cake_wallet/src/screens/address_book/edit_new_contact_page.dart'; import 'package:cake_wallet/src/screens/address_book/edit_new_contact_page.dart';
import 'package:cake_wallet/src/screens/address_book/entities/address_edit_request.dart'; import 'package:cake_wallet/src/screens/address_book/entities/address_edit_request.dart';
import 'package:cake_wallet/src/screens/address_book/supported_handles_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart'; import 'package:cake_wallet/src/screens/dev/monero_background_sync.dart';
import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart'; import 'package:cake_wallet/src/screens/dev/moneroc_call_profiler.dart';
@ -978,7 +979,7 @@ Future<void> setup({
AnimatedURPage(getIt.get<AnimatedURModel>(), urQr: urQr)); AnimatedURPage(getIt.get<AnimatedURModel>(), urQr: urQr));
getIt.registerFactoryParam<ContactViewModel, AddressEditRequest?, void>( getIt.registerFactoryParam<ContactViewModel, AddressEditRequest?, void>(
(req, _) => ContactViewModel(_contactSource,getIt<AppStore>().wallet!, request: req), (req, _) => ContactViewModel(_contactSource,getIt<AppStore>().wallet!,getIt<SettingsStore>(), request: req,),
); );
getIt.registerFactoryParam<ContactListViewModel, CryptoCurrency?, void>( getIt.registerFactoryParam<ContactListViewModel, CryptoCurrency?, void>(
@ -1012,6 +1013,9 @@ Future<void> setup({
), ),
); );
getIt.registerFactory<SupportedHandlesPage>(
() => SupportedHandlesPage(contactViewModel: getIt<ContactViewModel>()),
);
getIt.registerFactoryParam<EditContactGroupPage, ContactViewModel, void>( getIt.registerFactoryParam<EditContactGroupPage, ContactViewModel, void>(
(vm, _) => EditContactGroupPage(contactViewModel: vm), (vm, _) => EditContactGroupPage(contactViewModel: vm),

View file

@ -200,8 +200,7 @@ class AddressResolverService {
LookupEntry( LookupEntry(
source: AddressSource.fio, source: AddressSource.fio,
currencies: AddressSource.fio.supportedCurrencies, currencies: AddressSource.fio.supportedCurrencies,
applies: (q) => !q.startsWith('@') && q.contains('@') && !q.contains('.'), applies: (q) => settingsStore.lookupsFio && !q.startsWith('@') && q.contains('@') && !q.contains('.'),
// TODO: Add condition for FIO lookups
// FIO handle example: username@domain // FIO handle example: username@domain
run: _lookupFio, run: _lookupFio,
), ),
@ -215,8 +214,7 @@ class AddressResolverService {
LookupEntry( LookupEntry(
source: AddressSource.thorChain, source: AddressSource.thorChain,
currencies: AddressSource.thorChain.supportedCurrencies, currencies: AddressSource.thorChain.supportedCurrencies,
applies: (q) => true, applies: (q) => settingsStore.lookupsThorChain && q.isNotEmpty,
// ThorChain handles can be any string //TODO: Add condition for ThorChain lookups
run: _lookupThorChain, run: _lookupThorChain,
), ),
LookupEntry( LookupEntry(
@ -238,7 +236,7 @@ class AddressResolverService {
LookupEntry( LookupEntry(
source: AddressSource.bip353, source: AddressSource.bip353,
currencies: AddressSource.bip353.supportedCurrencies, currencies: AddressSource.bip353.supportedCurrencies,
applies: (q) => true, //TODO: Add condition for BIP-353 lookups applies: (q) => settingsStore.lookupsBip353,
run: _lookupsBip353, run: _lookupsBip353,
), ),
LookupEntry( LookupEntry(
@ -262,8 +260,8 @@ class AddressResolverService {
LookupEntry( LookupEntry(
source: AddressSource.nostr, source: AddressSource.nostr,
currencies: [CryptoCurrency.btc], currencies: [CryptoCurrency.btc],
applies: (q) => isEmailFormat(q), applies: (q) => settingsStore.lookupsNostr && isEmailFormat(q),
// Nostr handle example: name@domain //TODO: Add condition for Nostr lookups // Nostr handle example: name@domain
run: _lookupsNostr, run: _lookupsNostr,
), ),
]; ];

View file

@ -84,6 +84,10 @@ class PreferencesKey {
static const lookupsOpenAlias = 'looks_up_open_alias'; static const lookupsOpenAlias = 'looks_up_open_alias';
static const lookupsENS = 'looks_up_ens'; static const lookupsENS = 'looks_up_ens';
static const lookupsWellKnown = 'looks_up_well_known'; static const lookupsWellKnown = 'looks_up_well_known';
static const lookupsFio = 'looks_up_fio';
static const lookupsNostr = 'looks_up_nostr';
static const lookupsThorChain = 'looks_up_thor_chain';
static const lookupsBip353 = 'looks_up_bip353';
static const usePayjoin = 'use_payjoin'; static const usePayjoin = 'use_payjoin';
static const showPayjoinCard = 'show_payjoin_card'; static const showPayjoinCard = 'show_payjoin_card';
static const showCameraConsent = 'show_camera_consent'; static const showCameraConsent = 'show_camera_consent';

View file

@ -2,21 +2,39 @@ import 'package:cake_wallet/entities/parsed_address.dart';
import 'package:cake_wallet/src/screens/address_book/widgets/handles_list_widget.dart'; import 'package:cake_wallet/src/screens/address_book/widgets/handles_list_widget.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/themes/utils/custom_theme_colors.dart'; import 'package:cake_wallet/themes/utils/custom_theme_colors.dart';
import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SupportedHandlesPage extends BasePage { class SupportedHandlesPage extends BasePage {
SupportedHandlesPage(); SupportedHandlesPage({required this.contactViewModel});
final ContactViewModel contactViewModel;
@override @override
String? get title => 'Supported Handles'; String? get title => 'Supported Handles';
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
final fillColor = currentTheme.isDark final fill = currentTheme.isDark
? CustomThemeColors.backgroundGradientColorDark ? CustomThemeColors.backgroundGradientColorDark
: CustomThemeColors.backgroundGradientColorLight; : CustomThemeColors.backgroundGradientColorLight;
return HandlesListWidget(items: supportedSources, fillColor: fillColor); final selectedInit = <AddressSource>[
for (final src in supportedSources)
if (contactViewModel.lookupMap[src.label]!.$1()) src
];
return HandlesListWidget(
items: supportedSources,
fillColor: fill,
initiallySelected: selectedInit,
onSelectionChanged: (sel) {
for (final src in supportedSources) {
final pair = contactViewModel.lookupMap[src.label]!;
pair.$2(sel.contains(src));
}
},
);
} }
} }

View file

@ -1,46 +1,85 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/parsed_address.dart';
import 'package:cake_wallet/utils/image_utill.dart'; import 'package:cake_wallet/utils/image_utill.dart';
import 'package:flutter/material.dart';
class HandlesListWidget extends StatelessWidget { class HandlesListWidget extends StatefulWidget {
const HandlesListWidget({ const HandlesListWidget(
super.key, {super.key,
required this.items, required this.items,
required this.fillColor, required this.fillColor,
}); this.initiallySelected = const [],
this.onSelectionChanged});
final List<AddressSource> items; final List<AddressSource> items;
final Color fillColor; final Color fillColor;
final List<AddressSource> initiallySelected;
final ValueChanged<Set<AddressSource>>? onSelectionChanged;
@override
State<HandlesListWidget> createState() => _HandlesListWidgetState();
}
class _HandlesListWidgetState extends State<HandlesListWidget> {
late final Set<AddressSource> _selected = widget.initiallySelected.toSet();
void _toggle(AddressSource src) {
setState(() {
if (_selected.contains(src)) {
_selected.remove(src);
} else {
_selected.add(src);
}
});
widget.onSelectionChanged?.call(_selected);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context);
final iconColor = theme.colorScheme.primary;
return ListView.separated( return ListView.separated(
shrinkWrap: true, shrinkWrap: true,
primary: false, primary: false,
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
itemCount: items.length, itemCount: widget.items.length,
separatorBuilder: (context, index) => const SizedBox(height: 6), separatorBuilder: (_, __) => const SizedBox(height: 6),
itemBuilder: (context, index) { itemBuilder: (ctx, i) {
final src = items[index]; final src = widget.items[i];
final isSelected = _selected.contains(src);
return ListTile( return ListTile(
title: Text(src.label, style: Theme title: Text(src.label, style: theme.textTheme.bodyMedium),
.of(context) trailing: Text(src.alias, style: theme.textTheme.bodyMedium),
.textTheme tileColor: widget.fillColor,
.bodyMedium), splashColor: Colors.transparent,
trailing: Text(src.alias, style: Theme
.of(context)
.textTheme
.bodyMedium),
tileColor: fillColor,
dense: true, dense: true,
visualDensity: VisualDensity(horizontal: 0, vertical: -3), visualDensity: const VisualDensity(horizontal: 0, vertical: -3),
contentPadding: EdgeInsets.symmetric(horizontal: 12), contentPadding: const EdgeInsets.symmetric(horizontal: 12),
leading: ImageUtil.getImageFromPath(imagePath: src.iconPath, height: 24, width: 24), leading: Row(
shape: RoundedRectangleBorder( mainAxisSize: MainAxisSize.min,
borderRadius: const BorderRadius.all(Radius.circular(12)), children: [
SizedBox(
width: 24,
height: 24,
child: isSelected
? Icon(Icons.check_circle, size: 20, color: iconColor)
: Icon(Icons.circle_outlined, size: 20, color: iconColor),
),
const SizedBox(width: 6),
ImageUtil.getImageFromPath(
imagePath: src.iconPath,
height: 24,
width: 24,
),
],
), ),
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))),
onTap: () => _toggle(src),
); );
}, },
); );
} }
} }

View file

@ -325,33 +325,29 @@ class _ContactListBodyState extends State<ContactListBody> {
shrinkWrap: true, shrinkWrap: true,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final contact = contacts[index]; final contact = contacts[index];
return Padding( return ContactAddressesExpansionTile(
key: ValueKey(contact.key), key: Key(contact.key.toString()),
padding: const EdgeInsets.only(bottom: 8), contentPadding: EdgeInsets.symmetric(horizontal: 8),
child: ContactAddressesExpansionTile( manualByCurrency: contact.manual,
key: Key(contact.key.toString()), fillColor: Theme.of(context).colorScheme.surfaceContainer,
contentPadding: EdgeInsets.symmetric(horizontal: 8), title: _buildContactTitle(
manualByCurrency: contact.manual, context: context,
fillColor: Theme.of(context).colorScheme.surfaceContainer, contact: contact,
title: _buildContactTitle( contactListViewModel: widget.contactListViewModel),
context: context, onEditPressed: (cur, lbl) async {
await _showAddressBookBottomSheet(
context: context,
contactListViewModel: widget.contactListViewModel,
initialRoute: Routes.editAddressPage,
initialArgs: AddressEditRequest.address(
contact: contact, contact: contact,
contactListViewModel: widget.contactListViewModel), currency: cur,
onEditPressed: (cur, lbl) async { label: lbl,
await _showAddressBookBottomSheet( kindIsManual: true,
context: context, ),
contactListViewModel: widget.contactListViewModel, );
initialRoute: Routes.editAddressPage, },
initialArgs: AddressEditRequest.address( onCopyPressed: (addr) => Clipboard.setData(ClipboardData(text: addr)),
contact: contact,
currency: cur,
label: lbl,
kindIsManual: true,
),
);
},
onCopyPressed: (addr) => Clipboard.setData(ClipboardData(text: addr)),
),
); );
}, },
), ),

View file

@ -53,8 +53,22 @@ class DomainLookupsPage extends BasePage {
title: 'Zano Aliases', title: 'Zano Aliases',
value: _privacySettingsViewModel.lookupsZanoAlias, value: _privacySettingsViewModel.lookupsZanoAlias,
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsZanoAlias(value)), onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsZanoAlias(value)),
SettingsSwitcherCell(
//if (!isHaven) it does not work correctly title: 'FIO',
value: _privacySettingsViewModel.lookupsFio,
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsFio(value)),
SettingsSwitcherCell(
title: 'Nostr',
value: _privacySettingsViewModel.lookupsNostr,
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsNostr(value)),
SettingsSwitcherCell(
title: 'ThorChain',
value: _privacySettingsViewModel.lookupsThorChain,
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsThorChain(value)),
SettingsSwitcherCell(
title: 'BIP-353',
value: _privacySettingsViewModel.lookupsBip353,
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsBip353(value)),
], ],
), ),
); );

View file

@ -10,6 +10,7 @@ class FilteredList extends StatefulWidget {
this.canReorder = true, this.canReorder = true,
this.shrinkWrap = false, this.shrinkWrap = false,
this.physics, this.physics,
this.itemPadding = const EdgeInsets.symmetric(vertical: 4),
}); });
final ObservableList<dynamic> list; final ObservableList<dynamic> list;
@ -18,39 +19,51 @@ class FilteredList extends StatefulWidget {
final bool canReorder; final bool canReorder;
final bool shrinkWrap; final bool shrinkWrap;
final ScrollPhysics? physics; final ScrollPhysics? physics;
final EdgeInsets itemPadding;
@override @override
FilteredListState createState() => FilteredListState(); FilteredListState createState() => FilteredListState();
} }
class FilteredListState extends State<FilteredList> { class FilteredListState extends State<FilteredList> {
Widget _buildPaddedItem(BuildContext ctx, int index) {
return Padding(
key: ValueKey(widget.list[index]),
padding: widget.itemPadding,
child: widget.itemBuilder(ctx, index),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.canReorder) { if (!widget.canReorder) {
return Observer(
builder: (_) => ReorderableListView.builder(
shrinkWrap: widget.shrinkWrap,
physics: widget.physics ?? const BouncingScrollPhysics(),
itemBuilder: widget.itemBuilder,
itemCount: widget.list.length,
onReorder: (int oldIndex, int newIndex) {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final dynamic item = widget.list.removeAt(oldIndex);
widget.list.insert(newIndex, item);
widget.updateFunction();
},
),
);
} else {
return Observer( return Observer(
builder: (_) => ListView.builder( builder: (_) => ListView.builder(
shrinkWrap: widget.shrinkWrap,
physics: widget.physics ?? const BouncingScrollPhysics(), physics: widget.physics ?? const BouncingScrollPhysics(),
itemBuilder: widget.itemBuilder,
itemCount: widget.list.length, itemCount: widget.list.length,
itemBuilder: _buildPaddedItem,
), ),
); );
} }
return Observer(
builder: (_) => ReorderableListView.builder(
shrinkWrap: widget.shrinkWrap,
physics: widget.physics ?? const BouncingScrollPhysics(),
itemCount: widget.list.length,
itemBuilder: _buildPaddedItem,
onReorder: (oldIndex, newIndex) {
if (oldIndex < newIndex) newIndex -= 1;
final item = widget.list.removeAt(oldIndex);
widget.list.insert(newIndex, item);
widget.updateFunction();
},
proxyDecorator: (child, _, __) => Material(
color: Colors.transparent,
child: child,
),
),
);
} }
} }

View file

@ -13,10 +13,10 @@ import 'package:cake_wallet/src/screens/address_book/edit_new_contact_page.dart'
import 'package:cake_wallet/src/screens/address_book/entities/address_edit_request.dart'; import 'package:cake_wallet/src/screens/address_book/entities/address_edit_request.dart';
import 'package:cake_wallet/src/screens/address_book/supported_handles_page.dart'; import 'package:cake_wallet/src/screens/address_book/supported_handles_page.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart'; import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AddressBookBottomSheet extends StatelessWidget { class AddressBookBottomSheet extends StatelessWidget {
const AddressBookBottomSheet({ const AddressBookBottomSheet({
super.key, super.key,
@ -29,10 +29,8 @@ class AddressBookBottomSheet extends StatelessWidget {
final String? initialRoute; final String? initialRoute;
final Object? initialArgs; final Object? initialArgs;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ClipRRect( return ClipRRect(
borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), borderRadius: const BorderRadius.vertical(top: Radius.circular(20)),
child: Material( child: Material(
@ -47,8 +45,8 @@ class AddressBookBottomSheet extends StatelessWidget {
), ),
child: _AddContactNavigator( child: _AddContactNavigator(
onHandlerSearch: onHandlerSearch, onHandlerSearch: onHandlerSearch,
initialRoute : initialRoute ?? Navigator.defaultRouteName, initialRoute: initialRoute ?? Navigator.defaultRouteName,
initialArgs : initialArgs, initialArgs: initialArgs,
), ),
), ),
], ],
@ -57,6 +55,7 @@ class AddressBookBottomSheet extends StatelessWidget {
); );
} }
} }
Widget _buildDragHandle(BuildContext context) { Widget _buildDragHandle(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 16), padding: const EdgeInsets.only(top: 16),
@ -106,20 +105,19 @@ class _AddContactNavigator extends StatelessWidget {
Route<dynamic> _routeFor(String name, Object? args) { Route<dynamic> _routeFor(String name, Object? args) {
late final Widget page; late final Widget page;
switch (name) { switch (name) {
case Routes.supportedHandlesPage: case Routes.supportedHandlesPage:
page = SupportedHandlesPage(); page = getIt<SupportedHandlesPage>();
break; break;
case Routes.newContactWelcomePage: case Routes.newContactWelcomePage:
final list = args as List<dynamic>; final list = args as List<dynamic>;
final onSearch = list[0] as Future<List<ParsedAddress>> Function(String); final onSearch = list[0] as Future<List<ParsedAddress>> Function(String);
final handleOnly = list.length > 1 && list[1] == true; final handleOnly = list.length > 1 && list[1] == true;
final contact = list.length > 2 ? list[2] as ContactRecord? : null; final contact = list.length > 2 ? list[2] as ContactRecord? : null;
page = NewContactWelcomePage( page = NewContactWelcomePage(
onSearch : onSearch, onSearch: onSearch,
handleOnly : handleOnly, handleOnly: handleOnly,
existingContact: contact, existingContact: contact,
); );
break; break;

View file

@ -117,6 +117,10 @@ abstract class SettingsStoreBase with Store {
required this.lookupsOpenAlias, required this.lookupsOpenAlias,
required this.lookupsENS, required this.lookupsENS,
required this.lookupsWellKnown, required this.lookupsWellKnown,
required this.lookupsFio,
required this.lookupsNostr,
required this.lookupsThorChain,
required this.lookupsBip353,
required this.usePayjoin, required this.usePayjoin,
required this.showPayjoinCard, required this.showPayjoinCard,
required this.customBitcoinFeeRate, required this.customBitcoinFeeRate,
@ -481,6 +485,26 @@ abstract class SettingsStoreBase with Store {
(bool looksUpWellKnown) => (bool looksUpWellKnown) =>
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown)); _sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));
reaction(
(_) => lookupsFio,
(bool looksUpWellKnown) =>
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));
reaction(
(_) => lookupsNostr,
(bool looksUpWellKnown) =>
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));
reaction(
(_) => lookupsThorChain,
(bool looksUpWellKnown) =>
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));
reaction(
(_) => lookupsBip353,
(bool looksUpWellKnown) =>
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));
reaction( reaction(
(_) => usePayjoin, (_) => usePayjoin,
(bool usePayjoin) => (bool usePayjoin) =>
@ -809,6 +833,18 @@ abstract class SettingsStoreBase with Store {
@observable @observable
bool lookupsWellKnown; bool lookupsWellKnown;
@observable
bool lookupsFio;
@observable
bool lookupsNostr;
@observable
bool lookupsThorChain;
@observable
bool lookupsBip353;
@observable @observable
bool usePayjoin; bool usePayjoin;
@ -1012,6 +1048,10 @@ abstract class SettingsStoreBase with Store {
final lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true; final lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true;
final lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true; final lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true;
final lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true; final lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true;
final lookupsFio = sharedPreferences.getBool(PreferencesKey.lookupsFio) ?? true;
final lookupsNostr = sharedPreferences.getBool(PreferencesKey.lookupsNostr) ?? true;
final lookupsThorChain = sharedPreferences.getBool(PreferencesKey.lookupsThorChain) ?? true;
final lookupsBip353 = sharedPreferences.getBool(PreferencesKey.lookupsBip353) ?? true;
final usePayjoin = sharedPreferences.getBool(PreferencesKey.usePayjoin) ?? false; final usePayjoin = sharedPreferences.getBool(PreferencesKey.usePayjoin) ?? false;
final showPayjoinCard = sharedPreferences.getBool(PreferencesKey.showPayjoinCard) ?? true; final showPayjoinCard = sharedPreferences.getBool(PreferencesKey.showPayjoinCard) ?? true;
final customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1; final customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
@ -1316,6 +1356,10 @@ abstract class SettingsStoreBase with Store {
lookupsOpenAlias: lookupsOpenAlias, lookupsOpenAlias: lookupsOpenAlias,
lookupsENS: lookupsENS, lookupsENS: lookupsENS,
lookupsWellKnown: lookupsWellKnown, lookupsWellKnown: lookupsWellKnown,
lookupsFio: lookupsFio,
lookupsNostr: lookupsNostr,
lookupsThorChain: lookupsThorChain,
lookupsBip353: lookupsBip353,
usePayjoin: usePayjoin, usePayjoin: usePayjoin,
showPayjoinCard: showPayjoinCard, showPayjoinCard: showPayjoinCard,
customBitcoinFeeRate: customBitcoinFeeRate, customBitcoinFeeRate: customBitcoinFeeRate,

View file

@ -6,6 +6,7 @@ import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/parsed_address.dart';
import 'package:cake_wallet/src/screens/address_book/entities/address_edit_request.dart'; import 'package:cake_wallet/src/screens/address_book/entities/address_edit_request.dart';
import 'package:cake_wallet/src/screens/address_book/entities/user_handles.dart'; import 'package:cake_wallet/src/screens/address_book/entities/user_handles.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -25,7 +26,8 @@ class ContactViewModel = _ContactViewModel with _$ContactViewModel;
abstract class _ContactViewModel with Store { abstract class _ContactViewModel with Store {
_ContactViewModel( _ContactViewModel(
this.box, this.box,
this.wallet, { this.wallet,
this.settingsStore, {
AddressEditRequest? request, AddressEditRequest? request,
}) : mode = request?.mode == EditMode.manualAddressAdd || }) : mode = request?.mode == EditMode.manualAddressAdd ||
request?.mode == EditMode.manualAddressEdit request?.mode == EditMode.manualAddressEdit
@ -64,6 +66,7 @@ abstract class _ContactViewModel with Store {
final Box<Contact> box; final Box<Contact> box;
final WalletBase wallet; final WalletBase wallet;
final SettingsStore? settingsStore;
ContactRecord? record; ContactRecord? record;
@observable @observable
@ -269,4 +272,57 @@ abstract class _ContactViewModel with Store {
_originalAddress = address.trim(); _originalAddress = address.trim();
_originalHandleKey = blockKey ?? _defaultHandleKey(); _originalHandleKey = blockKey ?? _defaultHandleKey();
} }
late final Map<String, (bool Function(), void Function(bool))> lookupMap = settingsStore != null
? {
AddressSource.twitter.label: (
() => settingsStore!.lookupsTwitter,
(v) => settingsStore!.lookupsTwitter = v
),
AddressSource.zanoAlias.label: (
() => settingsStore!.lookupsZanoAlias,
(v) => settingsStore!.lookupsZanoAlias = v
),
AddressSource.mastodon.label: (
() => settingsStore!.lookupsMastodon,
(v) => settingsStore!.lookupsMastodon = v
),
AddressSource.yatRecord.label: (
() => settingsStore!.lookupsYatService,
(v) => settingsStore!.lookupsYatService = v
),
AddressSource.unstoppableDomains.label: (
() => settingsStore!.lookupsUnstoppableDomains,
(v) => settingsStore!.lookupsUnstoppableDomains = v
),
AddressSource.openAlias.label: (
() => settingsStore!.lookupsOpenAlias,
(v) => settingsStore!.lookupsOpenAlias = v
),
AddressSource.ens.label: (
() => settingsStore!.lookupsENS,
(v) => settingsStore!.lookupsENS = v
),
AddressSource.wellKnown.label: (
() => settingsStore!.lookupsWellKnown,
(v) => settingsStore!.lookupsWellKnown = v
),
AddressSource.fio.label: (
() => settingsStore!.lookupsFio,
(v) => settingsStore!.lookupsFio = v
),
AddressSource.nostr.label: (
() => settingsStore!.lookupsNostr,
(v) => settingsStore!.lookupsNostr = v
),
AddressSource.thorChain.label: (
() => settingsStore!.lookupsThorChain,
(v) => settingsStore!.lookupsThorChain = v
),
AddressSource.bip353.label: (
() => settingsStore!.lookupsBip353,
(v) => settingsStore!.lookupsBip353 = v
),
}
: {};
} }

View file

@ -103,6 +103,18 @@ abstract class PrivacySettingsViewModelBase with Store {
@computed @computed
bool get looksUpWellKnown => _settingsStore.lookupsWellKnown; bool get looksUpWellKnown => _settingsStore.lookupsWellKnown;
@computed
bool get lookupsFio => _settingsStore.lookupsFio;
@computed
bool get lookupsNostr => _settingsStore.lookupsNostr;
@computed
bool get lookupsThorChain => _settingsStore.lookupsThorChain;
@computed
bool get lookupsBip353 => _settingsStore.lookupsBip353;
@computed @computed
bool get usePayjoin => _settingsStore.usePayjoin; bool get usePayjoin => _settingsStore.usePayjoin;
@ -169,6 +181,18 @@ abstract class PrivacySettingsViewModelBase with Store {
ethereum!.updateEtherscanUsageState(_wallet, value); ethereum!.updateEtherscanUsageState(_wallet, value);
} }
@action
void setLookupsFio(bool value) => _settingsStore.lookupsFio = value;
@action
void setLookupsNostr(bool value) => _settingsStore.lookupsNostr = value;
@action
void setLookupsThorChain(bool value) => _settingsStore.lookupsThorChain = value;
@action
void setLookupsBip353(bool value) => _settingsStore.lookupsBip353 = value;
@action @action
void setUsePolygonScan(bool value) { void setUsePolygonScan(bool value) {
_settingsStore.usePolygonScan = value; _settingsStore.usePolygonScan = value;