1
-import 'dart:math';
2
-
3
-import 'package:auto_size_text/auto_size_text.dart';
4
-import 'package:cake_wallet/bitcoin/bitcoin.dart';
5
-import 'package:cake_wallet/generated/i18n.dart';
6
-import 'package:cake_wallet/reactions/wallet_connect.dart';
7
-import 'package:cake_wallet/routes.dart';
8
-import 'package:cake_wallet/src/screens/dashboard/pages/nft_listing_page.dart';
9
-import 'package:cake_wallet/src/screens/dashboard/widgets/home_screen_account_widget.dart';
10
-import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
11
-import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
12
-import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
13
-import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
14
-import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
15
-import 'package:cake_wallet/src/widgets/introducing_card.dart';
16
-import 'package:cake_wallet/src/widgets/standard_switch.dart';
17
-import 'package:cake_wallet/store/settings_store.dart';
18
-import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
19
-import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
20
-import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
21
-import 'package:cake_wallet/utils/feature_flag.dart';
22
-import 'package:cake_wallet/utils/payment_request.dart';
23
-import 'package:cake_wallet/utils/show_pop_up.dart';
24
-import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
25
-import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
26
-import 'package:cw_core/crypto_currency.dart';
27
-import 'package:cw_core/unspent_coin_type.dart';
28
-import 'package:flutter/material.dart';
29
-import 'package:flutter_mobx/flutter_mobx.dart';
30
-import 'package:url_launcher/url_launcher.dart';
31
-
32
-class BalancePage extends StatelessWidget {
33
- BalancePage({
34
- required this.dashboardViewModel,
35
- required this.settingsStore,
36
- required this.nftViewModel,
37
- });
38
-
39
- final DashboardViewModel dashboardViewModel;
40
- final NFTViewModel nftViewModel;
41
- final SettingsStore settingsStore;
42
-
43
- @override
44
- Widget build(BuildContext context) {
45
- return Observer(
46
- builder: (context) {
47
- final isEVMCompatible = isEVMCompatibleChain(dashboardViewModel.type);
48
- return DefaultTabController(
49
- length: isEVMCompatible ? 2 : 1,
50
- child: Column(
51
- children: [
52
- if (isEVMCompatible)
53
- Align(
54
- alignment: Alignment.centerLeft,
55
- child: Padding(
56
- padding: const EdgeInsets.only(left: 8),
57
- child: TabBar(
58
- indicatorSize: TabBarIndicatorSize.label,
59
- isScrollable: true,
60
- physics: NeverScrollableScrollPhysics(),
61
- labelStyle: TextStyle(
62
- fontSize: 18,
63
- fontFamily: 'Lato',
64
- fontWeight: FontWeight.w600,
65
- color:
66
- Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
67
- height: 1,
68
- ),
69
- unselectedLabelStyle: TextStyle(
70
- fontSize: 18,
71
- fontFamily: 'Lato',
72
- fontWeight: FontWeight.w600,
73
- color:
74
- Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
75
- height: 1,
76
- ),
77
- labelColor:
78
- Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
79
- dividerColor: Colors.transparent,
80
- indicatorColor:
81
- Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
82
- unselectedLabelColor: Theme.of(context)
83
- .extension<DashboardPageTheme>()!
84
- .pageTitleTextColor
85
- .withOpacity(0.5),
86
- tabAlignment: TabAlignment.start,
87
- tabs: [
88
- Tab(text: 'My Crypto'),
89
- Tab(text: 'My NFTs'),
90
- ],
91
- ),
92
- ),
93
- ),
94
- Expanded(
95
- child: TabBarView(
96
- physics: NeverScrollableScrollPhysics(),
97
- children: [
98
- CryptoBalanceWidget(dashboardViewModel: dashboardViewModel),
99
- if (isEVMCompatible) NFTListingPage(nftViewModel: nftViewModel)
100
- ],
101
- ),
102
- ),
103
- ],
104
- ),
105
- );
106
- },
107
- );
108
- }
109
-}
110
-
111
-class CryptoBalanceWidget extends StatelessWidget {
112
- const CryptoBalanceWidget({
113
- super.key,
114
- required this.dashboardViewModel,
115
- });
116
-
117
- final DashboardViewModel dashboardViewModel;
118
-
119
- @override
120
- Widget build(BuildContext context) {
121
- return SingleChildScrollView(
122
- child: Column(
123
- crossAxisAlignment: CrossAxisAlignment.center,
124
- children: [
125
- Observer(
126
- builder: (_) {
127
- if (dashboardViewModel.getMoneroError != null) {
128
- return Padding(
129
- padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
130
- child: DashBoardRoundedCardWidget(
131
- title: "Invalid monero bindings",
132
- subTitle: dashboardViewModel.getMoneroError.toString(),
133
- onTap: () {},
134
- ),
135
- );
136
- }
137
- return Container();
138
- },
139
- ),
140
- Observer(
141
- builder: (_) {
142
- if (dashboardViewModel.getWowneroError != null) {
143
- return Padding(
144
- padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
145
- child: DashBoardRoundedCardWidget(
146
- title: "Invalid wownero bindings",
147
- subTitle: dashboardViewModel.getWowneroError.toString(),
148
- onTap: () {},
149
- ));
150
- }
151
- return Container();
152
- },
153
- ),
154
- Observer(
155
- builder: (_) => dashboardViewModel.balanceViewModel.hasAccounts
156
- ? HomeScreenAccountWidget(
157
- walletName: dashboardViewModel.name,
158
- accountName: dashboardViewModel.subname)
159
- : Column(
160
- children: [
161
- SizedBox(height: 16),
162
- Container(
163
- margin: const EdgeInsets.only(left: 24, bottom: 16),
164
- child: Observer(
165
- builder: (_) {
166
- return Row(
167
- children: [
168
- Text(
169
- dashboardViewModel.balanceViewModel.asset,
170
- style: TextStyle(
171
- fontSize: 24,
172
- fontFamily: 'Lato',
173
- fontWeight: FontWeight.w600,
174
- color: Theme.of(context)
175
- .extension<DashboardPageTheme>()!
176
- .pageTitleTextColor,
177
- height: 1,
178
- ),
179
- maxLines: 1,
180
- textAlign: TextAlign.center,
181
- ),
182
- if (dashboardViewModel.wallet.isHardwareWallet)
183
- Padding(
184
- padding: const EdgeInsets.all(8.0),
185
- child: Image.asset(
186
- 'assets/images/hardware_wallet/ledger_nano_x.png',
187
- width: 24,
188
- color: Theme.of(context)
189
- .extension<DashboardPageTheme>()!
190
- .pageTitleTextColor,
191
- ),
192
- ),
193
- if (dashboardViewModel
194
- .balanceViewModel.isHomeScreenSettingsEnabled)
195
- InkWell(
196
- onTap: () => Navigator.pushNamed(
197
- context, Routes.homeSettings,
198
- arguments: dashboardViewModel.balanceViewModel),
199
- child: Padding(
200
- padding: const EdgeInsets.all(8.0),
201
- child: Image.asset(
202
- 'assets/images/home_screen_settings_icon.png',
203
- color: Theme.of(context)
204
- .extension<DashboardPageTheme>()!
205
- .pageTitleTextColor,
206
- ),
207
- ),
208
- ),
209
- ],
210
- );
211
- },
212
- ),
213
- ),
214
- ],
215
- )),
216
- Observer(
217
- builder: (_) {
218
- if (dashboardViewModel.balanceViewModel.isShowCard &&
219
- FeatureFlag.isCakePayEnabled) {
220
- return IntroducingCard(
221
- title: S.of(context).introducing_cake_pay,
222
- subTitle: S.of(context).cake_pay_learn_more,
223
- borderColor: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
224
- closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard);
225
- }
226
- return Container();
227
- },
228
- ),
229
- Observer(builder: (_) {
230
- if (!dashboardViewModel.showRepWarning) {
231
- return const SizedBox();
232
- }
233
- return Padding(
234
- padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
235
- child: DashBoardRoundedCardWidget(
236
- title: S.of(context).rep_warning,
237
- subTitle: S.of(context).rep_warning_sub,
238
- onTap: () => Navigator.of(context).pushNamed(Routes.changeRep),
239
- onClose: () {
240
- dashboardViewModel.settingsStore.shouldShowRepWarning = false;
241
- },
242
- ),
243
- );
244
- }),
245
- Observer(
246
- builder: (_) {
247
- return ListView.separated(
248
- physics: NeverScrollableScrollPhysics(),
249
- shrinkWrap: true,
250
- separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 8)),
251
- itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length,
252
- itemBuilder: (__, index) {
253
- final balance =
254
- dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
255
- return Observer(builder: (_) {
256
- return BalanceRowWidget(
257
- dashboardViewModel: dashboardViewModel,
258
- availableBalanceLabel:
259
- '${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
260
- availableBalance: balance.availableBalance,
261
- availableFiatBalance: balance.fiatAvailableBalance,
262
- additionalBalanceLabel:
263
- '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
264
- additionalBalance: balance.additionalBalance,
265
- additionalFiatBalance: balance.fiatAdditionalBalance,
266
- frozenBalance: balance.frozenBalance,
267
- frozenFiatBalance: balance.fiatFrozenBalance,
268
- currency: balance.asset,
269
- hasAdditionalBalance:
270
- dashboardViewModel.balanceViewModel.hasAdditionalBalance,
271
- hasSecondAdditionalBalance:
272
- dashboardViewModel.balanceViewModel.hasSecondAdditionalBalance,
273
- hasSecondAvailableBalance:
274
- dashboardViewModel.balanceViewModel.hasSecondAvailableBalance,
275
- secondAdditionalBalance: balance.secondAdditionalBalance,
276
- secondAdditionalFiatBalance: balance.fiatSecondAdditionalBalance,
277
- secondAvailableBalance: balance.secondAvailableBalance,
278
- secondAvailableFiatBalance: balance.fiatSecondAvailableBalance,
279
- secondAdditionalBalanceLabel:
280
- '${dashboardViewModel.balanceViewModel.secondAdditionalBalanceLabel}',
281
- secondAvailableBalanceLabel:
282
- '${dashboardViewModel.balanceViewModel.secondAvailableBalanceLabel}',
283
- isTestnet: dashboardViewModel.isTestnet,
284
- );
285
- });
286
- },
287
- );
288
- },
289
- ),
290
- Observer(builder: (context) {
291
- return Column(
292
- children: [
293
- if (dashboardViewModel.isMoneroWalletBrokenReasons.isNotEmpty) ...[
294
- SizedBox(height: 10),
295
- Padding(
296
- padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
297
- child: DashBoardRoundedCardWidget(
298
- customBorder: 30,
299
- title: "This wallet has encountered an issue",
300
- subTitle: "Here are the things that you should note:\n - " +
301
- dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") +
302
- "\n\nPlease restart your wallet and if it doesn't help contact our support.",
303
- onTap: () {},
304
- ))
305
- ],
306
- if (dashboardViewModel.showSilentPaymentsCard) ...[
307
- SizedBox(height: 10),
308
- Padding(
309
- padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
310
- child: DashBoardRoundedCardWidget(
311
- customBorder: 30,
312
- title: S.of(context).silent_payments,
313
- subTitle: S.of(context).enable_silent_payments_scanning,
314
- hint: Column(
315
- children: [
316
- Row(
317
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
318
- children: [
319
- GestureDetector(
320
- behavior: HitTestBehavior.opaque,
321
- onTap: () => launchUrl(
322
- Uri.parse(
323
- "https://docs.cakewallet.com/cryptos/bitcoin#silent-payments"),
324
- mode: LaunchMode.externalApplication,
325
- ),
326
- child: Row(
327
- children: [
328
- Text(
329
- S.of(context).what_is_silent_payments,
330
- style: TextStyle(
331
- fontSize: 12,
332
- fontFamily: 'Lato',
333
- fontWeight: FontWeight.w400,
334
- color: Theme.of(context)
335
- .extension<BalancePageTheme>()!
336
- .labelTextColor,
337
- height: 1,
338
- ),
339
- softWrap: true,
340
- ),
341
- Padding(
342
- padding: const EdgeInsets.symmetric(horizontal: 4),
343
- child: Icon(Icons.help_outline,
344
- size: 16,
345
- color: Theme.of(context)
346
- .extension<BalancePageTheme>()!
347
- .labelTextColor),
348
- )
349
- ],
350
- ),
351
- ),
352
- Observer(
353
- builder: (_) => StandardSwitch(
354
- value: dashboardViewModel.silentPaymentsScanningActive,
355
- onTaped: () => _toggleSilentPaymentsScanning(context),
356
- ),
357
- )
358
- ],
359
- ),
360
- ],
361
- ),
362
- onTap: () => _toggleSilentPaymentsScanning(context),
363
- icon: Icon(
364
- Icons.lock,
365
- color:
366
- Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
367
- size: 50,
368
- ),
369
- ),
370
- ),
371
- ],
372
- if (dashboardViewModel.showMwebCard) ...[
373
- SizedBox(height: 10),
374
- Padding(
375
- padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
376
- child: DashBoardRoundedCardWidget(
377
- customBorder: 30,
378
- title: S.of(context).litecoin_mweb,
379
- subTitle: S.of(context).litecoin_mweb_description,
380
- hint: Column(
381
- crossAxisAlignment: CrossAxisAlignment.start,
382
- children: [
383
- GestureDetector(
384
- behavior: HitTestBehavior.opaque,
385
- onTap: () => launchUrl(
386
- Uri.parse(
387
- "https://docs.cakewallet.com/cryptos/litecoin/#mweb"),
388
- mode: LaunchMode.externalApplication,
389
- ),
390
- child: Text(
391
- S.of(context).learn_more,
392
- style: TextStyle(
393
- fontSize: 12,
394
- fontFamily: 'Lato',
395
- fontWeight: FontWeight.w400,
396
- color: Theme.of(context)
397
- .extension<BalancePageTheme>()!
398
- .labelTextColor,
399
- height: 1,
400
- ),
401
- softWrap: true,
402
- ),
403
- ),
404
- SizedBox(height: 8),
405
- Row(
406
- children: [
407
- Expanded(
408
- child: ElevatedButton(
409
- onPressed: () => _dismissMweb(context),
410
- style: ElevatedButton.styleFrom(
411
- backgroundColor: Theme.of(context).primaryColor,
412
- ),
413
- child: Text(
414
- S.of(context).litecoin_mweb_dismiss,
415
- style: TextStyle(color: Colors.white),
416
- ),
417
- ),
418
- ),
419
- const SizedBox(width: 8),
420
- Expanded(
421
- child: ElevatedButton(
422
- onPressed: () => _enableMweb(context),
423
- style: ElevatedButton.styleFrom(
424
- backgroundColor: Colors.white,
425
- foregroundColor: Colors.black,
426
- ),
427
- child: Text(
428
- S.of(context).enable,
429
- maxLines: 1,
430
- ),
431
- ),
432
- ),
433
- ],
434
- ),
435
- ],
436
- ),
437
- onTap: () => {},
438
- icon: Container(
439
- decoration: BoxDecoration(
440
- color: Colors.white,
441
- shape: BoxShape.circle,
442
- ),
443
- child: ImageIcon(
444
- AssetImage('assets/images/mweb_logo.png'),
445
- color: Color.fromARGB(255, 11, 70, 129),
446
- size: 40,
447
- ),
448
- ),
449
- ),
450
- ),
451
- ],
452
- ],
453
- );
454
- }),
455
- ],
456
- ),
457
- );
458
- }
459
-
460
- Future<void> _toggleSilentPaymentsScanning(BuildContext context) async {
461
- final isSilentPaymentsScanningActive = dashboardViewModel.silentPaymentsScanningActive;
462
- final newValue = !isSilentPaymentsScanningActive;
463
-
464
- dashboardViewModel.silentPaymentsScanningActive = newValue;
465
-
466
- final needsToSwitch = !isSilentPaymentsScanningActive &&
467
- await bitcoin!.getNodeIsElectrsSPEnabled(dashboardViewModel.wallet) == false;
468
-
469
- if (needsToSwitch) {
470
- return showPopUp<void>(
471
- context: context,
472
- builder: (BuildContext context) => AlertWithTwoActions(
473
- alertTitle: S.of(context).change_current_node_title,
474
- alertContent: S.of(context).confirm_silent_payments_switch_node,
475
- rightButtonText: S.of(context).confirm,
476
- leftButtonText: S.of(context).cancel,
477
- actionRightButton: () {
478
- dashboardViewModel.setSilentPaymentsScanning(newValue);
479
- Navigator.of(context).pop();
480
- },
481
- actionLeftButton: () {
482
- dashboardViewModel.silentPaymentsScanningActive = isSilentPaymentsScanningActive;
483
- Navigator.of(context).pop();
484
- },
485
- ));
486
- }
487
-
488
- return dashboardViewModel.setSilentPaymentsScanning(newValue);
489
- }
490
-
491
- Future<void> _enableMweb(BuildContext context) async {
492
- if (!dashboardViewModel.hasEnabledMwebBefore) {
493
- await showPopUp<void>(
494
- context: context,
495
- builder: (BuildContext context) => AlertWithOneAction(
496
- alertTitle: S.of(context).alert_notice,
497
- alertContent: S.of(context).litecoin_mweb_warning,
498
- buttonText: S.of(context).understand,
499
- buttonAction: () {
500
- Navigator.of(context).pop();
501
- },
502
- ));
503
- }
504
- dashboardViewModel.setMwebEnabled();
505
- }
506
-
507
- Future<void> _dismissMweb(BuildContext context) async {
508
- await showPopUp<void>(
509
- context: context,
510
- builder: (BuildContext context) => AlertWithOneAction(
511
- alertTitle: S.of(context).alert_notice,
512
- alertContent: S.of(context).litecoin_mweb_enable_later,
513
- buttonText: S.of(context).understand,
514
- buttonAction: () {
515
- Navigator.of(context).pop();
516
- },
517
- ));
518
- dashboardViewModel.dismissMweb();
519
- }
520
-}
521
-
522
-class BalanceRowWidget extends StatelessWidget {
523
- BalanceRowWidget({
524
- required this.availableBalanceLabel,
525
- required this.availableBalance,
526
- required this.availableFiatBalance,
527
- required this.additionalBalanceLabel,
528
- required this.additionalBalance,
529
- required this.additionalFiatBalance,
530
- required this.secondAvailableBalanceLabel,
531
- required this.secondAvailableBalance,
532
- required this.secondAvailableFiatBalance,
533
- required this.secondAdditionalBalanceLabel,
534
- required this.secondAdditionalBalance,
535
- required this.secondAdditionalFiatBalance,
536
- required this.frozenBalance,
537
- required this.frozenFiatBalance,
538
- required this.currency,
539
- required this.hasAdditionalBalance,
540
- required this.hasSecondAvailableBalance,
541
- required this.hasSecondAdditionalBalance,
542
- required this.isTestnet,
543
- required this.dashboardViewModel,
544
- super.key,
545
- });
546
-
547
- final String availableBalanceLabel;
548
- final String availableBalance;
549
- final String availableFiatBalance;
550
- final String additionalBalanceLabel;
551
- final String additionalBalance;
552
- final String additionalFiatBalance;
553
- final String secondAvailableBalanceLabel;
554
- final String secondAvailableBalance;
555
- final String secondAvailableFiatBalance;
556
- final String secondAdditionalBalanceLabel;
557
- final String secondAdditionalBalance;
558
- final String secondAdditionalFiatBalance;
559
- final String frozenBalance;
560
- final String frozenFiatBalance;
561
- final CryptoCurrency currency;
562
- final bool hasAdditionalBalance;
563
- final bool hasSecondAvailableBalance;
564
- final bool hasSecondAdditionalBalance;
565
- final bool isTestnet;
566
- final DashboardViewModel dashboardViewModel;
567
-
568
- // void _showBalanceDescription(BuildContext context) {
569
- // showPopUp<void>(
570
- // context: context,
571
- // builder: (_) =>
572
- // InformationPage(information: S.of(context).available_balance_description),
573
- // );
574
- // }
575
-
576
- @override
577
- Widget build(BuildContext context) {
578
- return Column(children: [
579
- Container(
580
- margin: const EdgeInsets.only(left: 16, right: 16),
581
- decoration: BoxDecoration(
582
- borderRadius: BorderRadius.circular(30.0),
583
- border: Border.all(
584
- color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
585
- width: 1,
586
- ),
587
- color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
588
- ),
589
- child: Container(
590
- margin: const EdgeInsets.only(top: 16, left: 24, right: 8, bottom: 16),
591
- child: Column(
592
- crossAxisAlignment: CrossAxisAlignment.start,
593
- children: [
594
- GestureDetector(
595
- onTap: () => dashboardViewModel.balanceViewModel.switchBalanceValue(),
596
- child: Row(
597
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
598
- crossAxisAlignment: CrossAxisAlignment.center,
599
- children: [
600
- Column(
601
- crossAxisAlignment: CrossAxisAlignment.start,
602
- children: [
603
- GestureDetector(
604
- behavior: HitTestBehavior.opaque,
605
- onTap: hasAdditionalBalance
606
- ? () => _showBalanceDescription(
607
- context, S.of(context).available_balance_description)
608
- : null,
609
- child: Row(
610
- children: [
611
- Semantics(
612
- hint: 'Double tap to see more information',
613
- container: true,
614
- child: Text('${availableBalanceLabel}',
615
- style: TextStyle(
616
- fontSize: 12,
617
- fontFamily: 'Lato',
618
- fontWeight: FontWeight.w400,
619
- color: Theme.of(context)
620
- .extension<BalancePageTheme>()!
621
- .labelTextColor,
622
- height: 1)),
623
- ),
624
- if (hasAdditionalBalance)
625
- Padding(
626
- padding: const EdgeInsets.symmetric(horizontal: 4),
627
- child: Icon(Icons.help_outline,
628
- size: 16,
629
- color: Theme.of(context)
630
- .extension<BalancePageTheme>()!
631
- .labelTextColor),
632
- ),
633
- ],
634
- ),
635
- ),
636
- SizedBox(height: 6),
637
- AutoSizeText(availableBalance,
638
- style: TextStyle(
639
- fontSize: 24,
640
- fontFamily: 'Lato',
641
- fontWeight: FontWeight.w900,
642
- color: Theme.of(context)
643
- .extension<BalancePageTheme>()!
644
- .balanceAmountColor,
645
- height: 1),
646
- maxLines: 1,
647
- textAlign: TextAlign.start),
648
- SizedBox(height: 6),
649
- if (isTestnet)
650
- Text(S.of(context).testnet_coins_no_value,
651
- textAlign: TextAlign.center,
652
- style: TextStyle(
653
- fontSize: 14,
654
- fontFamily: 'Lato',
655
- fontWeight: FontWeight.w400,
656
- color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
657
- height: 1)),
658
- if (!isTestnet)
659
- Text('${availableFiatBalance}',
660
- textAlign: TextAlign.center,
661
- style: TextStyle(
662
- fontSize: 16,
663
- fontFamily: 'Lato',
664
- fontWeight: FontWeight.w500,
665
- color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
666
- height: 1)),
667
-
668
- ],
669
- ),
670
-
671
- SizedBox(
672
- width: min(MediaQuery.of(context).size.width * 0.2, 100),
673
- child: Center(
674
- child: Column(
675
- children: [
676
- CakeImageWidget(
677
- imageUrl: currency.iconPath,
678
- height: 40,
679
- width: 40,
680
- displayOnError: Container(
681
- height: 30.0,
682
- width: 30.0,
683
- child: Center(
684
- child: Text(
685
- currency.title.substring(0, min(currency.title.length, 2)),
686
- style: TextStyle(fontSize: 11),
687
- ),
688
- ),
689
- decoration: BoxDecoration(
690
- shape: BoxShape.circle,
691
- color: Colors.grey.shade400,
692
- ),
693
- ),
694
- ),
695
- const SizedBox(height: 10),
696
- Text(
697
- currency.title,
698
- style: TextStyle(
699
- fontSize: 15,
700
- fontFamily: 'Lato',
701
- fontWeight: FontWeight.w800,
702
- color:
703
- Theme.of(context).extension<BalancePageTheme>()!.assetTitleColor,
704
- height: 1,
705
- ),
706
- ),
707
- ],
708
- ),
709
- ),
710
- ),
711
- ],
712
- ),
713
- ),
714
- if (frozenBalance.isNotEmpty)
715
- GestureDetector(
716
- behavior: HitTestBehavior.opaque,
717
- onTap: hasAdditionalBalance
718
- ? () => _showBalanceDescription(
719
- context, S.of(context).unavailable_balance_description)
720
- : null,
721
- child: Column(
722
- crossAxisAlignment: CrossAxisAlignment.start,
723
- children: [
724
- SizedBox(height: 26),
725
- Row(
726
- children: [
727
- Text(
728
- S.of(context).unavailable_balance,
729
- textAlign: TextAlign.center,
730
- style: TextStyle(
731
- fontSize: 12,
732
- fontFamily: 'Lato',
733
- fontWeight: FontWeight.w400,
734
- color:
735
- Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
736
- height: 1,
737
- ),
738
- ),
739
- Padding(
740
- padding: const EdgeInsets.symmetric(horizontal: 4),
741
- child: Icon(Icons.help_outline,
742
- size: 16,
743
- color: Theme.of(context)
744
- .extension<BalancePageTheme>()!
745
- .labelTextColor),
746
- ),
747
- ],
748
- ),
749
- SizedBox(height: 8),
750
- AutoSizeText(
751
- frozenBalance,
752
- style: TextStyle(
753
- fontSize: 20,
754
- fontFamily: 'Lato',
755
- fontWeight: FontWeight.w400,
756
- color:
757
- Theme.of(context).extension<BalancePageTheme>()!.balanceAmountColor,
758
- height: 1,
759
- ),
760
- maxLines: 1,
761
- textAlign: TextAlign.center,
762
- ),
763
- SizedBox(height: 4),
764
- if (!isTestnet)
765
- Text(
766
- frozenFiatBalance,
767
- textAlign: TextAlign.center,
768
- style: TextStyle(
769
- fontSize: 12,
770
- fontFamily: 'Lato',
771
- fontWeight: FontWeight.w400,
772
- color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
773
- height: 1,
774
- ),
775
- ),
776
- ],
777
- ),
778
- ),
779
- if (hasAdditionalBalance)
780
- GestureDetector(
781
- onTap: () => dashboardViewModel.balanceViewModel.switchBalanceValue(),
782
- child: Column(
783
- crossAxisAlignment: CrossAxisAlignment.start,
784
- children: [
785
- SizedBox(height: 24),
786
- Text(
787
- '${additionalBalanceLabel}',
788
- textAlign: TextAlign.center,
789
- style: TextStyle(
790
- fontSize: 12,
791
- fontFamily: 'Lato',
792
- fontWeight: FontWeight.w400,
793
- color: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
794
- height: 1,
795
- ),
796
- ),
797
- SizedBox(height: 8),
798
- AutoSizeText(
799
- additionalBalance,
800
- style: TextStyle(
801
- fontSize: 20,
802
- fontFamily: 'Lato',
803
- fontWeight: FontWeight.w400,
804
- color: Theme.of(context).extension<BalancePageTheme>()!.assetTitleColor,
805
- height: 1,
806
- ),
807
- maxLines: 1,
808
- textAlign: TextAlign.center,
809
- ),
810
- SizedBox(height: 4),
811
- if (!isTestnet)
812
- Text(
813
- '${additionalFiatBalance}',
814
- textAlign: TextAlign.center,
815
- style: TextStyle(
816
- fontSize: 12,
817
- fontFamily: 'Lato',
818
- fontWeight: FontWeight.w400,
819
- color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
820
- height: 1,
821
- ),
822
- ),
823
- ],
824
- ),
825
- ),
826
- ],
827
- ),
828
- ),
829
- ),
830
- if (hasSecondAdditionalBalance || hasSecondAvailableBalance) ...[
831
- SizedBox(height: 10),
832
- Container(
833
- margin: const EdgeInsets.only(left: 16, right: 16),
834
- decoration: BoxDecoration(
835
- borderRadius: BorderRadius.circular(30.0),
836
- border: Border.all(
837
- color: Theme.of(context).extension<BalancePageTheme>()!.cardBorderColor,
838
- width: 1,
839
- ),
840
- color: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
841
- ),
842
- child: Container(
843
- child: Column(
844
- crossAxisAlignment: CrossAxisAlignment.start,
845
- children: [
846
- Container(
847
- margin: const EdgeInsets.only(top: 16, left: 24, right: 8, bottom: 16),
848
- child: Stack(
849
- children: [
850
- if (currency == CryptoCurrency.ltc)
851
- Row(
852
- mainAxisAlignment: MainAxisAlignment.end,
853
- children: [
854
- Container(
855
- padding: EdgeInsets.only(right: 16, top: 0),
856
- child: Column(
857
- children: [
858
- Container(
859
- child: ImageIcon(
860
- AssetImage('assets/images/mweb_logo.png'),
861
- color: Theme.of(context)
862
- .extension<BalancePageTheme>()!
863
- .assetTitleColor,
864
- size: 40,
865
- ),
866
- ),
867
- const SizedBox(height: 10),
868
- Text(
869
- 'MWEB',
870
- style: TextStyle(
871
- fontSize: 15,
872
- fontFamily: 'Lato',
873
- fontWeight: FontWeight.w800,
874
- color: Theme.of(context)
875
- .extension<BalancePageTheme>()!
876
- .assetTitleColor,
877
- height: 1,
878
- ),
879
- ),
880
- ],
881
- ),
882
- ),
883
- ],
884
- ),
885
- if (hasSecondAvailableBalance)
886
- GestureDetector(
887
- onTap: () => dashboardViewModel.balanceViewModel.switchBalanceValue(),
888
- child: Row(
889
- children: [
890
- Column(
891
- crossAxisAlignment: CrossAxisAlignment.start,
892
- children: [
893
- GestureDetector(
894
- behavior: HitTestBehavior.opaque,
895
- onTap: () => launchUrl(
896
- Uri.parse(
897
- "https://docs.cakewallet.com/cryptos/litecoin.html#mweb"),
898
- mode: LaunchMode.externalApplication,
899
- ),
900
- child: Row(
901
- children: [
902
- Text(
903
- '${secondAvailableBalanceLabel}',
904
- textAlign: TextAlign.center,
905
- style: TextStyle(
906
- fontSize: 12,
907
- fontFamily: 'Lato',
908
- fontWeight: FontWeight.w400,
909
- color: Theme.of(context)
910
- .extension<BalancePageTheme>()!
911
- .labelTextColor,
912
- height: 1,
913
- ),
914
- ),
915
- Padding(
916
- padding: const EdgeInsets.symmetric(horizontal: 4),
917
- child: Icon(Icons.help_outline,
918
- size: 16,
919
- color: Theme.of(context)
920
- .extension<BalancePageTheme>()!
921
- .labelTextColor),
922
- )
923
- ],
924
- ),
925
- ),
926
- SizedBox(height: 8),
927
- AutoSizeText(
928
- secondAvailableBalance,
929
- style: TextStyle(
930
- fontSize: 24,
931
- fontFamily: 'Lato',
932
- fontWeight: FontWeight.w900,
933
- color: Theme.of(context)
934
- .extension<BalancePageTheme>()!
935
- .assetTitleColor,
936
- height: 1,
937
- ),
938
- maxLines: 1,
939
- textAlign: TextAlign.center,
940
- ),
941
- SizedBox(height: 6),
942
- if (!isTestnet)
943
- Text(
944
- '${secondAvailableFiatBalance}',
945
- textAlign: TextAlign.center,
946
- style: TextStyle(
947
- fontSize: 16,
948
- fontFamily: 'Lato',
949
- fontWeight: FontWeight.w500,
950
- color: Theme.of(context)
951
- .extension<BalancePageTheme>()!
952
- .textColor,
953
- height: 1,
954
- ),
955
- ),
956
- ],
957
- ),
958
- ],
959
- ),
960
- ),
961
- ],
962
- ),
963
- ),
964
- Container(
965
- margin: const EdgeInsets.only(top: 0, left: 24, right: 8, bottom: 16),
966
- child: Stack(
967
- children: [
968
- if (hasSecondAdditionalBalance)
969
- Row(
970
- children: [
971
- Column(
972
- crossAxisAlignment: CrossAxisAlignment.start,
973
- children: [
974
- SizedBox(height: 24),
975
- Text(
976
- '${secondAdditionalBalanceLabel}',
977
- textAlign: TextAlign.center,
978
- style: TextStyle(
979
- fontSize: 12,
980
- fontFamily: 'Lato',
981
- fontWeight: FontWeight.w400,
982
- color: Theme.of(context)
983
- .extension<BalancePageTheme>()!
984
- .labelTextColor,
985
- height: 1,
986
- ),
987
- ),
988
- SizedBox(height: 8),
989
- AutoSizeText(
990
- secondAdditionalBalance,
991
- style: TextStyle(
992
- fontSize: 20,
993
- fontFamily: 'Lato',
994
- fontWeight: FontWeight.w400,
995
- color: Theme.of(context)
996
- .extension<BalancePageTheme>()!
997
- .assetTitleColor,
998
- height: 1,
999
- ),
1000
- maxLines: 1,
1001
- textAlign: TextAlign.center,
1002
- ),
1003
- SizedBox(height: 4),
1004
- if (!isTestnet)
1005
- Text(
1006
- '${secondAdditionalFiatBalance}',
1007
- textAlign: TextAlign.center,
1008
- style: TextStyle(
1009
- fontSize: 12,
1010
- fontFamily: 'Lato',
1011
- fontWeight: FontWeight.w400,
1012
- color: Theme.of(context)
1013
- .extension<BalancePageTheme>()!
1014
- .textColor,
1015
- height: 1,
1016
- ),
1017
- ),
1018
- ],
1019
- ),
1020
- ],
1021
- ),
1022
- ],
1023
- ),
1024
- ),
1025
- IntrinsicHeight(
1026
- child: Container(
1027
- padding: EdgeInsets.symmetric(horizontal: 24),
1028
- child: Row(
1029
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
1030
- children: [
1031
- Expanded(
1032
- child: Semantics(
1033
- label: S.of(context).litecoin_mweb_pegin,
1034
- child: OutlinedButton(
1035
- onPressed: () {
1036
- final mwebAddress =
1037
- bitcoin!.getUnusedMwebAddress(dashboardViewModel.wallet);
1038
- PaymentRequest? paymentRequest = null;
1039
- if ((mwebAddress?.isNotEmpty ?? false)) {
1040
- paymentRequest =
1041
- PaymentRequest.fromUri(Uri.parse("litecoin:${mwebAddress}"));
1042
- }
1043
- Navigator.pushNamed(
1044
- context,
1045
- Routes.send,
1046
- arguments: {
1047
- 'paymentRequest': paymentRequest,
1048
- 'coinTypeToSpendFrom': UnspentCoinType.nonMweb,
1049
- },
1050
- );
1051
- },
1052
- style: OutlinedButton.styleFrom(
1053
- backgroundColor: Colors.grey.shade400
1054
- .withAlpha(50),
1055
- side: BorderSide(color: Colors.grey.shade400
1056
- .withAlpha(50), width: 0),
1057
- shape: RoundedRectangleBorder(
1058
- borderRadius: BorderRadius.circular(20),
1059
- ),
1060
- ),
1061
- child: Container(
1062
- padding: EdgeInsets.symmetric(vertical: 12),
1063
- child: Row(
1064
- mainAxisAlignment: MainAxisAlignment.center,
1065
- children: [
1066
- Image.asset(
1067
- height: 30,
1068
- width: 30,
1069
- 'assets/images/received.png',
1070
- color: Theme.of(context)
1071
- .extension<BalancePageTheme>()!
1072
- .balanceAmountColor,
1073
- ),
1074
- const SizedBox(width: 8),
1075
- Text(
1076
- S.of(context).litecoin_mweb_pegin,
1077
- style: TextStyle(
1078
- color: Theme.of(context)
1079
- .extension<BalancePageTheme>()!
1080
- .textColor,
1081
- ),
1082
- ),
1083
- ],
1084
- ),
1085
- ),
1086
- ),
1087
- ),
1088
- ),
1089
- SizedBox(width: 24),
1090
- Expanded(
1091
- child: Semantics(
1092
- label: S.of(context).litecoin_mweb_pegout,
1093
- child: OutlinedButton(
1094
- onPressed: () {
1095
- final litecoinAddress =
1096
- bitcoin!.getUnusedSegwitAddress(dashboardViewModel.wallet);
1097
- PaymentRequest? paymentRequest = null;
1098
- if ((litecoinAddress?.isNotEmpty ?? false)) {
1099
- paymentRequest = PaymentRequest.fromUri(
1100
- Uri.parse("litecoin:${litecoinAddress}"));
1101
- }
1102
- Navigator.pushNamed(
1103
- context,
1104
- Routes.send,
1105
- arguments: {
1106
- 'paymentRequest': paymentRequest,
1107
- 'coinTypeToSpendFrom': UnspentCoinType.mweb,
1108
- },
1109
- );
1110
- },
1111
- style: OutlinedButton.styleFrom(
1112
- backgroundColor: Colors.grey.shade400
1113
- .withAlpha(50),
1114
- side: BorderSide(color: Colors.grey.shade400
1115
- .withAlpha(50), width: 0),
1116
- shape: RoundedRectangleBorder(
1117
- borderRadius: BorderRadius.circular(20),
1118
- ),
1119
- ),
1120
- child: Container(
1121
- padding: EdgeInsets.symmetric(vertical: 12),
1122
- child: Row(
1123
- mainAxisAlignment: MainAxisAlignment.center,
1124
- children: [
1125
- Image.asset(
1126
- height: 30,
1127
- width: 30,
1128
- 'assets/images/upload.png',
1129
- color: Theme.of(context)
1130
- .extension<BalancePageTheme>()!
1131
- .balanceAmountColor,
1132
- ),
1133
- const SizedBox(width: 8),
1134
- Text(
1135
- S.of(context).litecoin_mweb_pegout,
1136
- style: TextStyle(
1137
- color: Theme.of(context)
1138
- .extension<BalancePageTheme>()!
1139
- .textColor,
1140
- ),
1141
- ),
1142
- ],
1143
- ),
1144
- ),
1145
- ),
1146
- ),
1147
- ),
1148
- ],
1149
- ),
1150
- ),
1151
- ),
1152
- SizedBox(height: 16),
1153
- ],
1154
- ),
1155
- ),
1156
- ),
1157
- ],
1158
- ]);
1159
- }
1160
-
1161
- void _showBalanceDescription(BuildContext context, String content) {
1162
- showPopUp<void>(context: context, builder: (_) => InformationPage(information: content));
1163
- }
1164
-}