From f704bdc864488f6ff42735129aaa82b366879a06 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Fri, 13 Nov 2020 20:29:01 +0200 Subject: [PATCH 1/7] CAKE-158 | added calculating balance to _onAccountChangeReaction in the monero wallet; created _onMoneroAccountChange method in the dashboard_view_model.dart; added _onMoneroAccountChangeReaction and account filter to transaction list in the dashboard_view_model.dart --- lib/monero/monero_wallet.dart | 4 + .../dashboard/dashboard_view_model.dart | 85 ++++++++++++++----- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index 4b9dd1cfc..1eaab9b18 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -40,6 +40,10 @@ abstract class MoneroWalletBase extends WalletBase with Store { fullBalance: monero_wallet.getFullBalance(accountIndex: 0), unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0)); _onAccountChangeReaction = reaction((_) => account, (Account account) { + balance = MoneroBalance( + fullBalance: monero_wallet.getFullBalance(accountIndex: account.id), + unlockedBalance: + monero_wallet.getUnlockedBalance(accountIndex: account.id)); subaddressList.update(accountIndex: account.id); subaddress = subaddressList.subaddresses.first; address = subaddress.address; diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index e76a663ec..62742d848 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -1,5 +1,6 @@ import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; +import 'package:cake_wallet/monero/account.dart'; import 'package:cake_wallet/monero/monero_wallet.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; @@ -74,27 +75,41 @@ abstract class DashboardViewModelBase with Store { wallet ??= appStore.wallet; type = wallet.type; - transactions = ObservableList.of(wallet - .transactionHistory.transactions.values - .map((transaction) => TransactionListItem( - transaction: transaction, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore))); - _reaction = reaction((_) => appStore.wallet, _onWalletChange); - // FIXME: fixme - connectMapToListWithTransform( - appStore.wallet.transactionHistory.transactions, - transactions, - (TransactionInfo val) => TransactionListItem( - transaction: val, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore)); final _wallet = wallet; if (_wallet is MoneroWallet) { subname = _wallet.account?.label; + + _onMoneroAccountChangeReaction = reaction((_) => _wallet.account, + (Account account) => _onMoneroAccountChange(_wallet)); + + final _accountTransactions = _wallet + .transactionHistory.transactions.values + .where((tx) => tx.accountIndex == _wallet.account.id).toList(); + + transactions = ObservableList.of(_accountTransactions + .map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + } else { + transactions = ObservableList.of(wallet + .transactionHistory.transactions.values + .map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + + // FIXME: fixme + connectMapToListWithTransform( + appStore.wallet.transactionHistory.transactions, + transactions, + (TransactionInfo val) => TransactionListItem( + transaction: val, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore)); } } @@ -170,6 +185,8 @@ abstract class DashboardViewModelBase with Store { ReactionDisposer _reaction; + ReactionDisposer _onMoneroAccountChangeReaction; + Future reconnect() async { final node = appStore.settingsStore.getCurrentNode(wallet.type); await wallet.connectToNode(node: node); @@ -180,10 +197,38 @@ abstract class DashboardViewModelBase with Store { this.wallet = wallet; name = wallet.name; transactions.clear(); - transactions.addAll(wallet.transactionHistory.transactions.values.map( - (transaction) => TransactionListItem( - transaction: transaction, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore))); + + if (wallet is MoneroWallet) { + final _accountTransactions = wallet + .transactionHistory.transactions.values + .where((tx) => tx.accountIndex == wallet.account.id).toList(); + + transactions.addAll(_accountTransactions + .map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + } else { + transactions.addAll(wallet.transactionHistory.transactions.values.map( + (transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + } + } + + @action + void _onMoneroAccountChange(MoneroWallet wallet) { + transactions.clear(); + + final _accountTransactions = wallet + .transactionHistory.transactions.values + .where((tx) => tx.accountIndex == wallet.account.id).toList(); + + transactions.addAll(_accountTransactions + .map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); } } From 23abacd2526c9d898422de3abc055f89fd9070bb Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Tue, 17 Nov 2020 20:16:58 +0200 Subject: [PATCH 2/7] CAKE-158 | made account tile slidable; added onEdit function to account tile; added ability to edit wallet account name; added isFirstAddress parameter to wallet_address_list_view_model.dart and made first address in the address list not editable (receive page); wrapped wallet account name in the wallet menu title by observer; added _moneroTransactionsChangeReaction to dashboard_view_model.dart --- lib/core/monero_account_label_validator.dart | 2 +- lib/di.dart | 18 ++++++++-- lib/router.dart | 4 ++- .../dashboard/widgets/menu_widget.dart | 5 +-- .../monero_account_list_page.dart | 7 +++- .../monero_accounts/widgets/account_tile.dart | 22 ++++++++++-- lib/src/screens/receive/receive_page.dart | 3 ++ .../screens/receive/widgets/address_cell.dart | 6 +++- .../dashboard/dashboard_view_model.dart | 36 +++++++++++++++++++ ...ero_account_edit_or_create_view_model.dart | 1 + .../wallet_address_list_view_model.dart | 4 +++ 11 files changed, 97 insertions(+), 11 deletions(-) diff --git a/lib/core/monero_account_label_validator.dart b/lib/core/monero_account_label_validator.dart index dcbac668f..2bc0fcccc 100644 --- a/lib/core/monero_account_label_validator.dart +++ b/lib/core/monero_account_label_validator.dart @@ -7,7 +7,7 @@ class MoneroLabelValidator extends TextValidator { MoneroLabelValidator({@required CryptoCurrency type}) : super( errorMessage: S.current.error_text_account_name, - pattern: '^[a-zA-Z0-9_]{1,15}\$', + pattern: '^[a-zA-Z0-9_ ]{1,15}\$', minLength: 1, maxLength: 15); } diff --git a/lib/di.dart b/lib/di.dart index 1dba56bc1..f7e6fe3b6 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -48,6 +48,7 @@ import 'package:cake_wallet/store/wallet_list_store.dart'; import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart'; import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; +import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart'; import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart'; import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart'; import 'package:cake_wallet/view_model/rescan_view_model.dart'; @@ -272,7 +273,7 @@ Future setup( getIt.registerFactory(() => MoneroAccountListPage( accountListViewModel: getIt.get())); - getIt.registerFactory(() { + /*getIt.registerFactory(() { final wallet = getIt.get().wallet; if (wallet is MoneroWallet) { @@ -285,7 +286,20 @@ Future setup( getIt.registerFactory(() => MoneroAccountEditOrCreatePage( moneroAccountCreationViewModel: - getIt.get())); + getIt.get()));*/ + + getIt.registerFactoryParam( + (AccountListItem account, _) => + MoneroAccountEditOrCreateViewModel(( + getIt.get().wallet as MoneroWallet).accountList, + accountListItem: account)); + + getIt.registerFactoryParam((AccountListItem account, _) => + MoneroAccountEditOrCreatePage( + moneroAccountCreationViewModel: + getIt.get(param1: account))); getIt.registerFactory(() { final appStore = getIt.get(); diff --git a/lib/router.dart b/lib/router.dart index acad61d04..2d7877d0b 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart'; import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/routes.dart'; @@ -261,7 +262,8 @@ Route createRoute(RouteSettings settings) { case Routes.accountCreation: return CupertinoPageRoute( - builder: (_) => getIt.get()); + builder: (_) => getIt.get( + param1: settings.arguments as AccountListItem)); case Routes.addressBook: return MaterialPageRoute( diff --git a/lib/src/screens/dashboard/widgets/menu_widget.dart b/lib/src/screens/dashboard/widgets/menu_widget.dart index 7701d0ad3..f8de5ba8d 100644 --- a/lib/src/screens/dashboard/widgets/menu_widget.dart +++ b/lib/src/screens/dashboard/widgets/menu_widget.dart @@ -5,6 +5,7 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/src/screens/dashboard/wallet_menu.dart'; import 'package:flutter/rendering.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; // FIXME: terrible design. @@ -147,7 +148,7 @@ class MenuWidgetState extends State { ), if (widget.dashboardViewModel.subname != null) - Text( + Observer(builder: (_) => Text( widget.dashboardViewModel.subname, style: TextStyle( color: Theme.of(context) @@ -156,7 +157,7 @@ class MenuWidgetState extends State { .decorationColor, fontWeight: FontWeight.w500, fontSize: 12), - ) + )) ], ), )) diff --git a/lib/src/screens/monero_accounts/monero_account_list_page.dart b/lib/src/screens/monero_accounts/monero_account_list_page.dart index 623f3cb90..47404e443 100644 --- a/lib/src/screens/monero_accounts/monero_account_list_page.dart +++ b/lib/src/screens/monero_accounts/monero_account_list_page.dart @@ -103,7 +103,12 @@ class MoneroAccountListPage extends StatelessWidget { accountListViewModel .select(account); Navigator.of(context).pop(); - }); + }, + onEdit: () async => + await Navigator.of(context) + .pushNamed( + Routes.accountCreation, + arguments: account)); }, ), isAlwaysShowScrollThumb diff --git a/lib/src/screens/monero_accounts/widgets/account_tile.dart b/lib/src/screens/monero_accounts/widgets/account_tile.dart index eb9c7f25d..f07539333 100644 --- a/lib/src/screens/monero_accounts/widgets/account_tile.dart +++ b/lib/src/screens/monero_accounts/widgets/account_tile.dart @@ -1,15 +1,19 @@ import 'package:flutter/material.dart'; +import 'package:flutter_slidable/flutter_slidable.dart'; +import 'package:cake_wallet/generated/i18n.dart'; class AccountTile extends StatelessWidget { AccountTile({ @required this.isCurrent, @required this.accountName, - @required this.onTap + @required this.onTap, + @required this.onEdit }); final bool isCurrent; final String accountName; - final VoidCallback onTap; + final Function() onTap; + final Function() onEdit; @override Widget build(BuildContext context) { @@ -20,7 +24,7 @@ class AccountTile extends StatelessWidget { ? Theme.of(context).textTheme.subtitle.color : Theme.of(context).textTheme.display4.color; - return GestureDetector( + final Widget cell = GestureDetector( onTap: onTap, child: Container( height: 77, @@ -39,5 +43,17 @@ class AccountTile extends StatelessWidget { ), ), ); + + return isCurrent ? cell : Slidable( + key: Key(accountName), + child: cell, + actionPane: SlidableDrawerActionPane(), + secondaryActions: [ + IconSlideAction( + caption: S.of(context).edit, + color: Colors.blue, + icon: Icons.edit, + onTap: () => onEdit?.call()) + ]); } } \ No newline at end of file diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 1ac4a073b..202784ee8 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -116,6 +116,8 @@ class ReceivePage extends BasePage { } if (item is WalletAddressListItem) { + final isFirst = addressListViewModel.isFirstAddress; + addressListViewModel.isFirstAddress = false; cell = Observer(builder: (_) { final isCurrent = item.address == addressListViewModel.address.address; @@ -134,6 +136,7 @@ class ReceivePage extends BasePage { return AddressCell.fromItem(item, isCurrent: isCurrent, + isFirstAddress: isFirst, backgroundColor: backgroundColor, textColor: textColor, onTap: (_) => addressListViewModel.setAddress(item), diff --git a/lib/src/screens/receive/widgets/address_cell.dart b/lib/src/screens/receive/widgets/address_cell.dart index 6306ae209..cfc63a242 100644 --- a/lib/src/screens/receive/widgets/address_cell.dart +++ b/lib/src/screens/receive/widgets/address_cell.dart @@ -6,6 +6,7 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_i class AddressCell extends StatelessWidget { factory AddressCell.fromItem(WalletAddressListItem item, {@required bool isCurrent, + @required bool isFirstAddress, @required Color backgroundColor, @required Color textColor, Function(String) onTap, @@ -14,6 +15,7 @@ class AddressCell extends StatelessWidget { address: item.address, name: item.name, isCurrent: isCurrent, + isFirstAddress: isFirstAddress, backgroundColor: backgroundColor, textColor: textColor, onTap: onTap, @@ -23,6 +25,7 @@ class AddressCell extends StatelessWidget { {@required this.address, @required this.name, @required this.isCurrent, + @required this.isFirstAddress, @required this.backgroundColor, @required this.textColor, this.onTap, @@ -31,6 +34,7 @@ class AddressCell extends StatelessWidget { final String address; final String name; final bool isCurrent; + final bool isFirstAddress; final Color backgroundColor; final Color textColor; final Function(String) onTap; @@ -56,7 +60,7 @@ class AddressCell extends StatelessWidget { ), )); - return isCurrent + return (isCurrent || isFirstAddress) ? cell : Slidable( key: Key(address), diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 62742d848..189c3ea32 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -1,6 +1,8 @@ import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; +import 'package:cake_wallet/entities/transaction_history.dart'; import 'package:cake_wallet/monero/account.dart'; +import 'package:cake_wallet/monero/monero_transaction_history.dart'; import 'package:cake_wallet/monero/monero_wallet.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; @@ -85,6 +87,10 @@ abstract class DashboardViewModelBase with Store { _onMoneroAccountChangeReaction = reaction((_) => _wallet.account, (Account account) => _onMoneroAccountChange(_wallet)); + _onMoneroTransactionsChangeReaction = reaction((_) => _wallet.transactionHistory, + (MoneroTransactionHistory transactionHistory) => + _onMoneroTransactionsChange(_wallet)); + final _accountTransactions = _wallet .transactionHistory.transactions.values .where((tx) => tx.accountIndex == _wallet.account.id).toList(); @@ -187,6 +193,8 @@ abstract class DashboardViewModelBase with Store { ReactionDisposer _onMoneroAccountChangeReaction; + ReactionDisposer _onMoneroTransactionsChangeReaction; + Future reconnect() async { final node = appStore.settingsStore.getCurrentNode(wallet.type); await wallet.connectToNode(node: node); @@ -199,6 +207,18 @@ abstract class DashboardViewModelBase with Store { transactions.clear(); if (wallet is MoneroWallet) { + subname = wallet.account?.label; + + _onMoneroAccountChangeReaction?.reaction?.dispose(); + _onMoneroTransactionsChangeReaction?.reaction?.dispose(); + + _onMoneroAccountChangeReaction = reaction((_) => wallet.account, + (Account account) => _onMoneroAccountChange(wallet)); + + _onMoneroTransactionsChangeReaction = reaction((_) => wallet.transactionHistory, + (MoneroTransactionHistory transactionHistory) => + _onMoneroTransactionsChange(wallet)); + final _accountTransactions = wallet .transactionHistory.transactions.values .where((tx) => tx.accountIndex == wallet.account.id).toList(); @@ -219,6 +239,22 @@ abstract class DashboardViewModelBase with Store { @action void _onMoneroAccountChange(MoneroWallet wallet) { + subname = wallet.account?.label; + transactions.clear(); + + final _accountTransactions = wallet + .transactionHistory.transactions.values + .where((tx) => tx.accountIndex == wallet.account.id).toList(); + + transactions.addAll(_accountTransactions + .map((transaction) => TransactionListItem( + transaction: transaction, + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); + } + + @action + void _onMoneroTransactionsChange(MoneroWallet wallet) { transactions.clear(); final _accountTransactions = wallet diff --git a/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart b/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart index 33e9dd1e5..d32f8eadd 100644 --- a/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart +++ b/lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart @@ -13,6 +13,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store { {AccountListItem accountListItem}) : state = InitialExecutionState(), isEdit = accountListItem != null, + label = accountListItem?.label??'', _accountListItem = accountListItem; final bool isEdit; diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart index e8c897bfc..de8ba1e9e 100644 --- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart @@ -67,6 +67,9 @@ abstract class WalletAddressListViewModelBase with Store { @observable String amount; + @observable + bool isFirstAddress; + @computed WalletType get type => _wallet.type; @@ -97,6 +100,7 @@ abstract class WalletAddressListViewModelBase with Store { final addressList = ObservableList(); if (wallet is MoneroWallet) { + isFirstAddress = true; addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) => WalletAddressListItem( id: subaddress.id, From 7aecb330442912fab3ad4079948120199317a1e1 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Wed, 18 Nov 2020 19:09:34 +0200 Subject: [PATCH 3/7] CAKE-158 | merged 4.0.8 into current branch; renamed _onMoneroTransactionsChange() on _onMoneroTransactionsUpdate(); applied _onMoneroTransactionsUpdate() in the dashboard_view_model.dart --- lib/src/screens/receive/receive_page.dart | 1 + .../dashboard/dashboard_view_model.dart | 31 +++++-------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 11d063cfd..3ee61c365 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 189c3ea32..b95ebc680 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -89,7 +89,7 @@ abstract class DashboardViewModelBase with Store { _onMoneroTransactionsChangeReaction = reaction((_) => _wallet.transactionHistory, (MoneroTransactionHistory transactionHistory) => - _onMoneroTransactionsChange(_wallet)); + _onMoneroTransactionsUpdate(_wallet)); final _accountTransactions = _wallet .transactionHistory.transactions.values @@ -204,7 +204,6 @@ abstract class DashboardViewModelBase with Store { void _onWalletChange(WalletBase wallet) { this.wallet = wallet; name = wallet.name; - transactions.clear(); if (wallet is MoneroWallet) { subname = wallet.account?.label; @@ -217,18 +216,12 @@ abstract class DashboardViewModelBase with Store { _onMoneroTransactionsChangeReaction = reaction((_) => wallet.transactionHistory, (MoneroTransactionHistory transactionHistory) => - _onMoneroTransactionsChange(wallet)); + _onMoneroTransactionsUpdate(wallet)); - final _accountTransactions = wallet - .transactionHistory.transactions.values - .where((tx) => tx.accountIndex == wallet.account.id).toList(); - - transactions.addAll(_accountTransactions - .map((transaction) => TransactionListItem( - transaction: transaction, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore))); + _onMoneroTransactionsUpdate(wallet); } else { + transactions.clear(); + transactions.addAll(wallet.transactionHistory.transactions.values.map( (transaction) => TransactionListItem( transaction: transaction, @@ -240,21 +233,11 @@ abstract class DashboardViewModelBase with Store { @action void _onMoneroAccountChange(MoneroWallet wallet) { subname = wallet.account?.label; - transactions.clear(); - - final _accountTransactions = wallet - .transactionHistory.transactions.values - .where((tx) => tx.accountIndex == wallet.account.id).toList(); - - transactions.addAll(_accountTransactions - .map((transaction) => TransactionListItem( - transaction: transaction, - balanceViewModel: balanceViewModel, - settingsStore: appStore.settingsStore))); + _onMoneroTransactionsUpdate(wallet); } @action - void _onMoneroTransactionsChange(MoneroWallet wallet) { + void _onMoneroTransactionsUpdate(MoneroWallet wallet) { transactions.clear(); final _accountTransactions = wallet From 5787bac65857e03218e2150d0368a93548117aa2 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Fri, 20 Nov 2020 18:27:56 +0200 Subject: [PATCH 4/7] CAKE-158 | added _onMoneroBalanceChangeReaction instead _onMoneroTransactionsChangeReaction in the dashboard_view_model.dart --- lib/monero/monero_wallet.dart | 5 +++-- .../dashboard/dashboard_view_model.dart | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index a68dbffff..81a3ab7a6 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -367,17 +367,18 @@ abstract class MoneroWalletBase extends WalletBase with Store { void _onNewBlock(int height, int blocksLeft, double ptc) async { if (walletInfo.isRecovery) { - _askForUpdateTransactionHistory(); + await _askForUpdateTransactionHistory(); _askForUpdateBalance(); } if (blocksLeft < 100) { + await _askForUpdateTransactionHistory(); _askForUpdateBalance(); syncStatus = SyncedSyncStatus(); await _afterSyncSave(); if (walletInfo.isRecovery) { - setAsRecovered(); + await setAsRecovered(); } } else { syncStatus = SyncingSyncStatus(blocksLeft, ptc); diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index b95ebc680..1c632396a 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -2,7 +2,9 @@ import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/entities/transaction_history.dart'; import 'package:cake_wallet/monero/account.dart'; +import 'package:cake_wallet/monero/monero_balance.dart'; import 'package:cake_wallet/monero/monero_transaction_history.dart'; +import 'package:cake_wallet/monero/monero_transaction_info.dart'; import 'package:cake_wallet/monero/monero_wallet.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; @@ -87,9 +89,9 @@ abstract class DashboardViewModelBase with Store { _onMoneroAccountChangeReaction = reaction((_) => _wallet.account, (Account account) => _onMoneroAccountChange(_wallet)); - _onMoneroTransactionsChangeReaction = reaction((_) => _wallet.transactionHistory, - (MoneroTransactionHistory transactionHistory) => - _onMoneroTransactionsUpdate(_wallet)); + _onMoneroBalanceChangeReaction = reaction((_) => + _wallet.balance, (MoneroBalance balance) => + _onMoneroTransactionsUpdate(_wallet)); final _accountTransactions = _wallet .transactionHistory.transactions.values @@ -193,7 +195,7 @@ abstract class DashboardViewModelBase with Store { ReactionDisposer _onMoneroAccountChangeReaction; - ReactionDisposer _onMoneroTransactionsChangeReaction; + ReactionDisposer _onMoneroBalanceChangeReaction; Future reconnect() async { final node = appStore.settingsStore.getCurrentNode(wallet.type); @@ -209,14 +211,14 @@ abstract class DashboardViewModelBase with Store { subname = wallet.account?.label; _onMoneroAccountChangeReaction?.reaction?.dispose(); - _onMoneroTransactionsChangeReaction?.reaction?.dispose(); + _onMoneroBalanceChangeReaction?.reaction?.dispose(); _onMoneroAccountChangeReaction = reaction((_) => wallet.account, (Account account) => _onMoneroAccountChange(wallet)); - _onMoneroTransactionsChangeReaction = reaction((_) => wallet.transactionHistory, - (MoneroTransactionHistory transactionHistory) => - _onMoneroTransactionsUpdate(wallet)); + _onMoneroBalanceChangeReaction = reaction((_) => + wallet.balance, (MoneroBalance balance) => + _onMoneroTransactionsUpdate(wallet)); _onMoneroTransactionsUpdate(wallet); } else { From e10387a1b6174e03b566753ad7748b9ef82d0aa5 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Mon, 30 Nov 2020 20:27:44 +0200 Subject: [PATCH 5/7] CAKE-158 | called update() method for accountList in the _onNewBlock() and rescan() methods (monero_wallet.dart) --- lib/monero/monero_wallet.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index 81a3ab7a6..f4774b68b 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -98,7 +98,7 @@ abstract class MoneroWalletBase extends WalletBase with Store { bool _isSavingAfterNewTransaction; Future init() async { - await accountList.update(); + accountList.update(); account = accountList.accounts.first; subaddressList.update(accountIndex: account.id ?? 0); subaddress = subaddressList.getAll().first; @@ -260,6 +260,7 @@ abstract class MoneroWalletBase extends WalletBase with Store { monero_wallet.rescanBlockchainAsync(); await startSync(); _askForUpdateBalance(); + accountList.update(); await _askForUpdateTransactionHistory(); await save(); await walletInfo.save(); @@ -369,11 +370,13 @@ abstract class MoneroWalletBase extends WalletBase with Store { if (walletInfo.isRecovery) { await _askForUpdateTransactionHistory(); _askForUpdateBalance(); + accountList.update(); } if (blocksLeft < 100) { await _askForUpdateTransactionHistory(); _askForUpdateBalance(); + accountList.update(); syncStatus = SyncedSyncStatus(); await _afterSyncSave(); From a5d5831d993e18ab0e58c7ccd491faa07bc48a8a Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Thu, 3 Dec 2020 22:06:16 +0200 Subject: [PATCH 6/7] CAKE-158 | removed isFirstAddress from wallet_address_list_view_model.dart; rename isFirstAddress property of AddressCell on isPrimary; defined primary address cell in the receive_page.dart --- lib/src/screens/receive/receive_page.dart | 153 +++++++++--------- .../screens/receive/widgets/address_cell.dart | 10 +- .../wallet_address_list_view_model.dart | 4 - 3 files changed, 84 insertions(+), 83 deletions(-) diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 3ee61c365..303d2aab2 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -95,85 +95,90 @@ class ReceivePage extends BasePage { amountTextFieldFocusNode: _cryptoAmountFocus), ), Observer( - builder: (_) => ListView.separated( - padding: EdgeInsets.all(0), - separatorBuilder: (context, _) => Container( - height: 1, color: Theme.of(context).dividerColor), - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: addressListViewModel.items.length, - itemBuilder: (context, index) { - final item = addressListViewModel.items[index]; - Widget cell = Container(); + builder: (_) { + var isPrimaryAddress = true; - if (item is WalletAccountListHeader) { - cell = HeaderTile( - onTap: () async => await showPopUp( - context: context, - builder: (_) => - getIt.get()), - title: S.of(context).accounts, - icon: Icon( - Icons.arrow_forward_ios, - size: 14, - color: - Theme.of(context).textTheme.display1.color, - )); - } + return ListView.separated( + padding: EdgeInsets.all(0), + separatorBuilder: (context, _) => Container( + height: 1, color: Theme.of(context).dividerColor), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: addressListViewModel.items.length, + itemBuilder: (context, index) { + final item = addressListViewModel.items[index]; + Widget cell = Container(); - if (item is WalletAddressListHeader) { - cell = HeaderTile( - onTap: () => Navigator.of(context) - .pushNamed(Routes.newSubaddress), - title: S.of(context).addresses, - icon: Icon( - Icons.add, - size: 20, - color: - Theme.of(context).textTheme.display1.color, - )); - } + if (item is WalletAccountListHeader) { + cell = HeaderTile( + onTap: () async => await showPopUp( + context: context, + builder: (_) => + getIt.get()), + title: S.of(context).accounts, + icon: Icon( + Icons.arrow_forward_ios, + size: 14, + color: + Theme.of(context).textTheme.display1.color, + )); + } - if (item is WalletAddressListItem) { - final isFirst = addressListViewModel.isFirstAddress; - addressListViewModel.isFirstAddress = false; - cell = Observer(builder: (_) { - final isCurrent = item.address == - addressListViewModel.address.address; - final backgroundColor = isCurrent - ? Theme.of(context) - .textTheme - .display3 - .decorationColor - : Theme.of(context) - .textTheme - .display2 - .decorationColor; - final textColor = isCurrent - ? Theme.of(context).textTheme.display3.color - : Theme.of(context).textTheme.display2.color; + if (item is WalletAddressListHeader) { + cell = HeaderTile( + onTap: () => Navigator.of(context) + .pushNamed(Routes.newSubaddress), + title: S.of(context).addresses, + icon: Icon( + Icons.add, + size: 20, + color: + Theme.of(context).textTheme.display1.color, + )); + } - return AddressCell.fromItem(item, - isCurrent: isCurrent, - isFirstAddress: isFirst, - backgroundColor: backgroundColor, - textColor: textColor, - onTap: (_) => addressListViewModel.setAddress(item), - onEdit: () => Navigator.of(context).pushNamed( - Routes.newSubaddress, - arguments: item)); - }); - } + if (item is WalletAddressListItem) { + final isPrimary = isPrimaryAddress; + isPrimaryAddress = false; - return index != 0 - ? cell - : ClipRRect( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(30), - topRight: Radius.circular(30)), - child: cell, - ); - })), + cell = Observer(builder: (_) { + final isCurrent = item.address == + addressListViewModel.address.address; + final backgroundColor = isCurrent + ? Theme.of(context) + .textTheme + .display3 + .decorationColor + : Theme.of(context) + .textTheme + .display2 + .decorationColor; + final textColor = isCurrent + ? Theme.of(context).textTheme.display3.color + : Theme.of(context).textTheme.display2.color; + + return AddressCell.fromItem(item, + isCurrent: isCurrent, + isPrimary: isPrimary, + backgroundColor: backgroundColor, + textColor: textColor, + onTap: (_) => addressListViewModel.setAddress(item), + onEdit: () => Navigator.of(context).pushNamed( + Routes.newSubaddress, + arguments: item)); + }); + } + + return index != 0 + ? cell + : ClipRRect( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(30), + topRight: Radius.circular(30)), + child: cell, + ); + }); + }), ], ), )); diff --git a/lib/src/screens/receive/widgets/address_cell.dart b/lib/src/screens/receive/widgets/address_cell.dart index cfc63a242..3f33c439e 100644 --- a/lib/src/screens/receive/widgets/address_cell.dart +++ b/lib/src/screens/receive/widgets/address_cell.dart @@ -6,7 +6,7 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_i class AddressCell extends StatelessWidget { factory AddressCell.fromItem(WalletAddressListItem item, {@required bool isCurrent, - @required bool isFirstAddress, + @required bool isPrimary, @required Color backgroundColor, @required Color textColor, Function(String) onTap, @@ -15,7 +15,7 @@ class AddressCell extends StatelessWidget { address: item.address, name: item.name, isCurrent: isCurrent, - isFirstAddress: isFirstAddress, + isPrimary: isPrimary, backgroundColor: backgroundColor, textColor: textColor, onTap: onTap, @@ -25,7 +25,7 @@ class AddressCell extends StatelessWidget { {@required this.address, @required this.name, @required this.isCurrent, - @required this.isFirstAddress, + @required this.isPrimary, @required this.backgroundColor, @required this.textColor, this.onTap, @@ -34,7 +34,7 @@ class AddressCell extends StatelessWidget { final String address; final String name; final bool isCurrent; - final bool isFirstAddress; + final bool isPrimary; final Color backgroundColor; final Color textColor; final Function(String) onTap; @@ -60,7 +60,7 @@ class AddressCell extends StatelessWidget { ), )); - return (isCurrent || isFirstAddress) + return (isCurrent || isPrimary) ? cell : Slidable( key: Key(address), diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart index de8ba1e9e..e8c897bfc 100644 --- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart @@ -67,9 +67,6 @@ abstract class WalletAddressListViewModelBase with Store { @observable String amount; - @observable - bool isFirstAddress; - @computed WalletType get type => _wallet.type; @@ -100,7 +97,6 @@ abstract class WalletAddressListViewModelBase with Store { final addressList = ObservableList(); if (wallet is MoneroWallet) { - isFirstAddress = true; addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) => WalletAddressListItem( id: subaddress.id, From b200c56c587c856eec22bf8d83cc6781d3cf7848 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Thu, 3 Dec 2020 22:47:00 +0200 Subject: [PATCH 7/7] CAKE-158 | added isPrimary property to WalletAddressListItem; removed defining primary address cell in the receive_page.dart --- lib/src/screens/receive/receive_page.dart | 150 +++++++++--------- .../screens/receive/widgets/address_cell.dart | 3 +- .../wallet_address_list_item.dart | 5 +- .../wallet_address_list_view_model.dart | 26 ++- 4 files changed, 94 insertions(+), 90 deletions(-) diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 303d2aab2..5126a1527 100644 --- a/lib/src/screens/receive/receive_page.dart +++ b/lib/src/screens/receive/receive_page.dart @@ -95,90 +95,82 @@ class ReceivePage extends BasePage { amountTextFieldFocusNode: _cryptoAmountFocus), ), Observer( - builder: (_) { - var isPrimaryAddress = true; + builder: (_) => ListView.separated( + padding: EdgeInsets.all(0), + separatorBuilder: (context, _) => Container( + height: 1, color: Theme.of(context).dividerColor), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: addressListViewModel.items.length, + itemBuilder: (context, index) { + final item = addressListViewModel.items[index]; + Widget cell = Container(); - return ListView.separated( - padding: EdgeInsets.all(0), - separatorBuilder: (context, _) => Container( - height: 1, color: Theme.of(context).dividerColor), - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemCount: addressListViewModel.items.length, - itemBuilder: (context, index) { - final item = addressListViewModel.items[index]; - Widget cell = Container(); + if (item is WalletAccountListHeader) { + cell = HeaderTile( + onTap: () async => await showPopUp( + context: context, + builder: (_) => + getIt.get()), + title: S.of(context).accounts, + icon: Icon( + Icons.arrow_forward_ios, + size: 14, + color: + Theme.of(context).textTheme.display1.color, + )); + } - if (item is WalletAccountListHeader) { - cell = HeaderTile( - onTap: () async => await showPopUp( - context: context, - builder: (_) => - getIt.get()), - title: S.of(context).accounts, - icon: Icon( - Icons.arrow_forward_ios, - size: 14, - color: - Theme.of(context).textTheme.display1.color, - )); - } + if (item is WalletAddressListHeader) { + cell = HeaderTile( + onTap: () => Navigator.of(context) + .pushNamed(Routes.newSubaddress), + title: S.of(context).addresses, + icon: Icon( + Icons.add, + size: 20, + color: + Theme.of(context).textTheme.display1.color, + )); + } - if (item is WalletAddressListHeader) { - cell = HeaderTile( - onTap: () => Navigator.of(context) - .pushNamed(Routes.newSubaddress), - title: S.of(context).addresses, - icon: Icon( - Icons.add, - size: 20, - color: - Theme.of(context).textTheme.display1.color, - )); - } + if (item is WalletAddressListItem) { + cell = Observer(builder: (_) { + final isCurrent = item.address == + addressListViewModel.address.address; + final backgroundColor = isCurrent + ? Theme.of(context) + .textTheme + .display3 + .decorationColor + : Theme.of(context) + .textTheme + .display2 + .decorationColor; + final textColor = isCurrent + ? Theme.of(context).textTheme.display3.color + : Theme.of(context).textTheme.display2.color; - if (item is WalletAddressListItem) { - final isPrimary = isPrimaryAddress; - isPrimaryAddress = false; + return AddressCell.fromItem(item, + isCurrent: isCurrent, + backgroundColor: backgroundColor, + textColor: textColor, + onTap: (_) => addressListViewModel.setAddress(item), + onEdit: () => Navigator.of(context).pushNamed( + Routes.newSubaddress, + arguments: item)); + }); + } - cell = Observer(builder: (_) { - final isCurrent = item.address == - addressListViewModel.address.address; - final backgroundColor = isCurrent - ? Theme.of(context) - .textTheme - .display3 - .decorationColor - : Theme.of(context) - .textTheme - .display2 - .decorationColor; - final textColor = isCurrent - ? Theme.of(context).textTheme.display3.color - : Theme.of(context).textTheme.display2.color; - - return AddressCell.fromItem(item, - isCurrent: isCurrent, - isPrimary: isPrimary, - backgroundColor: backgroundColor, - textColor: textColor, - onTap: (_) => addressListViewModel.setAddress(item), - onEdit: () => Navigator.of(context).pushNamed( - Routes.newSubaddress, - arguments: item)); - }); - } - - return index != 0 - ? cell - : ClipRRect( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(30), - topRight: Radius.circular(30)), - child: cell, - ); - }); - }), + return index != 0 + ? cell + : ClipRRect( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(30), + topRight: Radius.circular(30)), + child: cell, + ); + })), ], ), )); diff --git a/lib/src/screens/receive/widgets/address_cell.dart b/lib/src/screens/receive/widgets/address_cell.dart index 3f33c439e..703067dcf 100644 --- a/lib/src/screens/receive/widgets/address_cell.dart +++ b/lib/src/screens/receive/widgets/address_cell.dart @@ -6,7 +6,6 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_i class AddressCell extends StatelessWidget { factory AddressCell.fromItem(WalletAddressListItem item, {@required bool isCurrent, - @required bool isPrimary, @required Color backgroundColor, @required Color textColor, Function(String) onTap, @@ -15,7 +14,7 @@ class AddressCell extends StatelessWidget { address: item.address, name: item.name, isCurrent: isCurrent, - isPrimary: isPrimary, + isPrimary: item.isPrimary, backgroundColor: backgroundColor, textColor: textColor, onTap: onTap, diff --git a/lib/view_model/wallet_address_list/wallet_address_list_item.dart b/lib/view_model/wallet_address_list/wallet_address_list_item.dart index c6d8915ab..286cb8f94 100644 --- a/lib/view_model/wallet_address_list/wallet_address_list_item.dart +++ b/lib/view_model/wallet_address_list/wallet_address_list_item.dart @@ -2,10 +2,11 @@ import 'package:flutter/foundation.dart'; import 'package:cake_wallet/utils/list_item.dart'; class WalletAddressListItem extends ListItem { - const WalletAddressListItem({@required this.address, this.name, this.id}) - : super(); + const WalletAddressListItem({@required this.address, @required this.isPrimary, + this.name, this.id}) : super(); final int id; + final bool isPrimary; final String address; final String name; diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart index e8c897bfc..aca1ef808 100644 --- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart @@ -97,16 +97,28 @@ abstract class WalletAddressListViewModelBase with Store { final addressList = ObservableList(); if (wallet is MoneroWallet) { - addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) => - WalletAddressListItem( - id: subaddress.id, - name: subaddress.label, - address: subaddress.address))); + final primaryAddress = wallet.subaddressList.subaddresses.first; + addressList.addAll(wallet.subaddressList.subaddresses.map((subaddress) { + final isPrimary = subaddress == primaryAddress; + + return WalletAddressListItem( + id: subaddress.id, + isPrimary: isPrimary, + name: subaddress.label, + address: subaddress.address); + })); } if (wallet is BitcoinWallet) { - final bitcoinAddresses = wallet.addresses.map((addr) => - WalletAddressListItem(name: addr.label, address: addr.address)); + final primaryAddress = wallet.addresses.first; + final bitcoinAddresses = wallet.addresses.map((addr) { + final isPrimary = addr == primaryAddress; + + return WalletAddressListItem( + isPrimary: isPrimary, + name: addr.label, + address: addr.address); + }); addressList.addAll(bitcoinAddresses); }