Fixes

M committed Nov 6, 2020 at 20:54 UTC b17e7744c6122e2f791692defefedcda69396d8b
12 files changed +275 -199
cw_monero/lib/wallet.dart
+9 -3
@@ -212,13 +212,14 @@ String getPublicSpendKey() =>
212 convertUTF8ToString(pointer: getPublicSpendKeyNative());
213
214 class SyncListener {
215 - SyncListener({this.onNewBlock}) {
215 + SyncListener(this.onNewBlock, this.onNewTransaction) {
216 _cachedBlockchainHeight = 0;
217 _lastKnownBlockHeight = 0;
218 _initialSyncHeight = 0;
219 }
220
221 void Function(int, int, double) onNewBlock;
222 + void Function() onNewTransaction;
223
224 Timer _updateSyncInfoTimer;
225 int _cachedBlockchainHeight;
@@ -239,6 +240,10 @@ class SyncListener {
240 _initialSyncHeight = 0;
241 _updateSyncInfoTimer ??=
242 Timer.periodic(Duration(milliseconds: 1200), (_) async {
243 + if (isNewTransactionExist() ?? false) {
244 + onNewTransaction?.call();
245 + }
246 +
247 var syncHeight = getSyncingHeight();
248
249 if (syncHeight <= 0) {
@@ -273,8 +278,9 @@ class SyncListener {
278 void stop() => _updateSyncInfoTimer?.cancel();
279 }
280
276 -SyncListener setListeners(void Function(int, int, double) onNewBlock) {
277 - final listener = SyncListener(onNewBlock: onNewBlock);
281 +SyncListener setListeners(void Function(int, int, double) onNewBlock,
282 + void Function() onNewTransaction) {
283 + final listener = SyncListener(onNewBlock, onNewTransaction);
284 setListenerNative();
285 return listener;
286 }
ios/Runner.xcodeproj/project.pbxproj
+6 -6
@@ -354,7 +354,7 @@
354 buildSettings = {
355 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
356 CLANG_ENABLE_MODULES = YES;
357 - CURRENT_PROJECT_VERSION = 17;
357 + CURRENT_PROJECT_VERSION = 2;
358 DEVELOPMENT_TEAM = 32J6BB6VUS;
359 ENABLE_BITCODE = NO;
360 FRAMEWORK_SEARCH_PATHS = (
@@ -371,7 +371,7 @@
371 "$(inherited)",
372 "$(PROJECT_DIR)/Flutter",
373 );
374 - MARKETING_VERSION = 4.0.0;
374 + MARKETING_VERSION = 4.0.1;
375 PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
376 PRODUCT_NAME = "$(TARGET_NAME)";
377 SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -494,7 +494,7 @@
494 buildSettings = {
495 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
496 CLANG_ENABLE_MODULES = YES;
497 - CURRENT_PROJECT_VERSION = 17;
497 + CURRENT_PROJECT_VERSION = 2;
498 DEVELOPMENT_TEAM = 32J6BB6VUS;
499 ENABLE_BITCODE = NO;
500 FRAMEWORK_SEARCH_PATHS = (
@@ -511,7 +511,7 @@
511 "$(inherited)",
512 "$(PROJECT_DIR)/Flutter",
513 );
514 - MARKETING_VERSION = 4.0.0;
514 + MARKETING_VERSION = 4.0.1;
515 PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
516 PRODUCT_NAME = "$(TARGET_NAME)";
517 SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -528,7 +528,7 @@
528 buildSettings = {
529 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
530 CLANG_ENABLE_MODULES = YES;
531 - CURRENT_PROJECT_VERSION = 17;
531 + CURRENT_PROJECT_VERSION = 2;
532 DEVELOPMENT_TEAM = 32J6BB6VUS;
533 ENABLE_BITCODE = NO;
534 FRAMEWORK_SEARCH_PATHS = (
@@ -545,7 +545,7 @@
545 "$(inherited)",
546 "$(PROJECT_DIR)/Flutter",
547 );
548 - MARKETING_VERSION = 4.0.0;
548 + MARKETING_VERSION = 4.0.1;
549 PRODUCT_BUNDLE_IDENTIFIER = com.fotolockr.cakewallet;
550 PRODUCT_NAME = "$(TARGET_NAME)";
551 SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
lib/core/pending_transaction.dart
+1
@@ -1,4 +1,5 @@
1 mixin PendingTransaction {
2 + String get id;
3 String get amountFormatted;
4 String get feeFormatted;
5
lib/di.dart
+13 -3
@@ -1,8 +1,9 @@
1 -
1 import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart';
2 import 'package:cake_wallet/core/wallet_service.dart';
3 import 'package:cake_wallet/entities/biometric_auth.dart';
4 import 'package:cake_wallet/entities/contact_record.dart';
5 +import 'package:cake_wallet/entities/transaction_description.dart';
6 +import 'package:cake_wallet/entities/transaction_info.dart';
7 import 'package:cake_wallet/monero/monero_wallet_service.dart';
8 import 'package:cake_wallet/entities/contact.dart';
9 import 'package:cake_wallet/entities/node.dart';
@@ -23,6 +24,7 @@ import 'package:cake_wallet/src/screens/send/send_template_page.dart';
24 import 'package:cake_wallet/src/screens/settings/change_language.dart';
25 import 'package:cake_wallet/src/screens/settings/settings.dart';
26 import 'package:cake_wallet/src/screens/setup_pin_code/setup_pin_code.dart';
27 +import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
28 import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
29 import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
30 import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
@@ -92,7 +94,8 @@ Future setup(
94 Box<Contact> contactSource,
95 Box<Trade> tradesSource,
96 Box<Template> templates,
95 - Box<ExchangeTemplate> exchangeTemplates}) async {
97 + Box<ExchangeTemplate> exchangeTemplates,
98 + Box<TransactionDescription> transactionDescriptionBox}) async {
99 getIt.registerSingletonAsync<SharedPreferences>(
100 () => SharedPreferences.getInstance());
101
@@ -230,7 +233,8 @@ Future setup(
233 getIt.get<AppStore>().wallet,
234 getIt.get<AppStore>().settingsStore,
235 getIt.get<SendTemplateStore>(),
233 - getIt.get<FiatConversionStore>()));
236 + getIt.get<FiatConversionStore>(),
237 + transactionDescriptionBox));
238
239 getIt.registerFactory(
240 () => SendPage(sendViewModel: getIt.get<SendViewModel>()));
@@ -387,4 +391,10 @@ Future setup(
391
392 getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) =>
393 WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
394 +
395 + getIt.registerFactoryParam<TransactionDetailsPage, TransactionInfo, void>(
396 + (TransactionInfo transactionInfo, _) => TransactionDetailsPage(
397 + transactionInfo,
398 + getIt.get<SettingsStore>().shouldSaveRecipientAddress,
399 + transactionDescriptionBox));
400 }
lib/main.dart
+4 -1
@@ -67,6 +67,7 @@ void main() async {
67 // fiatConvertationService: fiatConvertationService,
68 templates: templates,
69 exchangeTemplates: exchangeTemplates,
70 + transactionDescriptions: transactionDescriptions,
71 initialMigrationVersion: 4);
72 runApp(App());
73 }
@@ -80,6 +81,7 @@ Future<void> initialSetup(
81 // @required FiatConvertationService fiatConvertationService,
82 @required Box<Template> templates,
83 @required Box<ExchangeTemplate> exchangeTemplates,
84 + @required Box<TransactionDescription> transactionDescriptions,
85 int initialMigrationVersion = 5}) async {
86 await defaultSettingsMigration(
87 version: initialMigrationVersion,
@@ -94,7 +96,8 @@ Future<void> initialSetup(
96 contactSource: contactSource,
97 tradesSource: tradesSource,
98 templates: templates,
97 - exchangeTemplates: exchangeTemplates);
99 + exchangeTemplates: exchangeTemplates,
100 + transactionDescriptionBox: transactionDescriptions);
101 bootstrap(navigatorKey);
102 monero_wallet.onStartup();
103 }
lib/monero/monero_transaction_info.dart
+1
@@ -52,5 +52,6 @@ class MoneroTransactionInfo extends TransactionInfo {
52 @override
53 String fiatAmount() => _fiatAmount ?? '';
54
55 + @override
56 void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
57 }
lib/monero/monero_wallet.dart
+12 -3
@@ -237,7 +237,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
237
238 void _setListeners() {
239 _listener?.stop();
240 - _listener = monero_wallet.setListeners(_onNewBlock);
240 + _listener = monero_wallet.setListeners(_onNewBlock, _onNewTransaction);
241 }
242
243 void _setInitialHeight() {
@@ -308,14 +308,23 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
308 }
309
310 void _onNewBlock(int height, int blocksLeft, double ptc) async {
311 - _askForUpdateTransactionHistory();
311 + if (walletInfo.isRecovery) {
312 + _askForUpdateTransactionHistory();
313 + }
314 +
315 _askForUpdateBalance();
316
314 - if (blocksLeft < moneroBlockSize) {
317 + if (blocksLeft < 100) {
318 syncStatus = SyncedSyncStatus();
319 await _afterSyncSave();
320 } else {
321 syncStatus = SyncingSyncStatus(blocksLeft, ptc);
322 }
323 }
324 +
325 + void _onNewTransaction() {
326 + _askForUpdateTransactionHistory();
327 + _askForUpdateBalance();
328 + _afterSyncSave();
329 + }
330 }
lib/monero/pending_monero_transaction.dart
+3
@@ -10,6 +10,9 @@ class PendingMoneroTransaction with PendingTransaction {
10
11 final PendingTransactionDescription pendingTransactionDescription;
12
13 + @override
14 + String get id => pendingTransactionDescription.hash;
15 +
16 @override
17 String get amountFormatted => AmountConverter.amountIntToString(
18 CryptoCurrency.xmr, pendingTransactionDescription.amount);
lib/router.dart
+19 -11
@@ -1,6 +1,8 @@
1 import 'package:cake_wallet/entities/contact_record.dart';
2 +import 'package:cake_wallet/entities/transaction_description.dart';
3 import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
4 import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
5 +import 'package:cake_wallet/store/settings_store.dart';
6 import 'package:flutter/cupertino.dart';
7 import 'package:flutter/material.dart';
8 import 'package:cake_wallet/routes.dart';
@@ -49,6 +51,7 @@ import 'package:cake_wallet/src/screens/send/send_template_page.dart';
51 import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
52 import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
53 import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart';
54 +import 'package:hive/hive.dart';
55
56 Route<dynamic> createRoute(RouteSettings settings) {
57 switch (settings.name) {
@@ -57,15 +60,19 @@ Route<dynamic> createRoute(RouteSettings settings) {
60
61 case Routes.newWalletFromWelcome:
62 return CupertinoPageRoute<void>(
60 - builder: (_) => getIt.get<SetupPinCodePage>(
61 - param1: (PinCodeState<PinCodeWidget> context, dynamic _) async {
63 + builder: (_) => getIt.get<SetupPinCodePage>(param1:
64 + (PinCodeState<PinCodeWidget> context, dynamic _) async {
65 try {
63 - context.changeProcessText('Creating new wallet'); // FIXME: Unnamed constant
64 - final newWalletVM = getIt.get<WalletNewVM>(param1: WalletType.monero);
65 - await newWalletVM.create(options: 'English'); // FIXME: Unnamed constant
66 + context.changeProcessText(
67 + 'Creating new wallet'); // FIXME: Unnamed constant
68 + final newWalletVM =
69 + getIt.get<WalletNewVM>(param1: WalletType.monero);
70 + await newWalletVM.create(
71 + options: 'English'); // FIXME: Unnamed constant
72 context.hideProgressText();
67 - await Navigator.of(context.context).pushNamed(Routes.seed, arguments: true);
68 - } catch(e) {
73 + await Navigator.of(context.context)
74 + .pushNamed(Routes.seed, arguments: true);
75 + } catch (e) {
76 context.changeProcessText('Error: ${e.toString()}');
77 }
78 }),
@@ -88,7 +95,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
95 Function(PinCodeState<PinCodeWidget>, String) callback;
96
97 if (settings.arguments is Function(PinCodeState<PinCodeWidget>, String)) {
91 - callback = settings.arguments as Function(PinCodeState<PinCodeWidget>, String);
98 + callback =
99 + settings.arguments as Function(PinCodeState<PinCodeWidget>, String);
100 }
101
102 return CupertinoPageRoute<void>(
@@ -194,8 +202,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
202 case Routes.transactionDetails:
203 return CupertinoPageRoute<void>(
204 fullscreenDialog: true,
197 - builder: (_) =>
198 - TransactionDetailsPage(settings.arguments as TransactionInfo));
205 + builder: (_) => getIt.get<TransactionDetailsPage>(
206 + param1: settings.arguments as TransactionInfo));
207
208 case Routes.newSubaddress:
209 return CupertinoPageRoute<void>(
@@ -320,4 +328,4 @@ Route<dynamic> createRoute(RouteSettings settings) {
328 body: Center(
329 child: Text(S.current.router_no_route(settings.name)))));
330 }
323 -}
\ No newline at end of file
331 +}
lib/src/screens/send/send_page.dart
+168 -151
@@ -70,10 +70,11 @@ class SendPage extends BasePage {
70
71 @override
72 Widget trailing(context) => TrailButton(
73 - caption: S.of(context).clear, onPressed: () {
74 - _formKey.currentState.reset();
75 - sendViewModel.reset();
76 - });
73 + caption: S.of(context).clear,
74 + onPressed: () {
75 + _formKey.currentState.reset();
76 + sendViewModel.reset();
77 + });
78
79 @override
80 Widget body(BuildContext context) {
@@ -166,72 +167,75 @@ class SendPage extends BasePage {
167 .decorationColor),
168 validator: sendViewModel.addressValidator,
169 ),
169 - Observer(builder: (_) => Padding(
170 - padding: const EdgeInsets.only(top: 20),
171 - child: BaseTextFormField(
172 - focusNode: _cryptoAmountFocus,
173 - controller: _cryptoAmountController,
174 - keyboardType:
175 - TextInputType.numberWithOptions(
176 - signed: false, decimal: true),
177 - prefixIcon: Padding(
178 - padding: EdgeInsets.only(top: 9),
179 - child: Text(
180 - sendViewModel.currency.title + ':',
181 - style: TextStyle(
182 - fontSize: 16,
183 - fontWeight: FontWeight.w600,
184 - color: Colors.white,
185 - )),
186 - ),
187 - suffixIcon: Container(
188 - height: 32,
189 - width: 32,
190 - margin: EdgeInsets.only(
191 - left: 14, top: 4, bottom: 10),
192 - decoration: BoxDecoration(
193 - color: Theme.of(context)
194 - .primaryTextTheme
195 - .display1
196 - .color,
197 - borderRadius: BorderRadius.all(
198 - Radius.circular(6))),
199 - child: InkWell(
200 - onTap: () =>
201 - sendViewModel.setSendAll(),
202 - child: Center(
203 - child: Text(S.of(context).all,
204 - textAlign: TextAlign.center,
170 + Observer(
171 + builder: (_) => Padding(
172 + padding: const EdgeInsets.only(top: 20),
173 + child: BaseTextFormField(
174 + focusNode: _cryptoAmountFocus,
175 + controller: _cryptoAmountController,
176 + keyboardType:
177 + TextInputType.numberWithOptions(
178 + signed: false, decimal: true),
179 + prefixIcon: Padding(
180 + padding: EdgeInsets.only(top: 9),
181 + child: Text(
182 + sendViewModel.currency.title +
183 + ':',
184 style: TextStyle(
206 - fontSize: 12,
207 - fontWeight: FontWeight.bold,
208 - color: Theme.of(context)
209 - .primaryTextTheme
210 - .display1
211 - .decorationColor)),
185 + fontSize: 16,
186 + fontWeight: FontWeight.w600,
187 + color: Colors.white,
188 + )),
189 ),
213 - ),
214 - ),
215 - hintText: '0.0000',
216 - borderColor: Theme.of(context)
217 - .primaryTextTheme
218 - .headline
219 - .color,
220 - textStyle: TextStyle(
221 - fontSize: 14,
222 - fontWeight: FontWeight.w500,
223 - color: Colors.white),
224 - placeholderTextStyle: TextStyle(
225 - color: Theme.of(context)
190 + suffixIcon: Container(
191 + height: 32,
192 + width: 32,
193 + margin: EdgeInsets.only(
194 + left: 14, top: 4, bottom: 10),
195 + decoration: BoxDecoration(
196 + color: Theme.of(context)
197 + .primaryTextTheme
198 + .display1
199 + .color,
200 + borderRadius: BorderRadius.all(
201 + Radius.circular(6))),
202 + child: InkWell(
203 + onTap: () =>
204 + sendViewModel.setSendAll(),
205 + child: Center(
206 + child: Text(S.of(context).all,
207 + textAlign: TextAlign.center,
208 + style: TextStyle(
209 + fontSize: 12,
210 + fontWeight:
211 + FontWeight.bold,
212 + color: Theme.of(context)
213 + .primaryTextTheme
214 + .display1
215 + .decorationColor)),
216 + ),
217 + ),
218 + ),
219 + hintText: '0.0000',
220 + borderColor: Theme.of(context)
221 .primaryTextTheme
222 .headline
228 - .decorationColor,
229 - fontWeight: FontWeight.w500,
230 - fontSize: 14),
231 - validator:
232 - sendViewModel.sendAll
233 - ? sendViewModel.allAmountValidator
234 - : sendViewModel.amountValidator))),
223 + .color,
224 + textStyle: TextStyle(
225 + fontSize: 14,
226 + fontWeight: FontWeight.w500,
227 + color: Colors.white),
228 + placeholderTextStyle: TextStyle(
229 + color: Theme.of(context)
230 + .primaryTextTheme
231 + .headline
232 + .decorationColor,
233 + fontWeight: FontWeight.w500,
234 + fontSize: 14),
235 + validator: sendViewModel.sendAll
236 + ? sendViewModel.allAmountValidator
237 + : sendViewModel
238 + .amountValidator))),
239 Observer(
240 builder: (_) => Padding(
241 padding: EdgeInsets.only(top: 10),
@@ -423,53 +427,60 @@ class SendPage extends BasePage {
427 )),
428 ),
429 ),
426 - Observer(
427 - builder: (_) {
428 - final templates = sendViewModel.templates;
429 - final itemCount = templates.length;
430 -
431 - return ListView.builder(
432 - scrollDirection: Axis.horizontal,
433 - shrinkWrap: true,
434 - physics: NeverScrollableScrollPhysics(),
435 - itemCount: itemCount,
436 - itemBuilder: (context, index) {
437 - final template = templates[index];
438 -
439 - return TemplateTile(
440 - key: UniqueKey(),
441 - to: template.name,
442 - amount: template.amount,
443 - from: template.cryptoCurrency,
444 - onTap: () {
445 - _addressController.text = template.address;
446 - _cryptoAmountController.text = template.amount;
447 - getOpenaliasRecord(context);
448 - },
449 - onRemove: () {
450 - showPopUp<void>(
451 - context: context,
452 - builder: (dialogContext) {
453 - return AlertWithTwoActions(
454 - alertTitle: S.of(context).template,
455 - alertContent: S.of(context).confirm_delete_template,
456 - rightButtonText: S.of(context).delete,
457 - leftButtonText: S.of(context).cancel,
458 - actionRightButton: () {
459 - Navigator.of(dialogContext).pop();
460 - sendViewModel.removeTemplate(template: template);
461 - sendViewModel.updateTemplate();
462 - },
463 - actionLeftButton: () => Navigator.of(dialogContext).pop()
464 - );
465 - }
466 - );
467 - },
468 - );
469 - }
470 - );
471 - }
472 - )
430 + Observer(builder: (_) {
431 + final templates = sendViewModel.templates;
432 + final itemCount = templates.length;
433 +
434 + return ListView.builder(
435 + scrollDirection: Axis.horizontal,
436 + shrinkWrap: true,
437 + physics: NeverScrollableScrollPhysics(),
438 + itemCount: itemCount,
439 + itemBuilder: (context, index) {
440 + final template = templates[index];
441 +
442 + return TemplateTile(
443 + key: UniqueKey(),
444 + to: template.name,
445 + amount: template.amount,
446 + from: template.cryptoCurrency,
447 + onTap: () {
448 + _addressController.text =
449 + template.address;
450 + _cryptoAmountController.text =
451 + template.amount;
452 + getOpenaliasRecord(context);
453 + },
454 + onRemove: () {
455 + showPopUp<void>(
456 + context: context,
457 + builder: (dialogContext) {
458 + return AlertWithTwoActions(
459 + alertTitle:
460 + S.of(context).template,
461 + alertContent: S
462 + .of(context)
463 + .confirm_delete_template,
464 + rightButtonText:
465 + S.of(context).delete,
466 + leftButtonText:
467 + S.of(context).cancel,
468 + actionRightButton: () {
469 + Navigator.of(dialogContext)
470 + .pop();
471 + sendViewModel.removeTemplate(
472 + template: template);
473 + sendViewModel
474 + .updateTemplate();
475 + },
476 + actionLeftButton: () =>
477 + Navigator.of(dialogContext)
478 + .pop());
479 + });
480 + },
481 + );
482 + });
483 + })
484 ],
485 ),
486 ),
@@ -486,13 +497,11 @@ class SendPage extends BasePage {
497 }
498 },
499 text: S.of(context).send,
489 - color: Theme
490 - .of(context)
500 + color: Theme.of(context)
501 .accentTextTheme
502 .subtitle
503 .decorationColor,
494 - textColor: Theme
495 - .of(context)
504 + textColor: Theme.of(context)
505 .accentTextTheme
506 .headline
507 .decorationColor,
@@ -606,6 +615,10 @@ class SendPage extends BasePage {
615 return Observer(builder: (_) {
616 final state = sendViewModel.state;
617
618 + if (state is FailureState) {
619 + Navigator.of(context).pop();
620 + }
621 +
622 if (state is TransactionCommitted) {
623 return Stack(
624 children: <Widget>[
@@ -652,45 +665,49 @@ class SendPage extends BasePage {
665 );
666 }
667
655 - return Stack(
656 - children: <Widget>[
657 - Container(
658 - color: Theme.of(context).backgroundColor,
659 - child: Center(
660 - child: Image.asset(
661 - 'assets/images/birthday_cake.png'),
662 - ),
663 - ),
664 - BackdropFilter(
665 - filter: ImageFilter.blur(
666 - sigmaX: 3.0, sigmaY: 3.0),
667 - child: Container(
668 - decoration: BoxDecoration(
669 - color: Theme.of(context)
670 - .backgroundColor
671 - .withOpacity(0.25)),
668 + if (state is TransactionCommitting) {
669 + return Stack(
670 + children: <Widget>[
671 + Container(
672 + color: Theme.of(context).backgroundColor,
673 child: Center(
673 - child: Padding(
674 - padding: EdgeInsets.only(top: 220),
675 - child: Text(
676 - S.of(context).send_sending,
677 - textAlign: TextAlign.center,
678 - style: TextStyle(
679 - fontSize: 22,
680 - fontWeight: FontWeight.bold,
681 - color: Theme.of(context)
682 - .primaryTextTheme
683 - .title
684 - .color,
685 - decoration: TextDecoration.none,
674 + child: Image.asset(
675 + 'assets/images/birthday_cake.png'),
676 + ),
677 + ),
678 + BackdropFilter(
679 + filter: ImageFilter.blur(
680 + sigmaX: 3.0, sigmaY: 3.0),
681 + child: Container(
682 + decoration: BoxDecoration(
683 + color: Theme.of(context)
684 + .backgroundColor
685 + .withOpacity(0.25)),
686 + child: Center(
687 + child: Padding(
688 + padding: EdgeInsets.only(top: 220),
689 + child: Text(
690 + S.of(context).send_sending,
691 + textAlign: TextAlign.center,
692 + style: TextStyle(
693 + fontSize: 22,
694 + fontWeight: FontWeight.bold,
695 + color: Theme.of(context)
696 + .primaryTextTheme
697 + .title
698 + .color,
699 + decoration: TextDecoration.none,
700 + ),
701 ),
702 ),
703 ),
704 ),
690 - ),
691 - )
692 - ],
693 - );
705 + )
706 + ],
707 + );
708 + }
709 +
710 + return Container();
711 });
712 });
713 },
lib/src/screens/transaction_details/transaction_details_page.dart
+15 -9
@@ -1,3 +1,4 @@
1 +import 'package:cake_wallet/entities/transaction_description.dart';
2 import 'package:cake_wallet/utils/show_bar.dart';
3 import 'package:flutter/material.dart';
4 import 'package:flutter/services.dart';
@@ -9,9 +10,11 @@ import 'package:cake_wallet/src/widgets/standart_list_row.dart';
10 import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
11 import 'package:cake_wallet/src/screens/base_page.dart';
12 import 'package:cake_wallet/utils/date_formatter.dart';
13 +import 'package:hive/hive.dart';
14
15 class TransactionDetailsPage extends BasePage {
14 - TransactionDetailsPage(this.transactionInfo) : _items = [] {
16 + TransactionDetailsPage(this.transactionInfo, bool showRecipientAddress, Box<TransactionDescription> transactionDescriptionBox)
17 + : _items = [] {
18 final dateFormat = DateFormatter.withCurrentLocal();
19 final tx = transactionInfo;
20
@@ -28,15 +31,18 @@ class TransactionDetailsPage extends BasePage {
31 title: S.current.transaction_details_amount,
32 value: tx.amountFormatted())
33 ];
31 - // FIXME
32 -// if (widget.settingsStore.shouldSaveRecipientAddress &&
33 -// tx.recipientAddress != null) {
34 -// items.add(StandartListItem(
35 -// title: S.current.transaction_details_recipient_address,
36 -// value: tx.recipientAddress));
37 -// }
34
39 - if (tx.key?.isNotEmpty) {
35 + if (showRecipientAddress) {
36 + final recipientAddress = transactionDescriptionBox.values.firstWhere((val) => val.id == transactionInfo.id, orElse: () => null)?.recipientAddress;
37 +
38 + if (recipientAddress?.isNotEmpty ?? false) {
39 + items.add(StandartListItem(
40 + title: S.current.transaction_details_recipient_address,
41 + value: recipientAddress));
42 + }
43 + }
44 +
45 + if (tx.key?.isNotEmpty ?? null) {
46 // FIXME: add translation
47 items.add(StandartListItem(title: 'Transaction Key', value: tx.key));
48 }
lib/view_model/send/send_view_model.dart
+24 -12
@@ -1,3 +1,5 @@
1 +import 'package:cake_wallet/entities/transaction_description.dart';
2 +import 'package:hive/hive.dart';
3 import 'package:intl/intl.dart';
4 import 'package:mobx/mobx.dart';
5 import 'package:cake_wallet/entities/openalias_record.dart';
@@ -30,9 +32,8 @@ part 'send_view_model.g.dart';
32 class SendViewModel = SendViewModelBase with _$SendViewModel;
33
34 abstract class SendViewModelBase with Store {
33 - SendViewModelBase(
34 - this._wallet, this._settingsStore, this._sendTemplateStore,
35 - this._fiatConversationStore)
35 + SendViewModelBase(this._wallet, this._settingsStore, this._sendTemplateStore,
36 + this._fiatConversationStore, this.transactionDescriptionBox)
37 : state = InitialExecutionState(),
38 _cryptoNumberFormat = NumberFormat(),
39 sendAll = false {
@@ -101,6 +102,7 @@ abstract class SendViewModelBase with Store {
102 final SendTemplateStore _sendTemplateStore;
103 final FiatConversionStore _fiatConversationStore;
104 final NumberFormat _cryptoNumberFormat;
105 + final Box<TransactionDescription> transactionDescriptionBox;
106
107 @action
108 void setSendAll() => sendAll = true;
@@ -129,6 +131,13 @@ abstract class SendViewModelBase with Store {
131 try {
132 state = TransactionCommitting();
133 await pendingTransaction.commit();
134 +
135 + if (_settingsStore.shouldSaveRecipientAddress &&
136 + (pendingTransaction.id?.isNotEmpty ?? false)) {
137 + await transactionDescriptionBox.add(TransactionDescription(
138 + id: pendingTransaction.id, recipientAddress: address));
139 + }
140 +
141 state = TransactionCommitted();
142 } catch (e) {
143 state = FailureState(e.toString());
@@ -156,8 +165,8 @@ abstract class SendViewModelBase with Store {
165 _settingsStore.transactionPriority = priority;
166
167 Future<OpenaliasRecord> decodeOpenaliasRecord(String name) async {
159 - final record = await OpenaliasRecord
160 - .fetchAddressAndName(OpenaliasRecord.formatDomainName(name));
168 + final record = await OpenaliasRecord.fetchAddressAndName(
169 + OpenaliasRecord.formatDomainName(name));
170
171 return record.name != name ? record : null;
172 }
@@ -232,13 +241,16 @@ abstract class SendViewModelBase with Store {
241
242 void updateTemplate() => _sendTemplateStore.update();
243
235 - void addTemplate({String name, String address, String cryptoCurrency,
236 - String amount}) => _sendTemplateStore
237 - .addTemplate(
238 - name: name,
239 - address: address,
240 - cryptoCurrency: cryptoCurrency,
241 - amount: amount);
244 + void addTemplate(
245 + {String name,
246 + String address,
247 + String cryptoCurrency,
248 + String amount}) =>
249 + _sendTemplateStore.addTemplate(
250 + name: name,
251 + address: address,
252 + cryptoCurrency: cryptoCurrency,
253 + amount: amount);
254
255 void removeTemplate({Template template}) =>
256 _sendTemplateStore.remove(template: template);