This commit is contained in:
M 2020-09-26 22:17:31 +03:00
parent dcdc411d41
commit 51cf11127c
21 changed files with 362 additions and 254 deletions

View file

@ -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);
}
}

View file

@ -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<AuthPage, void Function(bool, AuthPageState), bool>(
(onAuthFinished, closable) => AuthPage(getIt.get<AuthViewModel>(),
onAuthenticationFinished: onAuthFinished, closable: closable ?? false));
onAuthenticationFinished: onAuthFinished,
closable: closable ?? false));
getIt.registerFactory<DashboardPage>(() => DashboardPage(
walletViewModel: getIt.get<DashboardViewModel>(),
@ -282,8 +284,8 @@ Future setup(
getIt.registerFactory(() => WalletKeysPage(getIt.get<WalletKeysViewModel>()));
getIt.registerFactoryParam<ContactViewModel, Contact, void>(
(Contact contact, _) => ContactViewModel(
getIt.registerFactoryParam<ContactViewModel, ContactRecord, void>(
(ContactRecord contact, _) => ContactViewModel(
contactSource, getIt.get<AppStore>().wallet,
contact: contact));
@ -296,13 +298,14 @@ Future setup(
(bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
isEditable: isEditable));
getIt.registerFactoryParam<ContactPage, Contact, void>((Contact contact, _) =>
ContactPage(getIt.get<ContactViewModel>(param1: contact)));
getIt.registerFactoryParam<ContactPage, ContactRecord, void>(
(ContactRecord contact, _) =>
ContactPage(getIt.get<ContactViewModel>(param1: contact)));
getIt.registerFactory(() {
final appStore = getIt.get<AppStore>();
return NodeListViewModel(appStore.nodeListStore, nodeSource,
appStore.wallet, appStore.settingsStore);
return NodeListViewModel(
nodeSource, appStore.wallet, appStore.settingsStore);
});
getIt.registerFactory(() => NodeListPage(getIt.get<NodeListViewModel>()));

View file

@ -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<Contact> with Store {
ContactRecordBase(Box<Contact> 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;
}
}

View file

@ -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);

35
lib/entities/record.dart Normal file
View file

@ -0,0 +1,35 @@
import 'dart:async';
import 'package:cake_wallet/utils/mobx.dart';
import 'package:hive/hive.dart';
abstract class Record<T extends HiveObject> 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<T> _source;
StreamSubscription<BoxEvent> _listener;
void fromBind(T original);
void toBind(T original);
Future<void> save() => original.save();
}

View file

@ -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<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async {
startCurrentWalletChangeReaction(
appStore, settingsStore, fiatConversionStore);
startCurrentFiatChangeReaction(appStore, settingsStore);
startOnCurrentNodeChangeReaction(appStore);
}

View file

@ -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());
}
});
}

View file

@ -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<void>(
builder: (_) =>
getIt.get<ContactPage>(param1: settings.arguments as Contact));
getIt.get<ContactPage>(param1: settings.arguments as ContactRecord));
case Routes.showKeys:
return MaterialPageRoute<void>(

View file

@ -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),
),

View file

@ -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,

View file

