mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
feat: add toggle supported handles
This commit is contained in:
parent
8dc3bb649d
commit
a298a28f56
12 changed files with 305 additions and 97 deletions
|
@ -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),
|
||||||
|
|
|
@ -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,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -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)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
),
|
||||||
|
}
|
||||||
|
: {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue