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