From c729f86ac8521c00da799c51dcbbccb42c92d0ee Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Mon, 9 Nov 2020 17:01:58 +0200 Subject: [PATCH 01/19] CAKE-147 | changed back button image to arrow_back_ios icon with size 24; changed size of leading to 37 (base page) --- lib/src/screens/base_page.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/src/screens/base_page.dart b/lib/src/screens/base_page.dart index 440de962b..2b4ccf6c7 100644 --- a/lib/src/screens/base_page.dart +++ b/lib/src/screens/base_page.dart @@ -48,14 +48,15 @@ abstract class BasePage extends StatelessWidget { return null; } - final _backButton = Image.asset('assets/images/back_arrow.png', - color: titleColor ?? Theme.of(context).primaryTextTheme.title.color); + final _backButton = Icon(Icons.arrow_back_ios, + color: titleColor ?? Theme.of(context).primaryTextTheme.title.color, + size: 24,); final _closeButton = isDarkTheme ? _closeButtonImageDarkTheme : _closeButtonImage; return SizedBox( height: 37, - width: isModalBackButton ? 37 : 20, + width: 37, child: ButtonTheme( minWidth: double.minPositive, child: FlatButton( From c18fb9e31bcc932b025877929b1844d538ab0e98 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Wed, 11 Nov 2020 20:52:46 +0200 Subject: [PATCH 02/19] CAKE-147 | changed size of arrow_back_ios icon from 24 to 16 --- lib/src/screens/base_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/screens/base_page.dart b/lib/src/screens/base_page.dart index 2b4ccf6c7..a5bbde783 100644 --- a/lib/src/screens/base_page.dart +++ b/lib/src/screens/base_page.dart @@ -50,7 +50,7 @@ abstract class BasePage extends StatelessWidget { final _backButton = Icon(Icons.arrow_back_ios, color: titleColor ?? Theme.of(context).primaryTextTheme.title.color, - size: 24,); + size: 16,); final _closeButton = isDarkTheme ? _closeButtonImageDarkTheme : _closeButtonImage; From 7bbc14d5492ff0fb59170a857ef3b3b24649422a Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Thu, 12 Nov 2020 11:32:57 +0200 Subject: [PATCH 03/19] CAKE-171 | fixed fiat amount displaying bug on transaction list; moved calculating price, type of fiat currency and display mode to transaction list item --- lib/reactions/on_current_fiat_change.dart | 2 +- .../dashboard/dashboard_view_model.dart | 15 ++++++--------- .../dashboard/transaction_list_item.dart | 17 ++++++++++++----- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/reactions/on_current_fiat_change.dart b/lib/reactions/on_current_fiat_change.dart index 794323dc5..28c6f621c 100644 --- a/lib/reactions/on_current_fiat_change.dart +++ b/lib/reactions/on_current_fiat_change.dart @@ -13,6 +13,6 @@ void startCurrentFiatChangeReaction(AppStore appStore, SettingsStore settingsSto (_) => settingsStore.fiatCurrency, (FiatCurrency fiatCurrency) async { final cryptoCurrency = appStore.wallet.currency; fiatConversionStore.price = await FiatConversionService.fetchPrice( - cryptoCurrency, settingsStore.fiatCurrency); + cryptoCurrency, fiatCurrency); }); } \ No newline at end of file diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 500c9fb92..e76a663ec 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -78,9 +78,8 @@ abstract class DashboardViewModelBase with Store { .transactionHistory.transactions.values .map((transaction) => TransactionListItem( transaction: transaction, - price: price, - fiatCurrency: appStore.settingsStore.fiatCurrency, - displayMode: balanceDisplayMode))); + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); _reaction = reaction((_) => appStore.wallet, _onWalletChange); // FIXME: fixme @@ -89,9 +88,8 @@ abstract class DashboardViewModelBase with Store { transactions, (TransactionInfo val) => TransactionListItem( transaction: val, - price: price, - fiatCurrency: appStore.settingsStore.fiatCurrency, - displayMode: balanceDisplayMode)); + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore)); final _wallet = wallet; @@ -185,8 +183,7 @@ abstract class DashboardViewModelBase with Store { transactions.addAll(wallet.transactionHistory.transactions.values.map( (transaction) => TransactionListItem( transaction: transaction, - price: price, - fiatCurrency: appStore.settingsStore.fiatCurrency, - displayMode: balanceDisplayMode))); + balanceViewModel: balanceViewModel, + settingsStore: appStore.settingsStore))); } } diff --git a/lib/view_model/dashboard/transaction_list_item.dart b/lib/view_model/dashboard/transaction_list_item.dart index 909f22472..83477544e 100644 --- a/lib/view_model/dashboard/transaction_list_item.dart +++ b/lib/view_model/dashboard/transaction_list_item.dart @@ -1,6 +1,7 @@ import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/entities/transaction_info.dart'; +import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/utils/mobx.dart'; import 'package:cake_wallet/view_model/dashboard/action_list_item.dart'; import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart'; @@ -8,15 +9,21 @@ import 'package:cake_wallet/monero/monero_transaction_info.dart'; import 'package:cake_wallet/monero/monero_amount_format.dart'; import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart'; import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart'; +import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; class TransactionListItem extends ActionListItem with Keyable { TransactionListItem( - {this.transaction, this.price, this.fiatCurrency, this.displayMode}); + {this.transaction, this.balanceViewModel, this.settingsStore}); final TransactionInfo transaction; - final double price; - final FiatCurrency fiatCurrency; - final BalanceDisplayMode displayMode; + final BalanceViewModel balanceViewModel; + final SettingsStore settingsStore; + + double get price => balanceViewModel.price; + + FiatCurrency get fiatCurrency => settingsStore.fiatCurrency; + + BalanceDisplayMode get displayMode => settingsStore.balanceDisplayMode; @override dynamic get keyIndex => transaction.id; @@ -49,4 +56,4 @@ class TransactionListItem extends ActionListItem with Keyable { @override DateTime get date => transaction.date; -} +} \ No newline at end of file From 70467b1fe7ebca93b7ab1a5c381ef31af1ae91f7 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Thu, 12 Nov 2020 17:46:05 +0200 Subject: [PATCH 04/19] CAKE-168 | fixed blockheight calculation by date; changed getHeightByDate method; changed first date in the date picker to 1 of May, 2014 --- lib/monero/get_height_by_date.dart | 39 ++++++++----------- lib/src/widgets/blockchain_height_widget.dart | 2 +- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/lib/monero/get_height_by_date.dart b/lib/monero/get_height_by_date.dart index 3f5f87623..5393d2a32 100644 --- a/lib/monero/get_height_by_date.dart +++ b/lib/monero/get_height_by_date.dart @@ -85,34 +85,29 @@ final dates = { "2020-11": 2221803 }; +final heightCoefficient = 0.7; + int getHeigthByDate({DateTime date}) { final raw = '${date.year}' + '-' + '${date.month}'; - var endHeight = dates[raw] ?? 0; - int preLastYear = date.year; - int preLastMonth = date.month - 1; + final lastHeight = dates.values.last; + int startHeight; + int endHeight; + int height; - if (endHeight <= 0) { + if ((dates[raw] == null)||(dates[raw] == lastHeight)) { + startHeight = dates.values.toList()[dates.length - 2]; endHeight = dates.values.toList()[dates.length - 1]; - final preLastDate = - dateFormat.parse(dates.keys.elementAt(dates.keys.length - 2)); - preLastYear = preLastDate.year; - preLastMonth = preLastDate.month; + final heightPerDay = (endHeight - startHeight) / 31; + final daysHeight = (heightCoefficient * date.day * heightPerDay).round(); + height = endHeight + daysHeight; } else { - preLastYear = date.year; - preLastMonth = date.month - 1; + startHeight = dates[raw]; + final index = dates.values.toList().indexOf(startHeight); + endHeight = dates.values.toList()[index + 1]; + final heightPerDay = (endHeight - startHeight) / 31; + final daysHeight = date.day * heightPerDay.round(); + height = startHeight + daysHeight; } - if (preLastMonth <= 0) { - preLastMonth = 12; - preLastYear -= 1; - } - - final startRaw = '$preLastYear' + '-' + '$preLastMonth'; - final startHeight = dates[startRaw]; - final diff = endHeight - startHeight; - final heightPerDay = diff / 30; - final daysHeight = date.day * heightPerDay.round(); - final height = endHeight + daysHeight; - return height; } diff --git a/lib/src/widgets/blockchain_height_widget.dart b/lib/src/widgets/blockchain_height_widget.dart index 384700839..f8b22b5c4 100644 --- a/lib/src/widgets/blockchain_height_widget.dart +++ b/lib/src/widgets/blockchain_height_widget.dart @@ -92,7 +92,7 @@ class BlockchainHeightState extends State { final date = await getDate( context: context, initialDate: now.subtract(Duration(days: 1)), - firstDate: DateTime(2014, DateTime.april), + firstDate: DateTime(2014, DateTime.may), lastDate: now); if (date != null) { From 52c5d1178708934865b99cb0bb9a939ffbe5cd44 Mon Sep 17 00:00:00 2001 From: M Date: Thu, 12 Nov 2020 20:07:13 +0200 Subject: [PATCH 05/19] Fixes for biometrical auth for android --- .../com/cakewallet/cake_wallet/MainActivity.java | 15 ++++++++++++--- .../com/cakewallet/cake_wallet/MainActivity.kt | 7 +++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java index d41bd12a5..b78897919 100644 --- a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java +++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java @@ -1,6 +1,15 @@ package com.cakewallet.cake_wallet; -import io.flutter.embedding.android.FlutterActivity; +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterFragmentActivity; +import io.flutter.embedding.engine.FlutterEngine; +import io.flutter.plugins.GeneratedPluginRegistrant; -public class MainActivity extends FlutterActivity { -} + +public class MainActivity extends FlutterFragmentActivity { + + @Override + public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cakewallet/cake_wallet/MainActivity.kt b/android/app/src/main/kotlin/com/cakewallet/cake_wallet/MainActivity.kt index 3ea4c29ad..b5c933268 100644 --- a/android/app/src/main/kotlin/com/cakewallet/cake_wallet/MainActivity.kt +++ b/android/app/src/main/kotlin/com/cakewallet/cake_wallet/MainActivity.kt @@ -1,6 +1,13 @@ package com.cakewallet.cake_wallet +import androidx.annotation.NonNull; import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.android.FlutterFragmentActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterActivity() { + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine){ + GeneratedPluginRegistrant.registerWith(flutterEngine); + } } From 838368c1f44212d20df3b344fe69a43987a1a9f7 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Thu, 12 Nov 2020 21:03:57 +0200 Subject: [PATCH 06/19] CAKE-172 | added onHeightOrDateEntered function to blockchain_height_widget and called it in the restoreHeightController listener; added string resources to blockchain_height_widget; added isButtonEnabled parameter to rescan view model and wallet restore view model; added reaction on mode in the wallet restore page; applied isDisable to buttons in wallet restore page and rescan page --- lib/src/screens/rescan/rescan_page.dart | 21 +++------------ .../wallet_restore_from_keys_form.dart | 9 +++++-- .../wallet_restore_from_seed_form.dart | 7 +++-- .../screens/restore/wallet_restore_page.dart | 26 ++++++++++++++++--- lib/src/widgets/blockchain_height_widget.dart | 23 +++++++++++++++- lib/view_model/rescan_view_model.dart | 4 +++ lib/view_model/wallet_restore_view_model.dart | 4 +++ 7 files changed, 69 insertions(+), 25 deletions(-) diff --git a/lib/src/screens/rescan/rescan_page.dart b/lib/src/screens/rescan/rescan_page.dart index a1eaed7f5..f00ee685b 100644 --- a/lib/src/screens/rescan/rescan_page.dart +++ b/lib/src/screens/rescan/rescan_page.dart @@ -21,23 +21,9 @@ class RescanPage extends BasePage { padding: EdgeInsets.only(left: 24, right: 24, bottom: 24), child: Column(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Column( - children: [ - BlockchainHeightWidget(key: _blockchainHeightWidgetKey), - Padding( - padding: EdgeInsets.only(left: 40, right: 40, top: 24), - child: Text( - S.of(context).restore_from_date_or_blockheight, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: Theme.of(context).hintColor - ), - ), - ) - ], - ), + BlockchainHeightWidget(key: _blockchainHeightWidgetKey, + onHeightOrDateEntered: (value) => + _rescanViewModel.isButtonEnabled = value), Observer( builder: (_) => LoadingPrimaryButton( isLoading: @@ -51,6 +37,7 @@ class RescanPage extends BasePage { }, color: Theme.of(context).accentTextTheme.body2.color, textColor: Colors.white, + isDisabled: !_rescanViewModel.isButtonEnabled, )) ]), ); diff --git a/lib/src/screens/restore/wallet_restore_from_keys_form.dart b/lib/src/screens/restore/wallet_restore_from_keys_form.dart index 5a36b81d1..ade173d6f 100644 --- a/lib/src/screens/restore/wallet_restore_from_keys_form.dart +++ b/lib/src/screens/restore/wallet_restore_from_keys_form.dart @@ -6,7 +6,10 @@ import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; class WalletRestoreFromKeysFrom extends StatefulWidget { - WalletRestoreFromKeysFrom({Key key}) : super(key: key); + WalletRestoreFromKeysFrom({Key key, this.onHeightOrDateEntered}) + : super(key: key); + + final Function (bool) onHeightOrDateEntered; @override WalletRestoreFromKeysFromState createState() => @@ -63,7 +66,9 @@ class WalletRestoreFromKeysFromState extends State { hintText: S.of(context).restore_spend_key_private, maxLines: null)), BlockchainHeightWidget( - key: blockchainHeightKey, onHeightChange: (_) => null) + key: blockchainHeightKey, + onHeightChange: (_) => null, + onHeightOrDateEntered: widget.onHeightOrDateEntered) ]), )); } diff --git a/lib/src/screens/restore/wallet_restore_from_seed_form.dart b/lib/src/screens/restore/wallet_restore_from_seed_form.dart index ad8c4f84b..6044531d9 100644 --- a/lib/src/screens/restore/wallet_restore_from_seed_form.dart +++ b/lib/src/screens/restore/wallet_restore_from_seed_form.dart @@ -7,10 +7,12 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart'; class WalletRestoreFromSeedForm extends StatefulWidget { - WalletRestoreFromSeedForm({Key key, this.blockHeightFocusNode}) + WalletRestoreFromSeedForm({Key key, this.blockHeightFocusNode, + this.onHeightOrDateEntered}) : super(key: key); final FocusNode blockHeightFocusNode; + final Function (bool) onHeightOrDateEntered; @override WalletRestoreFromSeedFormState createState() => @@ -63,7 +65,8 @@ class WalletRestoreFromSeedFormState extends State { readOnly: true)))), BlockchainHeightWidget( focusNode: widget.blockHeightFocusNode, - key: blockchainHeightKey) + key: blockchainHeightKey, + onHeightOrDateEntered: widget.onHeightOrDateEntered) ])); } diff --git a/lib/src/screens/restore/wallet_restore_page.dart b/lib/src/screens/restore/wallet_restore_page.dart index 8b5e604e4..1a00639b6 100644 --- a/lib/src/screens/restore/wallet_restore_page.dart +++ b/lib/src/screens/restore/wallet_restore_page.dart @@ -28,8 +28,12 @@ class WalletRestorePage extends BasePage { _pages.addAll([ WalletRestoreFromSeedForm( key: walletRestoreFromSeedFormKey, - blockHeightFocusNode: _blockHeightFocusNode), - WalletRestoreFromKeysFrom(key: walletRestoreFromKeysFormKey) + blockHeightFocusNode: _blockHeightFocusNode, + onHeightOrDateEntered: (value) + => walletRestoreViewModel.isButtonEnabled = value), + WalletRestoreFromKeysFrom(key: walletRestoreFromKeysFormKey, + onHeightOrDateEntered: (value) + => walletRestoreViewModel.isButtonEnabled = value) ]); } @@ -72,6 +76,21 @@ class WalletRestorePage extends BasePage { } }); + reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) + { + walletRestoreViewModel.isButtonEnabled = false; + + walletRestoreFromSeedFormKey.currentState.blockchainHeightKey + .currentState.restoreHeightController.text = ''; + walletRestoreFromSeedFormKey.currentState.blockchainHeightKey + .currentState.dateController.text = ''; + + walletRestoreFromKeysFormKey.currentState.blockchainHeightKey + .currentState.restoreHeightController.text = ''; + walletRestoreFromKeysFormKey.currentState.blockchainHeightKey + .currentState.dateController.text = ''; + }); + return Column(mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: PageView.builder( @@ -113,7 +132,8 @@ class WalletRestorePage extends BasePage { .accentTextTheme .headline .decorationColor, - isLoading: walletRestoreViewModel.state is IsExecutingState); + isLoading: walletRestoreViewModel.state is IsExecutingState, + isDisabled: !walletRestoreViewModel.isButtonEnabled,); }, )) ]); diff --git a/lib/src/widgets/blockchain_height_widget.dart b/lib/src/widgets/blockchain_height_widget.dart index 384700839..7cf11e408 100644 --- a/lib/src/widgets/blockchain_height_widget.dart +++ b/lib/src/widgets/blockchain_height_widget.dart @@ -6,10 +6,12 @@ import 'package:cake_wallet/monero/get_height_by_date.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; class BlockchainHeightWidget extends StatefulWidget { - BlockchainHeightWidget({GlobalKey key, this.onHeightChange, this.focusNode}) + BlockchainHeightWidget({GlobalKey key, this.onHeightChange, this.focusNode, + this.onHeightOrDateEntered}) : super(key: key); final Function(int) onHeightChange; + final Function(bool) onHeightOrDateEntered; final FocusNode focusNode; @override @@ -26,6 +28,13 @@ class BlockchainHeightState extends State { @override void initState() { restoreHeightController.addListener(() { + if (restoreHeightController.text.isNotEmpty) { + widget.onHeightOrDateEntered?.call(true); + } + else { + widget.onHeightOrDateEntered?.call(false); + dateController.text = ''; + } try { _changeHeight(restoreHeightController.text != null && restoreHeightController.text.isNotEmpty @@ -83,6 +92,18 @@ class BlockchainHeightState extends State { )) ], ), + Padding( + padding: EdgeInsets.only(left: 40, right: 40, top: 24), + child: Text( + S.of(context).restore_from_date_or_blockheight, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.normal, + color: Theme.of(context).hintColor + ), + ), + ) ], ); } diff --git a/lib/view_model/rescan_view_model.dart b/lib/view_model/rescan_view_model.dart index 54df6af1a..be9477df5 100644 --- a/lib/view_model/rescan_view_model.dart +++ b/lib/view_model/rescan_view_model.dart @@ -10,12 +10,16 @@ enum RescanWalletState { rescaning, none } abstract class RescanViewModelBase with Store { RescanViewModelBase(this._wallet) { state = RescanWalletState.none; + isButtonEnabled = false; } @observable RescanWalletState state; final WalletBase _wallet; + @observable + bool isButtonEnabled; + @action Future rescanCurrentWallet({int restoreHeight}) async { state = RescanWalletState.rescaning; diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart index 4c2411a23..49dab88e4 100644 --- a/lib/view_model/wallet_restore_view_model.dart +++ b/lib/view_model/wallet_restore_view_model.dart @@ -23,6 +23,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store { Box walletInfoSource, {@required WalletType type}) : super(appStore, walletInfoSource, type: type, isRecovery: true) { + isButtonEnabled = false; mode = WalletRestoreMode.seed; _walletCreationService.changeWalletType(type: WalletType.monero); } @@ -30,6 +31,9 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store { @observable WalletRestoreMode mode; + @observable + bool isButtonEnabled; + final WalletCreationService _walletCreationService; @override From d682f6504b14438c8f20bbc20f24cd766c33e796 Mon Sep 17 00:00:00 2001 From: OleksandrSobol Date: Thu, 12 Nov 2020 21:12:58 +0200 Subject: [PATCH 07/19] CAKE-168 | fixed getHeightByDate method --- lib/monero/get_height_by_date.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/monero/get_height_by_date.dart b/lib/monero/get_height_by_date.dart index 5393d2a32..ed3d19cac 100644 --- a/lib/monero/get_height_by_date.dart +++ b/lib/monero/get_height_by_date.dart @@ -98,14 +98,14 @@ int getHeigthByDate({DateTime date}) { startHeight = dates.values.toList()[dates.length - 2]; endHeight = dates.values.toList()[dates.length - 1]; final heightPerDay = (endHeight - startHeight) / 31; - final daysHeight = (heightCoefficient * date.day * heightPerDay).round(); + final daysHeight = (heightCoefficient * (date.day - 1) * heightPerDay).round(); height = endHeight + daysHeight; } else { startHeight = dates[raw]; final index = dates.values.toList().indexOf(startHeight); endHeight = dates.values.toList()[index + 1]; final heightPerDay = (endHeight - startHeight) / 31; - final daysHeight = date.day * heightPerDay.round(); + final daysHeight = (date.day - 1) * heightPerDay.round(); height = startHeight + daysHeight; } From 4e4cd081353c5f14bc8540984130eb9f0320e182 Mon Sep 17 00:00:00 2001 From: M Date: Thu, 12 Nov 2020 22:02:37 +0200 Subject: [PATCH 08/19] Hack for display login issue --- lib/di.dart | 7 +++++++ lib/monero/monero_wallet_service.dart | 16 ++++++++-------- .../on_authentication_state_change.dart | 8 +++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/di.dart b/lib/di.dart index 9dad3efb3..1dba56bc1 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -2,12 +2,14 @@ import 'package:cake_wallet/bitcoin/bitcoin_wallet_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/entities/load_current_wallet.dart'; import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/entities/transaction_info.dart'; import 'package:cake_wallet/monero/monero_wallet_service.dart'; import 'package:cake_wallet/entities/contact.dart'; import 'package:cake_wallet/entities/node.dart'; import 'package:cake_wallet/exchange/trade.dart'; +import 'package:cake_wallet/reactions/on_authentication_state_change.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart'; @@ -199,6 +201,11 @@ Future setup( } authPageState.changeProcessText('Loading the wallet'); + + if (loginError != null) { + authPageState.changeProcessText('ERROR: ${loginError.toString()}'); + } + ReactionDisposer _reaction; _reaction = reaction((_) => appStore.wallet, (Object _) { _reaction?.reaction?.dispose(); diff --git a/lib/monero/monero_wallet_service.dart b/lib/monero/monero_wallet_service.dart index ac44147a4..91b9c184d 100644 --- a/lib/monero/monero_wallet_service.dart +++ b/lib/monero/monero_wallet_service.dart @@ -103,15 +103,15 @@ class MoneroWalletService extends WalletService< final isValid = await wallet.validate(); if (!isValid) { - if (wallet.seed?.isNotEmpty ?? false) { + // if (wallet.seed?.isNotEmpty ?? false) { // let restore from seed in this case; - final seed = wallet.seed; - final credentials = MoneroRestoreWalletFromSeedCredentials( - name: name, password: password, mnemonic: seed, height: 2000000) - ..walletInfo = walletInfo; - await remove(name); - return restoreFromSeed(credentials); - } + // final seed = wallet.seed; + // final credentials = MoneroRestoreWalletFromSeedCredentials( + // name: name, password: password, mnemonic: seed, height: 2000000) + // ..walletInfo = walletInfo; + // await remove(name); + // return restoreFromSeed(credentials); + // } throw MoneroWalletLoadingException(); } diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart index 23b314e52..20325cf5d 100644 --- a/lib/reactions/on_authentication_state_change.dart +++ b/lib/reactions/on_authentication_state_change.dart @@ -7,13 +7,19 @@ import 'package:cake_wallet/store/authentication_store.dart'; ReactionDisposer _onAuthenticationStateChange; +dynamic loginError; + void startAuthenticationStateChange(AuthenticationStore authenticationStore, @required GlobalKey navigatorKey) { _onAuthenticationStateChange ??= autorun((_) async { final state = authenticationStore.state; if (state == AuthenticationState.installed) { - await loadCurrentWallet(); + try { + await loadCurrentWallet(); + } catch(e) { + loginError = e; + } return; } From 29247967e7102d9f795ad242bceda77f7f07ee35 Mon Sep 17 00:00:00 2001 From: M Date: Thu, 12 Nov 2020 22:20:20 +0200 Subject: [PATCH 09/19] Fixes --- lib/monero/get_height_by_date.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/monero/get_height_by_date.dart b/lib/monero/get_height_by_date.dart index ed3d19cac..64ab7e05b 100644 --- a/lib/monero/get_height_by_date.dart +++ b/lib/monero/get_height_by_date.dart @@ -82,7 +82,7 @@ final dates = { "2020-8": 2153983, "2020-9": 2176466, "2020-10": 2198453, - "2020-11": 2221803 + "2020-11": 2220000 }; final heightCoefficient = 0.7; @@ -104,9 +104,9 @@ int getHeigthByDate({DateTime date}) { startHeight = dates[raw]; final index = dates.values.toList().indexOf(startHeight); endHeight = dates.values.toList()[index + 1]; - final heightPerDay = (endHeight - startHeight) / 31; - final daysHeight = (date.day - 1) * heightPerDay.round(); - height = startHeight + daysHeight; + final heightPerDay = ((endHeight - startHeight) / 31).round(); + final daysHeight = (date.day - 1) * heightPerDay; + height = startHeight + daysHeight - heightPerDay; } return height; From fcaf7b4abb25affa811c48b2229b1a34becbeb0e Mon Sep 17 00:00:00 2001 From: M Date: Thu, 12 Nov 2020 22:58:54 +0200 Subject: [PATCH 10/19] Changed app version to 4.0.5 --- ios/Runner.xcodeproj/project.pbxproj | 12 ++++++------ pubspec.yaml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 1d79b9b6f..636c01bcb 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,7 +354,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -371,7 +371,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.0.3; + MARKETING_VERSION = 4.0.5; PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -494,7 +494,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -511,7 +511,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.0.3; + MARKETING_VERSION = 4.0.5; PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -528,7 +528,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -545,7 +545,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.0.3; + MARKETING_VERSION = 4.0.5; PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/pubspec.yaml b/pubspec.yaml index 81461d475..97b2b3036 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Cake Wallet. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 4.0.4+14 +version: 4.0.5+15 environment: sdk: ">=2.7.0 <3.0.0" From ba2b5fb1fa11abf6fa9640d38cc05286d5ce384d Mon Sep 17 00:00:00 2001 From: M Date: Fri, 13 Nov 2020 16:58:28 +0200 Subject: [PATCH 11/19] Fixes issue with loading old android wallets. Changed seed text field type to visual password. --- lib/entities/pathForWallet.dart | 7 +++ lib/monero/monero_account_list.dart | 2 +- lib/monero/monero_wallet.dart | 4 +- lib/monero/monero_wallet_service.dart | 57 ++++++++++++++++--- lib/src/widgets/seed_widget.dart | 2 +- .../validable_annotated_editable_text.dart | 16 +++--- 6 files changed, 67 insertions(+), 21 deletions(-) diff --git a/lib/entities/pathForWallet.dart b/lib/entities/pathForWallet.dart index 7e21ac178..2d55c6dfa 100644 --- a/lib/entities/pathForWallet.dart +++ b/lib/entities/pathForWallet.dart @@ -19,3 +19,10 @@ Future pathForWalletDir({@required String name, @required WalletType ty Future pathForWallet({@required String name, @required WalletType type}) async => await pathForWalletDir(name: name, type: type) .then((path) => path + '/$name'); + +Future outdatedAndroidPathForWalletDir({String name}) async { + final directory = await getApplicationDocumentsDirectory(); + final pathDir = directory.path + '/$name'; + + return pathDir; +} \ No newline at end of file diff --git a/lib/monero/monero_account_list.dart b/lib/monero/monero_account_list.dart index c8522b59b..9792d3c1d 100644 --- a/lib/monero/monero_account_list.dart +++ b/lib/monero/monero_account_list.dart @@ -20,7 +20,7 @@ abstract class MoneroAccountListBase with Store { bool _isRefreshing; bool _isUpdating; - Future update() async { + void update() async { if (_isUpdating) { return; } diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index 4b9dd1cfc..2d4878b4c 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -121,8 +121,8 @@ abstract class MoneroWalletBase extends WalletBase with Store { _onAccountChangeReaction?.reaction?.dispose(); } - Future validate() async { - await accountList.update(); + bool validate() { + accountList.update(); final accountListLength = accountList.accounts?.length ?? 0; if (accountListLength <= 0) { diff --git a/lib/monero/monero_wallet_service.dart b/lib/monero/monero_wallet_service.dart index 91b9c184d..191b340e4 100644 --- a/lib/monero/monero_wallet_service.dart +++ b/lib/monero/monero_wallet_service.dart @@ -27,7 +27,7 @@ class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials { class MoneroWalletLoadingException implements Exception { @override - String toString() => 'The wallet is damaged.'; + String toString() => 'Failure to load the wallet.'; } class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials { @@ -93,6 +93,11 @@ class MoneroWalletService extends WalletService< Future openWallet(String name, String password) async { try { final path = await pathForWallet(name: name, type: WalletType.monero); + + if (!File(path).existsSync()) { + await repairOldAndroidWallet(name); + } + await monero_wallet_manager .openWalletAsync({'path': path, 'password': password}); final walletInfo = walletInfoSource.values.firstWhere( @@ -100,17 +105,17 @@ class MoneroWalletService extends WalletService< orElse: () => null); final wallet = MoneroWallet( filename: monero_wallet.getFilename(), walletInfo: walletInfo); - final isValid = await wallet.validate(); + final isValid = wallet.validate(); if (!isValid) { // if (wallet.seed?.isNotEmpty ?? false) { - // let restore from seed in this case; - // final seed = wallet.seed; - // final credentials = MoneroRestoreWalletFromSeedCredentials( - // name: name, password: password, mnemonic: seed, height: 2000000) - // ..walletInfo = walletInfo; - // await remove(name); - // return restoreFromSeed(credentials); + // let restore from seed in this case; + // final seed = wallet.seed; + // final credentials = MoneroRestoreWalletFromSeedCredentials( + // name: name, password: password, mnemonic: seed, height: 2000000) + // ..walletInfo = walletInfo; + // await remove(name); + // return restoreFromSeed(credentials); // } throw MoneroWalletLoadingException(); @@ -187,4 +192,38 @@ class MoneroWalletService extends WalletService< rethrow; } } + + Future repairOldAndroidWallet(String name) async { + try { + if (!Platform.isAndroid) { + return; + } + + final oldAndroidWalletDirPath = + await outdatedAndroidPathForWalletDir(name: name); + final dir = Directory(oldAndroidWalletDirPath); + + if (!dir.existsSync()) { + throw MoneroWalletLoadingException(); + } + + final newWalletDirPath = + await pathForWalletDir(name: name, type: WalletType.monero); + + dir.listSync().forEach((f) { + final file = File(f.path); + final name = f.path.split('/').last; + final newPath = newWalletDirPath + '/$name'; + final newFile = File(newPath); + print(file.path); + if (!newFile.existsSync()) { + newFile.createSync(); + } + newFile.writeAsBytesSync(file.readAsBytesSync()); + }); + } catch (e) { + print(e.toString()); + throw MoneroWalletLoadingException(); + } + } } diff --git a/lib/src/widgets/seed_widget.dart b/lib/src/widgets/seed_widget.dart index e444bc687..ddebbffa0 100644 --- a/lib/src/widgets/seed_widget.dart +++ b/lib/src/widgets/seed_widget.dart @@ -77,7 +77,7 @@ class SeedWidgetState extends State { fontSize: 16.0, color: Theme.of(context).hintColor))), Padding( padding: EdgeInsets.only(right: 40, top: 10), - child: ValidableAnnotatedEditableText( + child: ValidatableAnnotatedEditableText( cursorColor: Colors.blue, backgroundCursorColor: Colors.blue, validStyle: TextStyle( diff --git a/lib/src/widgets/validable_annotated_editable_text.dart b/lib/src/widgets/validable_annotated_editable_text.dart index e603c0327..37bde13a2 100644 --- a/lib/src/widgets/validable_annotated_editable_text.dart +++ b/lib/src/widgets/validable_annotated_editable_text.dart @@ -22,8 +22,8 @@ class TextAnnotation extends Comparable { int compareTo(TextAnnotation other) => text.compareTo(other.text); } -class ValidableAnnotatedEditableText extends EditableText { - ValidableAnnotatedEditableText({ +class ValidatableAnnotatedEditableText extends EditableText { + ValidatableAnnotatedEditableText({ Key key, FocusNode focusNode, TextEditingController controller, @@ -49,7 +49,7 @@ class ValidableAnnotatedEditableText extends EditableText { controller: controller, cursorColor: cursorColor, style: validStyle, - keyboardType: TextInputType.text, + keyboardType: TextInputType.visiblePassword, autocorrect: false, autofocus: false, selectionColor: selectionColor, @@ -73,14 +73,14 @@ class ValidableAnnotatedEditableText extends EditableText { final TextStyle invalidStyle; @override - ValidableAnnotatedEditableTextState createState() => - ValidableAnnotatedEditableTextState(); + ValidatableAnnotatedEditableTextState createState() => + ValidatableAnnotatedEditableTextState(); } -class ValidableAnnotatedEditableTextState extends EditableTextState { +class ValidatableAnnotatedEditableTextState extends EditableTextState { @override - ValidableAnnotatedEditableText get widget => - super.widget as ValidableAnnotatedEditableText; + ValidatableAnnotatedEditableText get widget => + super.widget as ValidatableAnnotatedEditableText; List getRanges() { final result = List(); From 99ce7c78d12b31d78bbc50395215a437fba07003 Mon Sep 17 00:00:00 2001 From: M Date: Fri, 13 Nov 2020 17:25:44 +0200 Subject: [PATCH 12/19] Changed app version to 4.0.6 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 97b2b3036..4a0bc132a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Cake Wallet. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 4.0.5+15 +version: 4.0.6+16 environment: sdk: ">=2.7.0 <3.0.0" From 4ad03e7b3387ca8191a030f3e2bf560467423b3c Mon Sep 17 00:00:00 2001 From: M Date: Fri, 13 Nov 2020 18:54:09 +0200 Subject: [PATCH 13/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 463fadfbc..1e7ebb458 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Cake Wallet -The project description, motivation, build scripts, instructions, tests will be added soon (Spring 2020); +The project description, motivation, build scripts, instructions, tests will be added soon (Spring 202X); Copyright (c) 2020 Cake Technologies LLC. From 6e24abe244ec5715b131336b765ee9157e3cf1d6 Mon Sep 17 00:00:00 2001 From: M Date: Fri, 13 Nov 2020 18:54:29 +0200 Subject: [PATCH 14/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 463fadfbc..1e7ebb458 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Cake Wallet -The project description, motivation, build scripts, instructions, tests will be added soon (Spring 2020); +The project description, motivation, build scripts, instructions, tests will be added soon (Spring 202X); Copyright (c) 2020 Cake Technologies LLC. From 70cf8f456093a3dad03e22355c74422ffac50047 Mon Sep 17 00:00:00 2001 From: M Date: Mon, 16 Nov 2020 17:00:46 +0200 Subject: [PATCH 15/19] Disabled backups for android. Changed version to 4.0.7 --- android/app/src/main/AndroidManifest.xml | 2 ++ pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 136e5ce14..4513c32f6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -6,6 +6,8 @@ =2.7.0 <3.0.0" From 6418b28c08736aef5b4ef5092e046c64ae734d1f Mon Sep 17 00:00:00 2001 From: M Date: Mon, 16 Nov 2020 20:17:03 +0200 Subject: [PATCH 16/19] CAKE-177. CAKE-176. CAKE-115. --- lib/di.dart | 3 +- lib/monero/pending_monero_transaction.dart | 21 +- lib/src/screens/auth/auth_page.dart | 14 +- lib/src/screens/receive/receive_page.dart | 196 ++++++++++-------- .../screens/receive/widgets/qr_widget.dart | 8 +- 5 files changed, 142 insertions(+), 100 deletions(-) diff --git a/lib/di.dart b/lib/di.dart index 1dba56bc1..1571c925b 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -203,7 +203,8 @@ Future setup( authPageState.changeProcessText('Loading the wallet'); if (loginError != null) { - authPageState.changeProcessText('ERROR: ${loginError.toString()}'); + authPageState + .changeProcessText('ERROR: ${loginError.toString()}'); } ReactionDisposer _reaction; diff --git a/lib/monero/pending_monero_transaction.dart b/lib/monero/pending_monero_transaction.dart index ef18a8f12..c939110a0 100644 --- a/lib/monero/pending_monero_transaction.dart +++ b/lib/monero/pending_monero_transaction.dart @@ -5,6 +5,14 @@ import 'package:cake_wallet/entities/crypto_currency.dart'; import 'package:cake_wallet/core/amount_converter.dart'; import 'package:cake_wallet/core/pending_transaction.dart'; +class DoubleSpendException implements Exception { + DoubleSpendException(); + + @override + String toString() => + 'This transaction cannot be committed. This can be due to many reasons including the wallet not being synced, there is not enough XMR in your available balance, or previous transactions are not yet fully processed.'; +} + class PendingMoneroTransaction with PendingTransaction { PendingMoneroTransaction(this.pendingTransactionDescription); @@ -22,7 +30,18 @@ class PendingMoneroTransaction with PendingTransaction { CryptoCurrency.xmr, pendingTransactionDescription.fee); @override - Future commit() async => + Future commit() async { + try { monero_transaction_history.commitTransactionFromPointerAddress( address: pendingTransactionDescription.pointerAddress); + } catch (e) { + final message = e.toString(); + + if (message.contains('Reason: double spend')) { + throw DoubleSpendException(); + } + + rethrow; + } + } } diff --git a/lib/src/screens/auth/auth_page.dart b/lib/src/screens/auth/auth_page.dart index 82d765fd6..a1e82d18e 100644 --- a/lib/src/screens/auth/auth_page.dart +++ b/lib/src/screens/auth/auth_page.dart @@ -39,14 +39,12 @@ class AuthPageState extends State { _reaction ??= reaction((_) => widget.authViewModel.state, (ExecutionState state) { if (state is ExecutedSuccessfullyState) { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (widget.onAuthenticationFinished != null) { - widget.onAuthenticationFinished(true, this); - } else { - _authBar?.dismiss(); - showBar(context, S.of(context).authenticated); - } - }); + if (widget.onAuthenticationFinished != null) { + widget.onAuthenticationFinished(true, this); + } else { + _authBar?.dismiss(); + showBar(context, S.of(context).authenticated); + } } if (state is IsExecutingState) { diff --git a/lib/src/screens/receive/receive_page.dart b/lib/src/screens/receive/receive_page.dart index 1ac4a073b..30d2b7cea 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'; @@ -15,9 +16,10 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_h import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart'; import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart'; +import 'package:keyboard_actions/keyboard_actions.dart'; class ReceivePage extends BasePage { - ReceivePage({this.addressListViewModel}); + ReceivePage({this.addressListViewModel}) : _cryptoAmountFocus = FocusNode(); final WalletAddressListViewModel addressListViewModel; @@ -33,6 +35,8 @@ class ReceivePage extends BasePage { @override Color get titleColor => Colors.white; + final FocusNode _cryptoAmountFocus; + @override Widget Function(BuildContext, Widget) get rootWrapper => (BuildContext context, Widget scaffold) => Container( @@ -67,93 +71,109 @@ class ReceivePage extends BasePage { @override Widget body(BuildContext context) { - return SingleChildScrollView( - child: Column( - children: [ - Padding( - padding: EdgeInsets.fromLTRB(24, 80, 24, 40), - child: QRWidget( - addressListViewModel: addressListViewModel, - isAmountFieldShow: true, - ), + return KeyboardActions( + config: KeyboardActionsConfig( + keyboardActionsPlatform: KeyboardActionsPlatform.IOS, + keyboardBarColor: isDarkTheme + ? Color.fromRGBO(48, 51, 60, 1.0) + : Color.fromRGBO(98, 98, 98, 1.0), + nextFocus: false, + actions: [ + KeyboardActionsItem( + focusNode: _cryptoAmountFocus, + toolbarButtons: [(_) => KeyboardDoneButton()], + ) + ]), + child: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: EdgeInsets.fromLTRB(24, 80, 24, 40), + child: QRWidget( + addressListViewModel: addressListViewModel, + isAmountFieldShow: true, + 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(); + + 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 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; + + return AddressCell.fromItem(item, + isCurrent: isCurrent, + 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, + ); + })), + ], ), - 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(); - - 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 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; - - return AddressCell.fromItem(item, - isCurrent: isCurrent, - 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/qr_widget.dart b/lib/src/screens/receive/widgets/qr_widget.dart index 46daa7f9e..ba2101d93 100644 --- a/lib/src/screens/receive/widgets/qr_widget.dart +++ b/lib/src/screens/receive/widgets/qr_widget.dart @@ -11,7 +11,9 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_v class QRWidget extends StatelessWidget { QRWidget( - {@required this.addressListViewModel, this.isAmountFieldShow = false}) + {@required this.addressListViewModel, + this.isAmountFieldShow = false, + this.amountTextFieldFocusNode}) : amountController = TextEditingController(), _formKey = GlobalKey() { amountController.addListener(() => addressListViewModel.amount = @@ -21,6 +23,7 @@ class QRWidget extends StatelessWidget { final WalletAddressListViewModel addressListViewModel; final bool isAmountFieldShow; final TextEditingController amountController; + final FocusNode amountTextFieldFocusNode; final GlobalKey _formKey; @override @@ -45,7 +48,7 @@ class QRWidget extends StatelessWidget { data: addressListViewModel.uri.toString(), backgroundColor: Colors.transparent, foregroundColor: Colors.white, - //Theme.of(context).textTheme.headline.color, + //Theme.of(context).textTheme.headline.color, ))))), Spacer(flex: 3) ]), @@ -68,6 +71,7 @@ class QRWidget extends StatelessWidget { child: Form( key: _formKey, child: BaseTextFormField( + focusNode: amountTextFieldFocusNode, controller: amountController, keyboardType: TextInputType.numberWithOptions( decimal: true), From d8ba6e411e31831ac161b1db6967aefc385ca9bc Mon Sep 17 00:00:00 2001 From: M Date: Mon, 16 Nov 2020 23:52:39 +0200 Subject: [PATCH 17/19] Changed version for iOS project to 4.0.8 (1). Updated version of flutter_secure_storage. --- ios/Runner.xcodeproj/project.pbxproj | 6 +++--- pubspec.lock | 8 ++++---- pubspec.yaml | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 636c01bcb..a32083824 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -371,7 +371,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.0.5; + MARKETING_VERSION = 4.0.8; PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -511,7 +511,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.0.5; + MARKETING_VERSION = 4.0.8; PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -545,7 +545,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - MARKETING_VERSION = 4.0.5; + MARKETING_VERSION = 4.0.8; PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/pubspec.lock b/pubspec.lock index 87132a57e..f254541af 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -401,10 +401,10 @@ packages: description: path: "." ref: cake - resolved-ref: a734c2ea3239f9153dba6f5bec740e1df54ee754 + resolved-ref: d4d68a9c1e4c45eb236cd7a5a2fac84c394a7605 url: "https://github.com/cake-tech/flutter_secure_storage.git" source: git - version: "3.3.55" + version: "3.3.57" flutter_slidable: dependency: "direct main" description: @@ -498,7 +498,7 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "2.1.18" + version: "2.1.19" intl: dependency: "direct main" description: @@ -1000,7 +1000,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "1.7.3" + version: "1.7.4" xdg_directories: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1029b5be4..0cd7f5cdf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Cake Wallet. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 4.0.7+17 +version: 4.0.8+18 environment: sdk: ">=2.7.0 <3.0.0" @@ -31,6 +31,7 @@ dependencies: git: url: https://github.com/cake-tech/flutter_secure_storage.git ref: cake + version: 3.3.57 provider: ^3.1.0 rxdart: ^0.22.2 yaml: ^2.1.16 From ce465ca622ac9f94a614252798fe78d757fbd73f Mon Sep 17 00:00:00 2001 From: M Date: Tue, 17 Nov 2020 11:00:58 +0200 Subject: [PATCH 18/19] Fixed authentication bar disapearing. Changed build version to 19 for android, 4.0.8 (2) for iOS. --- ios/Runner.xcodeproj/project.pbxproj | 6 +++--- lib/src/screens/auth/auth_page.dart | 2 +- pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a32083824..ec861d333 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,7 +354,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -494,7 +494,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -528,7 +528,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( diff --git a/lib/src/screens/auth/auth_page.dart b/lib/src/screens/auth/auth_page.dart index a1e82d18e..bb35f657b 100644 --- a/lib/src/screens/auth/auth_page.dart +++ b/lib/src/screens/auth/auth_page.dart @@ -39,10 +39,10 @@ class AuthPageState extends State { _reaction ??= reaction((_) => widget.authViewModel.state, (ExecutionState state) { if (state is ExecutedSuccessfullyState) { + _authBar?.dismiss(); if (widget.onAuthenticationFinished != null) { widget.onAuthenticationFinished(true, this); } else { - _authBar?.dismiss(); showBar(context, S.of(context).authenticated); } } diff --git a/pubspec.yaml b/pubspec.yaml index 0cd7f5cdf..5aa91cde3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Cake Wallet. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 4.0.8+18 +version: 4.0.8+19 environment: sdk: ">=2.7.0 <3.0.0" From 1afe4255a7266c985f2111480ad42a696b4a4c39 Mon Sep 17 00:00:00 2001 From: M Date: Tue, 17 Nov 2020 14:31:09 +0200 Subject: [PATCH 19/19] Another one fix for authentication bar disapearing. Changed build version to 20 for android, 4.0.8 (3) for iOS. --- ios/Runner.xcodeproj/project.pbxproj | 6 +++--- lib/src/screens/auth/auth_page.dart | 15 +++++++++------ lib/view_model/auth_view_model.dart | 2 ++ pubspec.yaml | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ec861d333..091116f43 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,7 +354,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -494,7 +494,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -528,7 +528,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( diff --git a/lib/src/screens/auth/auth_page.dart b/lib/src/screens/auth/auth_page.dart index bb35f657b..36dc2204b 100644 --- a/lib/src/screens/auth/auth_page.dart +++ b/lib/src/screens/auth/auth_page.dart @@ -39,12 +39,15 @@ class AuthPageState extends State { _reaction ??= reaction((_) => widget.authViewModel.state, (ExecutionState state) { if (state is ExecutedSuccessfullyState) { - _authBar?.dismiss(); - if (widget.onAuthenticationFinished != null) { - widget.onAuthenticationFinished(true, this); - } else { - showBar(context, S.of(context).authenticated); - } + WidgetsBinding.instance.addPostFrameCallback((_) { + _authBar?.dismiss(); + if (widget.onAuthenticationFinished != null) { + widget.onAuthenticationFinished(true, this); + } else { + showBar(context, S.of(context).authenticated); + } + }); + setState(() {}); } if (state is IsExecutingState) { diff --git a/lib/view_model/auth_view_model.dart b/lib/view_model/auth_view_model.dart index 76df95283..5bf5c25a1 100644 --- a/lib/view_model/auth_view_model.dart +++ b/lib/view_model/auth_view_model.dart @@ -110,6 +110,8 @@ abstract class AuthViewModelBase with Store { if (isAuthenticated) { state = ExecutedSuccessfullyState(); + } else { + state = FailureState('Failure biometric authentication'); } } } catch(e) { diff --git a/pubspec.yaml b/pubspec.yaml index 5aa91cde3..0634e3f2a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Cake Wallet. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 4.0.8+19 +version: 4.0.8+20 environment: sdk: ">=2.7.0 <3.0.0"