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:
Omar Hatem 2022-12-08 13:51:01 +02:00 committed by GitHub
commit f3b89a2c7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 61 additions and 105 deletions

View file

@ -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/src/screens/receive/fullscreen_qr_page.dart';
import 'package:cake_wallet/core/wallet_loading_service.dart';
import 'package:cw_core/crypto_currency.dart';
final getIt = GetIt.instance;
@ -472,12 +473,11 @@ Future setup(
(ContactRecord? contact, _) =>
ContactViewModel(_contactSource, contact: contact));
getIt.registerFactory(
() => ContactListViewModel(_contactSource, _walletInfoSource));
getIt.registerFactoryParam<ContactListViewModel, CryptoCurrency?, void>(
(CryptoCurrency? cur, _) => ContactListViewModel(_contactSource, _walletInfoSource, cur));
getIt.registerFactoryParam<ContactListPage, bool, void>(
(bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
isEditable: isEditable));
getIt.registerFactoryParam<ContactListPage, CryptoCurrency?, void>((CryptoCurrency? cur, _)
=> ContactListPage(getIt.get<ContactListViewModel>(param1: cur)));
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
(ContactRecord? contact, _) =>

View file

@ -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/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cw_core/crypto_currency.dart';
late RouteSettings currentRouteSettings;
@ -320,11 +321,13 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.addressBook:
return MaterialPageRoute<void>(
builder: (_) => getIt.get<ContactListPage>(param1: true));
builder: (_) =>
getIt.get<ContactListPage>());
case Routes.pickerAddressBook:
final selectedCurrency = settings.arguments as CryptoCurrency;
return MaterialPageRoute<void>(
builder: (_) => getIt.get<ContactListPage>(param1: false));
builder: (_) => getIt.get<ContactListPage>(param1: selectedCurrency));
case Routes.addressBookAddContact:
return CupertinoPageRoute<void>(

View file

@ -9,24 +9,22 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:cake_wallet/routes.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/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:cake_wallet/src/widgets/collapsible_standart_list.dart';
class ContactListPage extends BasePage {
ContactListPage(this.contactListViewModel, {this.isEditable = true});
ContactListPage(this.contactListViewModel);
final ContactListViewModel contactListViewModel;
final bool isEditable;
@override
String get title => S.current.address_book;
@override
Widget? trailing(BuildContext context) {
if (!isEditable) {
if (!contactListViewModel.isEditable) {
return null;
}
@ -60,10 +58,13 @@ class ContactListPage extends BasePage {
@override
Widget body(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
child: Observer(
builder: (_) {
final contacts = contactListViewModel.contactsToShow;
final walletContacts = contactListViewModel.walletContactsToShow;
return CollapsibleSectionList(
context: context,
sectionCount: 2,
@ -82,35 +83,37 @@ class ContactListPage extends BasePage {
child: Text(title, style: TextStyle(fontSize: 36)));
},
itemCounter: (int sectionIndex) => sectionIndex == 0
? contactListViewModel.walletContacts.length
: contactListViewModel.contacts.length,
? walletContacts.length
: contacts.length,
itemBuilder: (_, sectionIndex, index) {
if (sectionIndex == 0) {
final walletInfo = contactListViewModel.walletContacts[index];
final walletInfo = walletContacts[index];
return generateRaw(context, walletInfo);
}
final contact = contactListViewModel.contacts[index];
final contact = contacts[index];
final content = generateRaw(context, contact);
return !isEditable
? content
: Slidable(
return contactListViewModel.isEditable
? Slidable(
key: Key('${contact.key}'),
endActionPane: _actionPane(context, contact),
child: content,
);
)
: content;
},
);})
);
},
));
}
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(
onTap: () async {
if (!isEditable) {
if (!contactListViewModel.isEditable) {
Navigator.of(context).pop(contact);
return;
}
@ -131,12 +134,10 @@ class ContactListPage extends BasePage {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
image ?? Offstage(),
currencyIcon,
Expanded(
child: Padding(
padding: image != null
? EdgeInsets.only(left: 12)
: EdgeInsets.only(left: 0),
padding: EdgeInsets.only(left: 12),
child: Text(
contact.name,
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 {
return await showPopUp<bool>(
context: context,

View file

@ -395,7 +395,8 @@ class ExchangeCardState extends State<ExchangeCard> {
buttonColor: widget.addressButtonsColor,
validator: widget.addressTextFieldValidator,
onPushPasteButton: widget.onPushPasteButton,
onPushAddressBookButton: widget.onPushAddressBookButton
onPushAddressBookButton: widget.onPushAddressBookButton,
selectedCurrency: _selectedCurrency
),
)

View file

@ -154,6 +154,7 @@ class SendCardState extends State<SendCard>
await output.fetchParsedAddress(context);
},
validator: validator,
selectedCurrency: sendViewModel.currency,
);
}),
if (output.isParsedAddress) Padding(

View file

@ -4,6 +4,7 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/entities/qr_scanner.dart';
import 'package:cake_wallet/entities/contact_base.dart';
import 'package:cw_core/crypto_currency.dart';
enum AddressTextFieldOption { paste, qrCode, addressBook }
@ -26,7 +27,8 @@ class AddressTextField extends StatelessWidget {
this.hintStyle,
this.validator,
this.onPushPasteButton,
this.onPushAddressBookButton});
this.onPushAddressBookButton,
this.selectedCurrency});
static const prefixIconWidth = 34.0;
static const prefixIconHeight = 34.0;
@ -47,6 +49,7 @@ class AddressTextField extends StatelessWidget {
final FocusNode? focusNode;
final Function(BuildContext context)? onPushPasteButton;
final Function(BuildContext context)? onPushAddressBookButton;
final CryptoCurrency? selectedCurrency;
@override
Widget build(BuildContext context) {
@ -207,7 +210,7 @@ class AddressTextField extends StatelessWidget {
Future<void> _presetAddressBookPicker(BuildContext context) async {
final contact = await Navigator.of(context, rootNavigator: true)
.pushNamed(Routes.pickerAddressBook);
.pushNamed(Routes.pickerAddressBook,arguments: selectedCurrency);
if (contact is ContactBase && contact.address != null) {
controller?.text = contact.address;

View file

@ -7,27 +7,26 @@ import 'package:mobx/mobx.dart';
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/contact.dart';
import 'package:cake_wallet/utils/mobx.dart';
import 'package:cw_core/crypto_currency.dart';
part 'contact_list_view_model.g.dart';
class ContactListViewModel = ContactListViewModelBase
with _$ContactListViewModel;
class ContactListViewModel = ContactListViewModelBase with _$ContactListViewModel;
abstract class ContactListViewModelBase with Store {
ContactListViewModelBase(this.contactSource, this.walletInfoSource)
ContactListViewModelBase(this.contactSource, this.walletInfoSource, this._currency)
: contacts = ObservableList<ContactRecord>(),
walletContacts = [] {
walletInfoSource.values.forEach((info) {
if (info.addresses?.isNotEmpty ?? false) {
info.addresses?.forEach((address, label) {
final name = label.isNotEmpty
? info.name + ' ($label)'
: info.name;
final name = label.isNotEmpty ? info.name + ' ($label)' : info.name;
walletContacts.add(WalletContact(
address,
name,
walletTypeToCryptoCurrency(info.type)));
walletTypeToCryptoCurrency(info.type),
));
});
}
});
@ -41,7 +40,18 @@ abstract class ContactListViewModelBase with Store {
final Box<WalletInfo> walletInfoSource;
final ObservableList<ContactRecord> contacts;
final List<WalletContact> walletContacts;
final CryptoCurrency? _currency;
StreamSubscription<BoxEvent>? _subscription;
bool get isEditable => _currency == null;
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();
}