@ -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<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: Text(
S.of(context).change_current_node(node.value.uri),
textAlign: TextAlign.center,
await showPopUp<void>(
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: <Widget>[
const Icon(
CupertinoIcons.delete,
color: Colors.white,
),
actions: <Widget>[
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: <Widget>[
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) {

View file

@ -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<Contact>();
ContactListStoreBase() : contacts = ObservableList<ContactRecord>();
final ObservableList<Contact> contacts;
final ObservableList<ContactRecord> contacts;
}

View file

@ -22,17 +22,13 @@ abstract class NodeListStoreBase with Store {
final nodeSource = getIt.get<Box<Node>>();
_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<Node> nodes;
void replaceValues(Iterable<Node> newNodes) {
nodes.clear();
nodes.addAll(newNodes);
}
}

View file

@ -21,7 +21,6 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore;
abstract class SettingsStoreBase with Store {
SettingsStoreBase(
{@required SharedPreferences sharedPreferences,
@required Box<Node> 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<WalletType, Node>.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<String, String> itemHeaders;
Node currentNode;
String languageCode;
@ -97,7 +98,6 @@ abstract class SettingsStoreBase with Store {
String appVersion;
SharedPreferences _sharedPreferences;
Box<Node> _nodeSource;
ObservableMap<WalletType, Node> 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<void> setCurrentNode(Node node, WalletType walletType) async {
Future<void> _saveCurrentNode(Node node, WalletType walletType) async {
switch (walletType) {
case WalletType.bitcoin:
await _sharedPreferences.setInt(

View file

@ -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<Item> 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;
}

View file

@ -6,36 +6,6 @@ mixin Keyable {
dynamic keyIndex;
}
void connectWithTransform<T extends Keyable, Y extends Keyable>(
ObservableList<T> source, ObservableList<Y> dest, Y Function(T) transform,
{bool Function(T) filter}) {
source.observe((ListChange<T> 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<T extends Keyable, Y extends Keyable>(
ObservableMap<dynamic, T> source,
ObservableList<Y> dest,
@ -50,8 +20,8 @@ void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>(
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<T extends Keyable, Y extends Keyable>(
});
}
void connect<T extends Keyable>(
ObservableList<T> source, ObservableList<T> dest) {
source.observe((ListChange<T> change) {
source.observe((ListChange<T> 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<T> = bool Function(T);
typedef Transform<T, Y> = Y Function(T);
if (item.keyIndex == change.newValue.key) {
dest[i] = change.newValue as T;
}
}
break;
}
});
});
});
enum ChangeType { update, delete, add }
class EntityChange<T extends Keyable> {
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<BoxEvent> bindBox<T extends Keyable>(
Box<T> source, ObservableList<T> dest) {
return source.watch().listen((event) {
extension MobxBindable<T extends Keyable> on Box<T> {
StreamSubscription<BoxEvent> bindToList(
ObservableList<T> dest, {
bool initialFire = false,
Filter<T> filter,
}) {
if (initialFire) {
dest.addAll(values);
}
return watch().listen((event) {
if (filter != null && !filter(event.value as T)) {
return;
}
dest.acceptBoxChange(event);
});
}
StreamSubscription<BoxEvent> bindToListWithTransform<Y extends Keyable>(
ObservableList<Y> dest,
Transform<T, Y> transform, {
bool initialFire = false,
Filter<T> 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<T extends Keyable> on ObservableList<T> {
Stream<EntityChange<T>> listen() {
// ignore: close_sinks
final controller = StreamController<EntityChange<T>>();
observe((ListChange<T> 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<EntityChange<T>> bindToList(ObservableList<T> 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<T> 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);
}
}
});
}
}

View file

@ -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<Contact> contactSource;
ObservableList<Contact> get contacts => addressBookStore.contacts;
ObservableList<ContactRecord> get contacts => addressBookStore.contacts;
StreamSubscription<BoxEvent> _subscription;
void dispose() {
_subscription.cancel();
// _subscription.cancel();
}
Future<void> delete(Contact contact) async => contactService.delete(contact);

View file

@ -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<CryptoCurrency> currencies;
final WalletBase _wallet;
final Box<Contact> _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));
}

View file

@ -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<ItemCell<Node>>() {
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<Node>(val,
isSelected: val.key == currentNode.key, key: val.key)));
connectWithTransform(
_nodeListStore.nodes,
nodes,
(Node val) => ItemCell<Node>(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<Node>() {
_nodeSource.bindToList(nodes,
filter: (Node val) => val.type == _wallet.type, initialFire: true);
}
ObservableList<ItemCell<Node>> nodes;
final ObservableList<Node> nodes;
final SettingsStore settingsStore;
final WalletBase _wallet;
final Box<Node> _nodeSource;
final NodeListStore _nodeListStore;
final SettingsStore _settingsStore;
Future<void> reset() async {
await resetToDefault(_nodeSource);
@ -64,24 +48,6 @@ abstract class NodeListViewModelBase with Store {
Future<void> delete(Node node) async => _nodeSource.delete(node.key);
Future<void> 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<Node>(item.value,
isSelected: isSelected, key: item.keyIndex);
}
}
}
Future<void> setAsCurrent(Node node) async =>
settingsStore.currentNode = node;
}

View file

@ -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:

View file

@ -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: