mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
Merge pull request #601 from cake-tech/CW-159-Filter-address-book-by-type
[CW-159] filter contacts and wallets by type
This commit is contained in:
commit
f3b89a2c7f
7 changed files with 61 additions and 105 deletions
10
lib/di.dart
10
lib/di.dart
|
@ -160,6 +160,7 @@ import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
|
||||||
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
|
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
|
||||||
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
|
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
|
||||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
|
||||||
final getIt = GetIt.instance;
|
final getIt = GetIt.instance;
|
||||||
|
|
||||||
|
@ -472,12 +473,11 @@ Future setup(
|
||||||
(ContactRecord? contact, _) =>
|
(ContactRecord? contact, _) =>
|
||||||
ContactViewModel(_contactSource, contact: contact));
|
ContactViewModel(_contactSource, contact: contact));
|
||||||
|
|
||||||
getIt.registerFactory(
|
getIt.registerFactoryParam<ContactListViewModel, CryptoCurrency?, void>(
|
||||||
() => ContactListViewModel(_contactSource, _walletInfoSource));
|
(CryptoCurrency? cur, _) => ContactListViewModel(_contactSource, _walletInfoSource, cur));
|
||||||
|
|
||||||
getIt.registerFactoryParam<ContactListPage, bool, void>(
|
getIt.registerFactoryParam<ContactListPage, CryptoCurrency?, void>((CryptoCurrency? cur, _)
|
||||||
(bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
|
=> ContactListPage(getIt.get<ContactListViewModel>(param1: cur)));
|
||||||
isEditable: isEditable));
|
|
||||||
|
|
||||||
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
|
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
|
||||||
(ContactRecord? contact, _) =>
|
(ContactRecord? contact, _) =>
|
||||||
|
|
|
@ -80,6 +80,7 @@ import 'package:cake_wallet/src/screens/ionia/ionia.dart';
|
||||||
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
|
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
|
||||||
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
|
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
|
||||||
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
|
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
|
||||||
late RouteSettings currentRouteSettings;
|
late RouteSettings currentRouteSettings;
|
||||||
|
|
||||||
|
@ -320,11 +321,13 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
|
|
||||||
case Routes.addressBook:
|
case Routes.addressBook:
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
builder: (_) => getIt.get<ContactListPage>(param1: true));
|
builder: (_) =>
|
||||||
|
getIt.get<ContactListPage>());
|
||||||
|
|
||||||
case Routes.pickerAddressBook:
|
case Routes.pickerAddressBook:
|
||||||
|
final selectedCurrency = settings.arguments as CryptoCurrency;
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
builder: (_) => getIt.get<ContactListPage>(param1: false));
|
builder: (_) => getIt.get<ContactListPage>(param1: selectedCurrency));
|
||||||
|
|
||||||
case Routes.addressBookAddContact:
|
case Routes.addressBookAddContact:
|
||||||
return CupertinoPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
|
|
|
@ -9,24 +9,22 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
|
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
|
||||||
import 'package:cake_wallet/src/widgets/collapsible_standart_list.dart';
|
import 'package:cake_wallet/src/widgets/collapsible_standart_list.dart';
|
||||||
|
|
||||||
class ContactListPage extends BasePage {
|
class ContactListPage extends BasePage {
|
||||||
ContactListPage(this.contactListViewModel, {this.isEditable = true});
|
ContactListPage(this.contactListViewModel);
|
||||||
|
|
||||||
final ContactListViewModel contactListViewModel;
|
final ContactListViewModel contactListViewModel;
|
||||||
final bool isEditable;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get title => S.current.address_book;
|
String get title => S.current.address_book;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? trailing(BuildContext context) {
|
Widget? trailing(BuildContext context) {
|
||||||
if (!isEditable) {
|
if (!contactListViewModel.isEditable) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,11 +58,14 @@ class ContactListPage extends BasePage {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget body(BuildContext context) {
|
Widget body(BuildContext context) {
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
|
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
|
||||||
child: Observer(
|
child: Observer(
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
return CollapsibleSectionList(
|
final contacts = contactListViewModel.contactsToShow;
|
||||||
|
final walletContacts = contactListViewModel.walletContactsToShow;
|
||||||
|
return CollapsibleSectionList(
|
||||||
context: context,
|
context: context,
|
||||||
sectionCount: 2,
|
sectionCount: 2,
|
||||||
themeColor: Theme.of(context).primaryTextTheme.headline6!.color!,
|
themeColor: Theme.of(context).primaryTextTheme.headline6!.color!,
|
||||||
|
@ -82,35 +83,37 @@ class ContactListPage extends BasePage {
|
||||||
child: Text(title, style: TextStyle(fontSize: 36)));
|
child: Text(title, style: TextStyle(fontSize: 36)));
|
||||||
},
|
},
|
||||||
itemCounter: (int sectionIndex) => sectionIndex == 0
|
itemCounter: (int sectionIndex) => sectionIndex == 0
|
||||||
? contactListViewModel.walletContacts.length
|
? walletContacts.length
|
||||||
: contactListViewModel.contacts.length,
|
: contacts.length,
|
||||||
itemBuilder: (_, sectionIndex, index) {
|
itemBuilder: (_, sectionIndex, index) {
|
||||||
if (sectionIndex == 0) {
|
if (sectionIndex == 0) {
|
||||||
final walletInfo = contactListViewModel.walletContacts[index];
|
final walletInfo = walletContacts[index];
|
||||||
return generateRaw(context, walletInfo);
|
return generateRaw(context, walletInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
final contact = contactListViewModel.contacts[index];
|
final contact = contacts[index];
|
||||||
final content = generateRaw(context, contact);
|
final content = generateRaw(context, contact);
|
||||||
return !isEditable
|
return contactListViewModel.isEditable
|
||||||
? content
|
? Slidable(
|
||||||
: Slidable(
|
|
||||||
key: Key('${contact.key}'),
|
key: Key('${contact.key}'),
|
||||||
endActionPane: _actionPane(context, contact),
|
endActionPane: _actionPane(context, contact),
|
||||||
child: content,
|
child: content,
|
||||||
);
|
)
|
||||||
|
: content;
|
||||||
},
|
},
|
||||||
);
|
);})
|
||||||
},
|
);
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget generateRaw(BuildContext context, ContactBase contact) {
|
Widget generateRaw(BuildContext context, ContactBase contact) {
|
||||||
final image = _getCurrencyImage(contact.type);
|
final image = contact.type.iconPath;
|
||||||
|
final currencyIcon = image != null ? Image.asset(image, height: 24, width: 24)
|
||||||
|
: const SizedBox(height: 24, width: 24);
|
||||||
|
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (!isEditable) {
|
if (!contactListViewModel.isEditable) {
|
||||||
Navigator.of(context).pop(contact);
|
Navigator.of(context).pop(contact);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -131,12 +134,10 @@ class ContactListPage extends BasePage {
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
image ?? Offstage(),
|
currencyIcon,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: image != null
|
padding: EdgeInsets.only(left: 12),
|
||||||
? EdgeInsets.only(left: 12)
|
|
||||||
: EdgeInsets.only(left: 0),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
contact.name,
|
contact.name,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -152,69 +153,6 @@ class ContactListPage extends BasePage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image? _getCurrencyImage(CryptoCurrency currency) {
|
|
||||||
Image? image;
|
|
||||||
|
|
||||||
switch (currency) {
|
|
||||||
case CryptoCurrency.xmr:
|
|
||||||
image =
|
|
||||||
Image.asset('assets/images/monero_logo.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.ada:
|
|
||||||
image = Image.asset('assets/images/ada.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.bch:
|
|
||||||
image = Image.asset('assets/images/bch.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.bnb:
|
|
||||||
image = Image.asset('assets/images/bnb.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.btc:
|
|
||||||
image = Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.dai:
|
|
||||||
image = Image.asset('assets/images/dai.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.dash:
|
|
||||||
image = Image.asset('assets/images/dash.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.eos:
|
|
||||||
image = Image.asset('assets/images/eos.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.eth:
|
|
||||||
image = Image.asset('assets/images/eth.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.ltc:
|
|
||||||
image =
|
|
||||||
Image.asset('assets/images/litecoin.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.nano:
|
|
||||||
image = Image.asset('assets/images/nano.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.trx:
|
|
||||||
image = Image.asset('assets/images/trx.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.usdt:
|
|
||||||
image = Image.asset('assets/images/usdt.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.usdterc20:
|
|
||||||
image = Image.asset('assets/images/usdterc.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.xlm:
|
|
||||||
image = Image.asset('assets/images/xlm.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.xrp:
|
|
||||||
image = Image.asset('assets/images/xrp.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
case CryptoCurrency.xhv:
|
|
||||||
image = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
image = null;
|
|
||||||
}
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> showAlertDialog(BuildContext context) async {
|
Future<bool> showAlertDialog(BuildContext context) async {
|
||||||
return await showPopUp<bool>(
|
return await showPopUp<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
|
@ -395,7 +395,8 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
buttonColor: widget.addressButtonsColor,
|
buttonColor: widget.addressButtonsColor,
|
||||||
validator: widget.addressTextFieldValidator,
|
validator: widget.addressTextFieldValidator,
|
||||||
onPushPasteButton: widget.onPushPasteButton,
|
onPushPasteButton: widget.onPushPasteButton,
|
||||||
onPushAddressBookButton: widget.onPushAddressBookButton
|
onPushAddressBookButton: widget.onPushAddressBookButton,
|
||||||
|
selectedCurrency: _selectedCurrency
|
||||||
),
|
),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -154,6 +154,7 @@ class SendCardState extends State<SendCard>
|
||||||
await output.fetchParsedAddress(context);
|
await output.fetchParsedAddress(context);
|
||||||
},
|
},
|
||||||
validator: validator,
|
validator: validator,
|
||||||
|
selectedCurrency: sendViewModel.currency,
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
if (output.isParsedAddress) Padding(
|
if (output.isParsedAddress) Padding(
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/entities/qr_scanner.dart';
|
import 'package:cake_wallet/entities/qr_scanner.dart';
|
||||||
import 'package:cake_wallet/entities/contact_base.dart';
|
import 'package:cake_wallet/entities/contact_base.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
|
||||||
enum AddressTextFieldOption { paste, qrCode, addressBook }
|
enum AddressTextFieldOption { paste, qrCode, addressBook }
|
||||||
|
|
||||||
|
@ -26,7 +27,8 @@ class AddressTextField extends StatelessWidget {
|
||||||
this.hintStyle,
|
this.hintStyle,
|
||||||
this.validator,
|
this.validator,
|
||||||
this.onPushPasteButton,
|
this.onPushPasteButton,
|
||||||
this.onPushAddressBookButton});
|
this.onPushAddressBookButton,
|
||||||
|
this.selectedCurrency});
|
||||||
|
|
||||||
static const prefixIconWidth = 34.0;
|
static const prefixIconWidth = 34.0;
|
||||||
static const prefixIconHeight = 34.0;
|
static const prefixIconHeight = 34.0;
|
||||||
|
@ -47,6 +49,7 @@ class AddressTextField extends StatelessWidget {
|
||||||
final FocusNode? focusNode;
|
final FocusNode? focusNode;
|
||||||
final Function(BuildContext context)? onPushPasteButton;
|
final Function(BuildContext context)? onPushPasteButton;
|
||||||
final Function(BuildContext context)? onPushAddressBookButton;
|
final Function(BuildContext context)? onPushAddressBookButton;
|
||||||
|
final CryptoCurrency? selectedCurrency;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -207,7 +210,7 @@ class AddressTextField extends StatelessWidget {
|
||||||
|
|
||||||
Future<void> _presetAddressBookPicker(BuildContext context) async {
|
Future<void> _presetAddressBookPicker(BuildContext context) async {
|
||||||
final contact = await Navigator.of(context, rootNavigator: true)
|
final contact = await Navigator.of(context, rootNavigator: true)
|
||||||
.pushNamed(Routes.pickerAddressBook);
|
.pushNamed(Routes.pickerAddressBook,arguments: selectedCurrency);
|
||||||
|
|
||||||
if (contact is ContactBase && contact.address != null) {
|
if (contact is ContactBase && contact.address != null) {
|
||||||
controller?.text = contact.address;
|
controller?.text = contact.address;
|
||||||
|
|
|
@ -7,27 +7,26 @@ import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/entities/contact_record.dart';
|
import 'package:cake_wallet/entities/contact_record.dart';
|
||||||
import 'package:cake_wallet/entities/contact.dart';
|
import 'package:cake_wallet/entities/contact.dart';
|
||||||
import 'package:cake_wallet/utils/mobx.dart';
|
import 'package:cake_wallet/utils/mobx.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
|
||||||
part 'contact_list_view_model.g.dart';
|
part 'contact_list_view_model.g.dart';
|
||||||
|
|
||||||
class ContactListViewModel = ContactListViewModelBase
|
class ContactListViewModel = ContactListViewModelBase with _$ContactListViewModel;
|
||||||
with _$ContactListViewModel;
|
|
||||||
|
|
||||||
abstract class ContactListViewModelBase with Store {
|
abstract class ContactListViewModelBase with Store {
|
||||||
ContactListViewModelBase(this.contactSource, this.walletInfoSource)
|
ContactListViewModelBase(this.contactSource, this.walletInfoSource, this._currency)
|
||||||
: contacts = ObservableList<ContactRecord>(),
|
: contacts = ObservableList<ContactRecord>(),
|
||||||
walletContacts = [] {
|
walletContacts = [] {
|
||||||
walletInfoSource.values.forEach((info) {
|
walletInfoSource.values.forEach((info) {
|
||||||
if (info.addresses?.isNotEmpty ?? false) {
|
if (info.addresses?.isNotEmpty ?? false) {
|
||||||
info.addresses?.forEach((address, label) {
|
info.addresses?.forEach((address, label) {
|
||||||
final name = label.isNotEmpty
|
final name = label.isNotEmpty ? info.name + ' ($label)' : info.name;
|
||||||
? info.name + ' ($label)'
|
|
||||||
: info.name;
|
|
||||||
|
|
||||||
walletContacts.add(WalletContact(
|
walletContacts.add(WalletContact(
|
||||||
address,
|
address,
|
||||||
name,
|
name,
|
||||||
walletTypeToCryptoCurrency(info.type)));
|
walletTypeToCryptoCurrency(info.type),
|
||||||
|
));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -41,7 +40,18 @@ abstract class ContactListViewModelBase with Store {
|
||||||
final Box<WalletInfo> walletInfoSource;
|
final Box<WalletInfo> walletInfoSource;
|
||||||
final ObservableList<ContactRecord> contacts;
|
final ObservableList<ContactRecord> contacts;
|
||||||
final List<WalletContact> walletContacts;
|
final List<WalletContact> walletContacts;
|
||||||
|
final CryptoCurrency? _currency;
|
||||||
StreamSubscription<BoxEvent>? _subscription;
|
StreamSubscription<BoxEvent>? _subscription;
|
||||||
|
|
||||||
|
bool get isEditable => _currency == null;
|
||||||
|
|
||||||
Future<void> delete(ContactRecord contact) async => contact.original.delete();
|
Future<void> delete(ContactRecord contact) async => contact.original.delete();
|
||||||
|
|
||||||
|
@computed
|
||||||
|
List<ContactRecord> get contactsToShow =>
|
||||||
|
contacts.where((element) => _currency == null || element.type == _currency).toList();
|
||||||
|
|
||||||
|
@computed
|
||||||
|
List<WalletContact> get walletContactsToShow =>
|
||||||
|
walletContacts.where((element) => _currency == null || element.type == _currency).toList();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue