diff --git a/lib/core/contact_service.dart b/lib/core/contact_service.dart index c7027fa8f..3f2a46203 100644 --- a/lib/core/contact_service.dart +++ b/lib/core/contact_service.dart @@ -22,7 +22,7 @@ class ContactService { if (index >= 0) { _forceUpdateContactListStore(); } else { - contactListStore.contacts.add(contact); + // contactListStore.contacts.add(contact); } } @@ -33,6 +33,6 @@ class ContactService { void _forceUpdateContactListStore() { contactListStore.contacts.clear(); - contactListStore.contacts.addAll(contactSource.values); + // contactListStore.contacts.addAll(contactSource.values); } } diff --git a/lib/di.dart b/lib/di.dart index 2010a6158..d6ccde3cc 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -2,6 +2,7 @@ import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart'; import 'package:cake_wallet/core/contact_service.dart'; import 'package:cake_wallet/core/wallet_service.dart'; import 'package:cake_wallet/entities/biometric_auth.dart'; +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:cake_wallet/monero/monero_wallet_service.dart'; import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/node.dart'; @@ -197,7 +198,8 @@ Future setup( getIt .registerFactoryParam( (onAuthFinished, closable) => AuthPage(getIt.get(), - onAuthenticationFinished: onAuthFinished, closable: closable ?? false)); + onAuthenticationFinished: onAuthFinished, + closable: closable ?? false)); getIt.registerFactory(() => DashboardPage( walletViewModel: getIt.get(), @@ -282,8 +284,8 @@ Future setup( getIt.registerFactory(() => WalletKeysPage(getIt.get())); - getIt.registerFactoryParam( - (Contact contact, _) => ContactViewModel( + getIt.registerFactoryParam( + (ContactRecord contact, _) => ContactViewModel( contactSource, getIt.get().wallet, contact: contact)); @@ -296,13 +298,14 @@ Future setup( (bool isEditable, _) => ContactListPage(getIt.get(), isEditable: isEditable)); - getIt.registerFactoryParam((Contact contact, _) => - ContactPage(getIt.get(param1: contact))); + getIt.registerFactoryParam( + (ContactRecord contact, _) => + ContactPage(getIt.get(param1: contact))); getIt.registerFactory(() { final appStore = getIt.get(); - return NodeListViewModel(appStore.nodeListStore, nodeSource, - appStore.wallet, appStore.settingsStore); + return NodeListViewModel( + nodeSource, appStore.wallet, appStore.settingsStore); }); getIt.registerFactory(() => NodeListPage(getIt.get())); diff --git a/lib/entities/contact_record.dart b/lib/entities/contact_record.dart new file mode 100644 index 000000000..c4f55cc5a --- /dev/null +++ b/lib/entities/contact_record.dart @@ -0,0 +1,40 @@ +import 'package:hive/hive.dart'; +import 'package:mobx/mobx.dart'; +import 'package:cake_wallet/entities/contact.dart'; +import 'package:cake_wallet/entities/crypto_currency.dart'; +import 'package:cake_wallet/entities/record.dart'; + +part 'contact_record.g.dart'; + +class ContactRecord = ContactRecordBase with _$ContactRecord; + +abstract class ContactRecordBase extends Record with Store { + ContactRecordBase(Box source, Contact original) + : super(source, original); + + @observable + String name; + + @observable + String address; + + @observable + CryptoCurrency type; + + @override + void toBind(Contact original) { + reaction((_) => name, (String name) => original.name = name); + reaction((_) => address, (String address) => original.address = address); + reaction( + (_) => type, + (CryptoCurrency currency) => + original.updateCryptoCurrency(currency: currency)); + } + + @override + void fromBind(Contact original) { + name = original.name; + address = original.address; + type = original.type; + } +} diff --git a/lib/entities/node.dart b/lib/entities/node.dart index 74643112a..f79b8b2e0 100644 --- a/lib/entities/node.dart +++ b/lib/entities/node.dart @@ -38,6 +38,9 @@ class Node extends HiveObject with Keyable { @HiveField(3) int typeRaw; + @override + dynamic get keyIndex => key; + WalletType get type => deserializeFromInt(typeRaw); set type(WalletType type) => typeRaw = serializeToInt(type); diff --git a/lib/entities/record.dart b/lib/entities/record.dart new file mode 100644 index 000000000..3c21441cc --- /dev/null +++ b/lib/entities/record.dart @@ -0,0 +1,35 @@ +import 'dart:async'; + +import 'package:cake_wallet/utils/mobx.dart'; +import 'package:hive/hive.dart'; + +abstract class Record with Keyable { + Record(this._source, this.original) { + _listener?.cancel(); + _listener = _source.watch(key: original.key).listen((event) { + if (!event.deleted) { + fromBind(event.value as T); + } + }); + + fromBind(original); + toBind(original); + } + + dynamic get key => original.key; + + @override + dynamic get keyIndex => key; + + final T original; + + final Box _source; + + StreamSubscription _listener; + + void fromBind(T original); + + void toBind(T original); + + Future save() => original.save(); +} diff --git a/lib/reactions/bootstrap.dart b/lib/reactions/bootstrap.dart index 2ffb5d376..fef73c46f 100644 --- a/lib/reactions/bootstrap.dart +++ b/lib/reactions/bootstrap.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:cake_wallet/reactions/on_current_node_change.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/widgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -31,4 +32,5 @@ Future bootstrap(GlobalKey navigatorKey) async { startCurrentWalletChangeReaction( appStore, settingsStore, fiatConversionStore); startCurrentFiatChangeReaction(appStore, settingsStore); + startOnCurrentNodeChangeReaction(appStore); } diff --git a/lib/reactions/on_current_node_change.dart b/lib/reactions/on_current_node_change.dart new file mode 100644 index 000000000..c03bbac21 --- /dev/null +++ b/lib/reactions/on_current_node_change.dart @@ -0,0 +1,17 @@ +import 'package:mobx/mobx.dart'; +import 'package:cake_wallet/entities/node.dart'; +import 'package:cake_wallet/store/app_store.dart'; + +ReactionDisposer _onCurrentNodeChangeReaction; + +void startOnCurrentNodeChangeReaction(AppStore appStore) { + _onCurrentNodeChangeReaction?.reaction?.dispose(); + _onCurrentNodeChangeReaction = + reaction((_) => appStore.settingsStore.currentNode, (Node node) async { + try { + await appStore.wallet.connectToNode(node: node); + } catch (e) { + print(e.toString()); + } + }); +} diff --git a/lib/router.dart b/lib/router.dart index 5213758f2..cc660d9a0 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/routes.dart'; @@ -252,7 +253,7 @@ class Router { case Routes.addressBookAddContact: return CupertinoPageRoute( builder: (_) => - getIt.get(param1: settings.arguments as Contact)); + getIt.get(param1: settings.arguments as ContactRecord)); case Routes.showKeys: return MaterialPageRoute( diff --git a/lib/src/screens/contact/contact_list_page.dart b/lib/src/screens/contact/contact_list_page.dart index 044484f49..37c37876f 100644 --- a/lib/src/screens/contact/contact_list_page.dart +++ b/lib/src/screens/contact/contact_list_page.dart @@ -164,17 +164,17 @@ class ContactListPage extends BasePage { final isDelete = await showAlertDialog(context) ?? false; - if (isDelete) { - await contactListViewModel - .delete(contact); - } + // if (isDelete) { + // await contactListViewModel + // .delete(contact); + // } }, ), ], dismissal: SlidableDismissal( child: SlidableDrawerDismissal(), - onDismissed: (actionType) async => - await contactListViewModel.delete(contact), + onDismissed: (actionType) async => null, + // await contactListViewModel.delete(contact), onWillDismiss: (actionType) async => showAlertDialog(context), ), diff --git a/lib/src/screens/monero_accounts/widgets/account_tile.dart b/lib/src/screens/monero_accounts/widgets/account_tile.dart index c39758bd5..50238a67c 100644 --- a/lib/src/screens/monero_accounts/widgets/account_tile.dart +++ b/lib/src/screens/monero_accounts/widgets/account_tile.dart @@ -31,7 +31,7 @@ class AccountTile extends StatelessWidget { accountName, style: TextStyle( fontSize: 18, - fontWeight: FontWeight.bold, + fontWeight: FontWeight.w600, fontFamily: 'Poppins', color: textColor, decoration: TextDecoration.none, diff --git a/lib/src/screens/nodes/nodes_list_page.dart b/lib/src/screens/nodes/nodes_list_page.dart index 84e87a3a5..b0bc8c15f 100644 --- a/lib/src/screens/nodes/nodes_list_page.dart +++ b/lib/src/screens/nodes/nodes_list_page.dart @@ -67,87 +67,86 @@ class NodeListPage extends BasePage { sectionCount: 2, context: context, itemBuilder: (_, sectionIndex, index) { - if (sectionIndex == 0) { - return NodeHeaderListRow( - title: S.of(context).add_new_node, - onTap: (_) async => - await Navigator.of(context).pushNamed(Routes.newNode)); - } + return Observer(builder: (_) { + if (sectionIndex == 0) { + return NodeHeaderListRow( + title: S.of(context).add_new_node, + onTap: (_) async => await Navigator.of(context) + .pushNamed(Routes.newNode)); + } - final node = nodeListViewModel.nodes[index]; - final nodeListRow = NodeListRow( - title: node.value.uri, - isSelected: node.isSelected, - isAlive: node.value.requestNode(), - onTap: (_) async { - if (node.isSelected) { - return; - } + final node = nodeListViewModel.nodes[index]; + final isSelected = node.keyIndex == + nodeListViewModel.settingsStore.currentNode.keyIndex; + final nodeListRow = NodeListRow( + title: node.uri, + isSelected: isSelected, + isAlive: node.requestNode(), + onTap: (_) async { + if (isSelected) { + return; + } - await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertDialog( - content: Text( - S.of(context).change_current_node(node.value.uri), - textAlign: TextAlign.center, + await showPopUp( + context: context, + builder: (BuildContext context) { + // FIXME: Add translation. + return AlertWithTwoActions( + alertTitle: 'Change current node', + alertContent: + S.of(context).change_current_node(node.uri), + leftButtonText: S.of(context).cancel, + rightButtonText: S.of(context).change, + actionLeftButton: () => + Navigator.of(context).pop(), + actionRightButton: () async { + await nodeListViewModel.setAsCurrent(node); + Navigator.of(context).pop(); + }); + }); + }); + + final dismissibleRow = Dismissible( + key: Key('${node.keyIndex}'), + confirmDismiss: (direction) async { + return await showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithTwoActions( + alertTitle: S.of(context).remove_node, + alertContent: S.of(context).remove_node_message, + rightButtonText: S.of(context).remove, + leftButtonText: S.of(context).cancel, + actionRightButton: () => + Navigator.pop(context, true), + actionLeftButton: () => + Navigator.pop(context, false)); + }); + }, + onDismissed: (direction) async => + nodeListViewModel.delete(node), + direction: DismissDirection.endToStart, + background: Container( + padding: EdgeInsets.only(right: 10.0), + alignment: AlignmentDirectional.centerEnd, + color: Palette.red, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + const Icon( + CupertinoIcons.delete, + color: Colors.white, ), - actions: [ - FlatButton( - onPressed: () => Navigator.pop(context), - child: Text(S.of(context).cancel)), - FlatButton( - onPressed: () async { - Navigator.of(context).pop(); - await nodeListViewModel - .setAsCurrent(node.value); - }, - child: Text(S.of(context).change)), - ], - ); - }); - }); + Text( + S.of(context).delete, + style: TextStyle(color: Colors.white), + ) + ], + )), + child: nodeListRow); - final dismissibleRow = Dismissible( - key: Key('${node.keyIndex}'), - confirmDismiss: (direction) async { - return await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithTwoActions( - alertTitle: S.of(context).remove_node, - alertContent: S.of(context).remove_node_message, - rightButtonText: S.of(context).remove, - leftButtonText: S.of(context).cancel, - actionRightButton: () => - Navigator.pop(context, true), - actionLeftButton: () => - Navigator.pop(context, false)); - }); - }, - onDismissed: (direction) async => - nodeListViewModel.delete(node.value), - direction: DismissDirection.endToStart, - background: Container( - padding: EdgeInsets.only(right: 10.0), - alignment: AlignmentDirectional.centerEnd, - color: Palette.red, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - const Icon( - CupertinoIcons.delete, - color: Colors.white, - ), - Text( - S.of(context).delete, - style: TextStyle(color: Colors.white), - ) - ], - )), - child: nodeListRow); - - return node.isSelected ? nodeListRow : dismissibleRow; + return isSelected ? nodeListRow : dismissibleRow; + }); }, itemCounter: (int sectionIndex) { if (sectionIndex == 0) { diff --git a/lib/store/contact_list_store.dart b/lib/store/contact_list_store.dart index ca3d0bcf0..85194e0d6 100644 --- a/lib/store/contact_list_store.dart +++ b/lib/store/contact_list_store.dart @@ -1,12 +1,12 @@ import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/entities/contact.dart'; +import 'package:cake_wallet/entities/contact_record.dart'; part 'contact_list_store.g.dart'; class ContactListStore = ContactListStoreBase with _$ContactListStore; abstract class ContactListStoreBase with Store { - ContactListStoreBase() : contacts = ObservableList(); + ContactListStoreBase() : contacts = ObservableList(); - final ObservableList contacts; + final ObservableList contacts; } diff --git a/lib/store/node_list_store.dart b/lib/store/node_list_store.dart index 0ff958e3f..56fe0333a 100644 --- a/lib/store/node_list_store.dart +++ b/lib/store/node_list_store.dart @@ -22,17 +22,13 @@ abstract class NodeListStoreBase with Store { final nodeSource = getIt.get>(); _instance = NodeListStore(); - _instance.replaceValues(nodeSource.values); + _instance.nodes.clear(); + _instance.nodes.addAll(nodeSource.values); _onNodesSourceChange?.cancel(); - _onNodesSourceChange = bindBox(nodeSource, _instance.nodes); + _onNodesSourceChange = nodeSource.bindToList(_instance.nodes); return _instance; } final ObservableList nodes; - - void replaceValues(Iterable newNodes) { - nodes.clear(); - nodes.addAll(newNodes); - } } diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index e17ce2de9..d4f6bf95a 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -21,7 +21,6 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore; abstract class SettingsStoreBase with Store { SettingsStoreBase( {@required SharedPreferences sharedPreferences, - @required Box nodeSource, @required FiatCurrency initialFiatCurrency, @required TransactionPriority initialTransactionPriority, @required BalanceDisplayMode initialBalanceDisplayMode, @@ -43,10 +42,9 @@ abstract class SettingsStoreBase with Store { pinCodeLength = initialPinLength; languageCode = initialLanguageCode; currentLocale = initialCurrentLocale; - itemHeaders = {}; + currentNode = nodes[WalletType.monero]; this.nodes = ObservableMap.of(nodes); _sharedPreferences = sharedPreferences; - _nodeSource = nodeSource; reaction( (_) => allowBiometricalAuthentication, @@ -58,6 +56,9 @@ abstract class SettingsStoreBase with Store { (_) => pinCodeLength, (int pinLength) => sharedPreferences.setInt( PreferencesKey.currentPinLength, pinLength)); + + reaction((_) => currentNode, + (Node node) => _saveCurrentNode(node, WalletType.monero)); } static const defaultPinLength = 4; @@ -88,7 +89,7 @@ abstract class SettingsStoreBase with Store { int pinCodeLength; @observable - Map itemHeaders; + Node currentNode; String languageCode; @@ -97,7 +98,6 @@ abstract class SettingsStoreBase with Store { String appVersion; SharedPreferences _sharedPreferences; - Box _nodeSource; ObservableMap nodes; @@ -150,7 +150,6 @@ abstract class SettingsStoreBase with Store { WalletType.monero: moneroNode, WalletType.bitcoin: bitcoinElectrumServer }, - nodeSource: nodeSource, appVersion: packageInfo.version, initialFiatCurrency: currentFiatCurrency, initialTransactionPriority: currentTransactionPriority, @@ -164,7 +163,7 @@ abstract class SettingsStoreBase with Store { initialCurrentLocale: initialCurrentLocale); } - Future setCurrentNode(Node node, WalletType walletType) async { + Future _saveCurrentNode(Node node, WalletType walletType) async { switch (walletType) { case WalletType.bitcoin: await _sharedPreferences.setInt( diff --git a/lib/utils/item_cell.dart b/lib/utils/item_cell.dart index 4aca57b46..150df6d50 100644 --- a/lib/utils/item_cell.dart +++ b/lib/utils/item_cell.dart @@ -1,11 +1,18 @@ import 'package:flutter/foundation.dart'; +import 'package:mobx/mobx.dart'; import 'package:cake_wallet/utils/mobx.dart'; +// part 'node_list_view_model.g.dart'; +// +// class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel; + class ItemCell with Keyable { - ItemCell(this.value, {@required this.isSelected, @required dynamic key}) { + ItemCell(this.value, {this.isSelectedBuilder, @required dynamic key}) { keyIndex = key; } final Item value; - final bool isSelected; + + bool get isSelected => isSelectedBuilder(value); + bool Function(Item item) isSelectedBuilder; } diff --git a/lib/utils/mobx.dart b/lib/utils/mobx.dart index cb2d810e5..b11922f8e 100644 --- a/lib/utils/mobx.dart +++ b/lib/utils/mobx.dart @@ -6,36 +6,6 @@ mixin Keyable { dynamic keyIndex; } -void connectWithTransform( - ObservableList source, ObservableList dest, Y Function(T) transform, - {bool Function(T) filter}) { - source.observe((ListChange change) { - change.elementChanges.forEach((change) { - switch (change.type) { - case OperationType.add: - if (filter?.call(change.newValue as T) ?? true) { - dest.add(transform(change.newValue as T)); - } - break; - case OperationType.remove: - // Hive could has equal index and key - dest.removeWhere( - (elem) => elem.keyIndex == (change.oldValue.key ?? change.index)); - break; - case OperationType.update: - for (var i = 0; i < dest.length; i++) { - final item = dest[i]; - - if (item.keyIndex == change.newValue.key) { - dest[i] = transform(change.newValue as T); - } - } - break; - } - }); - }); -} - void connectMapToListWithTransform( ObservableMap source, ObservableList dest, @@ -50,8 +20,8 @@ void connectMapToListWithTransform( break; case OperationType.remove: // Hive could has equal index and key - dest.removeWhere( - (elem) => elem.keyIndex == (change.key ?? change.newValue.keyIndex)); + dest.removeWhere((elem) => + elem.keyIndex == (change.key ?? change.newValue.keyIndex)); break; case OperationType.update: for (var i = 0; i < dest.length; i++) { @@ -66,54 +36,124 @@ void connectMapToListWithTransform( }); } -void connect( - ObservableList source, ObservableList dest) { - source.observe((ListChange change) { - source.observe((ListChange change) { - change.elementChanges.forEach((change) { - switch (change.type) { - case OperationType.add: - // if (filter?.call(change.newValue as T) ?? true) { - dest.add(change.newValue as T); - // } - break; - case OperationType.remove: - // Hive could has equal index and key - dest.removeWhere((elem) => - elem.keyIndex == (change.oldValue.key ?? change.index)); - break; - case OperationType.update: - for (var i = 0; i < dest.length; i++) { - final item = dest[i]; +typedef Filter = bool Function(T); +typedef Transform = Y Function(T); - if (item.keyIndex == change.newValue.key) { - dest[i] = change.newValue as T; - } - } - break; - } - }); - }); - }); +enum ChangeType { update, delete, add } + +class EntityChange { + EntityChange(this.value, this.type, {dynamic key}) : _key = key; + + dynamic get key => _key ?? value.keyIndex; + final T value; + final ChangeType type; + final dynamic _key; } -StreamSubscription bindBox( - Box source, ObservableList dest) { - return source.watch().listen((event) { +extension MobxBindable on Box { + StreamSubscription bindToList( + ObservableList dest, { + bool initialFire = false, + Filter filter, + }) { + if (initialFire) { + dest.addAll(values); + } + + return watch().listen((event) { + if (filter != null && !filter(event.value as T)) { + return; + } + + dest.acceptBoxChange(event); + }); + } + + StreamSubscription bindToListWithTransform( + ObservableList dest, + Transform transform, { + bool initialFire = false, + Filter filter, + }) { + if (initialFire) { + dest.addAll(values.map((value) => transform(value))); + } + + return watch().listen((event) { + if (filter != null && !filter(event.value as T)) { + return; + } + + dest.acceptBoxChange(event, transformed: transform(event.value as T)); + }); + } +} + +extension HiveBindable on ObservableList { + Stream> listen() { + // ignore: close_sinks + final controller = StreamController>(); + + observe((ListChange change) { + change.elementChanges.forEach((change) { + ChangeType type; + + switch (change.type) { + case OperationType.add: + type = ChangeType.add; + break; + case OperationType.remove: + type = ChangeType.delete; + break; + case OperationType.update: + type = ChangeType.update; + break; + } + + final value = change.newValue as T; + controller.add(EntityChange(value, type)); + }); + }); + + return controller.stream; + } + + StreamSubscription> bindToList(ObservableList dest) => + listen().listen((event) => dest.acceptEntityChange(event)); + + void acceptBoxChange(BoxEvent event, {T transformed}) { if (event.deleted) { - dest.removeWhere((el) => el.keyIndex == event.key); + removeWhere((el) => el.keyIndex == event.key); + } + + final dynamic value = transformed ?? event.value; + + if (value is T) { + final index = indexWhere((el) => el.keyIndex == value.keyIndex); + + if (index > -1) { + this.setAll(index, [value]); // FIXME: fixme + } else { + add(value); + } + } + } + + void acceptEntityChange(EntityChange event) { + if (event.type == ChangeType.delete) { + removeWhere((el) => el.keyIndex == event.key); } final dynamic value = event.value; if (value is T) { - final elIndex = dest.indexWhere((el) => el.keyIndex == value.keyIndex); + final index = indexWhere((el) => el.keyIndex == value.keyIndex); - if (elIndex > -1) { - dest[elIndex] = value; + if (index > -1) { + this.setAll(index, [value]); // FIXME: fixme } else { - dest.add(value); + add(value); } } - }); + } } diff --git a/lib/view_model/contact_list/contact_list_view_model.dart b/lib/view_model/contact_list/contact_list_view_model.dart index d222cb6dd..aa3a5e2c7 100644 --- a/lib/view_model/contact_list/contact_list_view_model.dart +++ b/lib/view_model/contact_list/contact_list_view_model.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/core/contact_service.dart'; @@ -14,19 +15,21 @@ class ContactListViewModel = ContactListViewModelBase abstract class ContactListViewModelBase with Store { ContactListViewModelBase( this.addressBookStore, this.contactService, this.contactSource) { - _subscription = bindBox(contactSource, addressBookStore.contacts); + _subscription = contactSource.bindToListWithTransform(addressBookStore.contacts, + (Contact contact) => ContactRecord(contactSource, contact), + initialFire: true); } final ContactListStore addressBookStore; final ContactService contactService; final Box contactSource; - ObservableList get contacts => addressBookStore.contacts; + ObservableList get contacts => addressBookStore.contacts; StreamSubscription _subscription; void dispose() { - _subscription.cancel(); + // _subscription.cancel(); } Future delete(Contact contact) async => contactService.delete(contact); diff --git a/lib/view_model/contact_list/contact_view_model.dart b/lib/view_model/contact_list/contact_view_model.dart index 059b6a210..cb48260b5 100644 --- a/lib/view_model/contact_list/contact_view_model.dart +++ b/lib/view_model/contact_list/contact_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/entities/contact_record.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/core/execution_state.dart'; @@ -11,7 +12,7 @@ part 'contact_view_model.g.dart'; class ContactViewModel = ContactViewModelBase with _$ContactViewModel; abstract class ContactViewModelBase with Store { - ContactViewModelBase(this._contacts, this._wallet, {Contact contact}) + ContactViewModelBase(this._contacts, this._wallet, {ContactRecord contact}) : state = InitialExecutionState(), currencies = CryptoCurrency.all, _contact = contact { @@ -41,7 +42,7 @@ abstract class ContactViewModelBase with Store { final List currencies; final WalletBase _wallet; final Box _contacts; - final Contact _contact; + final ContactRecord _contact; @action void reset() { @@ -57,9 +58,12 @@ abstract class ContactViewModelBase with Store { if (_contact != null) { _contact.name = name; _contact.address = address; - _contact.updateCryptoCurrency(currency: currency); - await _contacts.put(_contact.key, _contact); + _contact.type = currency; + await _contact.save(); + // await _contacts.put(_contact.key, _contact); } else { + // final contact = ContactRecordBase.create(_contacts, name, address, currency); + // await contact.save(); await _contacts .add(Contact(name: name, address: address, type: currency)); } diff --git a/lib/view_model/node_list/node_list_view_model.dart b/lib/view_model/node_list/node_list_view_model.dart index 4ca46c9fc..2231ff7c9 100644 --- a/lib/view_model/node_list/node_list_view_model.dart +++ b/lib/view_model/node_list/node_list_view_model.dart @@ -1,45 +1,29 @@ import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/core/wallet_base.dart'; +import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/entities/node.dart'; import 'package:cake_wallet/entities/node_list.dart'; -import 'package:cake_wallet/store/node_list_store.dart'; -import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/entities/default_settings_migration.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/utils/mobx.dart'; -import 'package:cake_wallet/utils/item_cell.dart'; part 'node_list_view_model.g.dart'; class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel; abstract class NodeListViewModelBase with Store { - NodeListViewModelBase( - this._nodeListStore, this._nodeSource, this._wallet, this._settingsStore) - : nodes = ObservableList>() { - final currentNode = _settingsStore.getCurrentNode(_wallet.type); - final values = _nodeListStore.nodes; - nodes.clear(); - nodes.addAll(values.where((Node node) => node.type == _wallet.type).map( - (Node val) => ItemCell(val, - isSelected: val.key == currentNode.key, key: val.key))); - connectWithTransform( - _nodeListStore.nodes, - nodes, - (Node val) => ItemCell(val, - isSelected: val.key == currentNode.key, key: val.key), - filter: (Node val) => val.type == _wallet.type); - reaction((_) => _settingsStore.nodes[_wallet.type], - (Node _) => _updateCurrentNode()); + NodeListViewModelBase(this._nodeSource, this._wallet, this.settingsStore) + : nodes = ObservableList() { + _nodeSource.bindToList(nodes, + filter: (Node val) => val.type == _wallet.type, initialFire: true); } - ObservableList> nodes; + final ObservableList nodes; + final SettingsStore settingsStore; final WalletBase _wallet; final Box _nodeSource; - final NodeListStore _nodeListStore; - final SettingsStore _settingsStore; Future reset() async { await resetToDefault(_nodeSource); @@ -64,24 +48,6 @@ abstract class NodeListViewModelBase with Store { Future delete(Node node) async => _nodeSource.delete(node.key); - Future setAsCurrent(Node node) async { - await _settingsStore.setCurrentNode(node, _wallet.type); - _updateCurrentNode(); - await _wallet.connectToNode(node: node); - } - - @action - void _updateCurrentNode() { - final currentNode = _settingsStore.getCurrentNode(_wallet.type); - - for (var i = 0; i < nodes.length; i++) { - final item = nodes[i]; - final isSelected = item.value.key == currentNode.key; - - if (item.isSelected != isSelected) { - nodes[i] = ItemCell(item.value, - isSelected: isSelected, key: item.keyIndex); - } - } - } + Future setAsCurrent(Node node) async => + settingsStore.currentNode = node; } diff --git a/pubspec.lock b/pubspec.lock index 612b1ac91..f9bbbbd26 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -217,7 +217,7 @@ packages: name: connectivity url: "https://pub.dartlang.org" source: hosted - version: "0.4.9+2" + version: "0.4.9+3" connectivity_for_web: dependency: transitive description: @@ -252,7 +252,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.5" csslib: dependency: transitive description: @@ -395,7 +395,7 @@ packages: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "1.0.9" + version: "1.0.11" flutter_secure_storage: dependency: "direct main" description: @@ -470,7 +470,7 @@ packages: name: hive_generator url: "https://pub.dartlang.org" source: hosted - version: "0.7.1" + version: "0.7.2+1" html: dependency: transitive description: @@ -505,7 +505,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.12" + version: "2.1.18" intl: dependency: "direct main" description: @@ -533,14 +533,14 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.1.0" local_auth: dependency: "direct main" description: name: local_auth url: "https://pub.dartlang.org" source: hosted - version: "0.6.3+1" + version: "0.6.3+2" logging: dependency: transitive description: @@ -645,7 +645,7 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.17" + version: "1.6.18" path_provider_linux: dependency: transitive description: @@ -687,7 +687,7 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "2.4.0" + version: "3.0.4" platform: dependency: transitive description: @@ -695,13 +695,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.1" - platform_detect: - dependency: transitive - description: - name: platform_detect - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" plugin_platform_interface: dependency: transitive description: @@ -785,14 +778,14 @@ packages: name: share url: "https://pub.dartlang.org" source: hosted - version: "0.6.5+1" + version: "0.6.5+2" shared_preferences: dependency: "direct main" description: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "0.5.11" + version: "0.5.12" shared_preferences_linux: dependency: transitive description: @@ -937,7 +930,7 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "5.7.0" + version: "5.7.2" url_launcher_linux: dependency: transitive description: @@ -965,7 +958,7 @@ packages: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.3+2" + version: "0.1.4+1" url_launcher_windows: dependency: transitive description: @@ -1021,7 +1014,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.6.1" + version: "4.5.1" yaml: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index f15f131c1..d6ac4bf73 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,7 +14,7 @@ description: Cake Wallet. version: 1.0.5+5 environment: - sdk: ">=2.2.2 <3.0.0" + sdk: ">=2.7.0 <3.0.0" dependencies: flutter: