CAKE-329 | reworked unspent_coins_list_page.dart and unspent_coins_list_item.dart; fixed standard_checkbox.dart; applied unspent coins control only to btc wallet
OleksandrSobol committed
May 31, 2021 at 21:04 UTC
b1add664ad5b762618190c3ad8e9e5f4c24600bf
7 files changed
+209
-118
lib/palette.dart
+1
@@ -44,6 +44,7 @@ class Palette {
44
static const Color dullGray = Color.fromRGBO(98, 98, 98, 1.0);
45
static const Color protectiveBlue = Color.fromRGBO(33, 148, 255, 1.0);
46
static const Color darkBlue = Color.fromRGBO(109, 128, 178, 1.0);
47
+ static const Color paleCornflowerBlue = Color.fromRGBO(185, 196, 237, 1.0);
48
}
49
50
class PaletteDark {
lib/src/screens/send/send_page.dart
+41
-30
@@ -425,7 +425,31 @@ class SendPage extends BasePage {
425
],
426
),
427
),
428
- ))
428
+ )),
429
+ if (sendViewModel.isBitcoinWallet) Padding(
430
+ padding: EdgeInsets.only(top: 6),
431
+ child: GestureDetector(
432
+ onTap: () => Navigator.of(context)
433
+ .pushNamed(Routes.unspentCoinsList),
434
+ child: Row(
435
+ mainAxisAlignment:
436
+ MainAxisAlignment.spaceBetween,
437
+ children: [
438
+ Text(
439
+ 'Coin control (optional)',
440
+ style: TextStyle(
441
+ fontSize: 12,
442
+ fontWeight: FontWeight.w600,
443
+ color: Colors.white)),
444
+ Icon(
445
+ Icons.arrow_forward_ios,
446
+ size: 12,
447
+ color: Colors.white,
448
+ )
449
+ ],
450
+ )
451
+ )
452
+ )
453
],
454
),
455
)
@@ -558,35 +582,22 @@ class SendPage extends BasePage {
582
),
583
bottomSectionPadding:
584
EdgeInsets.only(left: 24, right: 24, bottom: 24),
561
- bottomSection: Column(
562
- children: [
563
- Observer(builder: (_) {
564
- return LoadingPrimaryButton(
565
- onPressed: () async {
566
- if (_formKey.currentState.validate()) {
567
- await sendViewModel.createTransaction();
568
- }
569
- },
570
- text: S.of(context).send,
571
- color: Theme.of(context).accentTextTheme.body2.color,
572
- textColor: Colors.white,
573
- isLoading: sendViewModel.state is IsExecutingState ||
574
- sendViewModel.state is TransactionCommitting,
575
- isDisabled:
576
- false // FIXME !(syncStore.status is SyncedSyncStatus),
577
- );
578
- }),
579
- Padding(
580
- padding: EdgeInsets.only(top: 12),
581
- child: PrimaryButton(
582
- onPressed: () => Navigator.of(context).pushNamed(Routes.unspentCoinsList),
583
- text: 'Unspent coins',
584
- color: Colors.green,
585
- textColor: Colors.white,
586
- )
587
- )
588
- ],
589
- )),
585
+ bottomSection: Observer(builder: (_) {
586
+ return LoadingPrimaryButton(
587
+ onPressed: () async {
588
+ if (_formKey.currentState.validate()) {
589
+ await sendViewModel.createTransaction();
590
+ }
591
+ },
592
+ text: S.of(context).send,
593
+ color: Theme.of(context).accentTextTheme.body2.color,
594
+ textColor: Colors.white,
595
+ isLoading: sendViewModel.state is IsExecutingState ||
596
+ sendViewModel.state is TransactionCommitting,
597
+ isDisabled:
598
+ false // FIXME !(syncStore.status is SyncedSyncStatus),
599
+ );
600
+ })),
601
));
602
}
603
lib/src/screens/unspent_coins/unspent_coins_list_page.dart
+52
-18
@@ -1,10 +1,12 @@
1
import 'package:cake_wallet/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart';
2
-import 'package:cake_wallet/src/widgets/standard_list.dart';
2
+import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
3
+import 'package:cake_wallet/utils/show_pop_up.dart';
4
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
5
import 'package:flutter/material.dart';
6
import 'package:flutter/cupertino.dart';
7
import 'package:cake_wallet/src/screens/base_page.dart';
8
import 'package:flutter_mobx/flutter_mobx.dart';
9
+import 'package:cake_wallet/generated/i18n.dart';
10
11
class UnspentCoinsListPage extends BasePage {
12
UnspentCoinsListPage({this.unspentCoinsListViewModel});
@@ -12,27 +14,59 @@ class UnspentCoinsListPage extends BasePage {
14
@override
15
String get title => 'Unspent coins';
16
17
+ @override
18
+ Widget trailing(BuildContext context) {
19
+ final questionImage = Image.asset('assets/images/question_mark.png',
20
+ color: Theme.of(context).primaryTextTheme.title.color);
21
+
22
+ return SizedBox(
23
+ height: 20.0,
24
+ width: 20.0,
25
+ child: ButtonTheme(
26
+ minWidth: double.minPositive,
27
+ child: FlatButton(
28
+ highlightColor: Colors.transparent,
29
+ splashColor: Colors.transparent,
30
+ padding: EdgeInsets.all(0),
31
+ onPressed: () => showPopUp<void>(
32
+ context: context,
33
+ builder: (BuildContext context) {
34
+ return AlertWithOneAction(
35
+ alertTitle: '',
36
+ alertContent: 'Information about unspent coins',
37
+ buttonText: S.of(context).ok,
38
+ buttonAction: () => Navigator.of(context).pop());
39
+ }),
40
+ child: questionImage),
41
+ ),
42
+ );
43
+ }
44
+
45
final UnspentCoinsListViewModel unspentCoinsListViewModel;
46
47
@override
48
Widget body(BuildContext context) {
19
- return Observer(builder: (_) => SectionStandardList(
20
- sectionCount: 1,
21
- itemCounter: (int _) => unspentCoinsListViewModel.items.length,
22
- itemBuilder: (_, __, index) {
23
- final item = unspentCoinsListViewModel.items[index];
49
+ return Container(
50
+ padding: EdgeInsets.fromLTRB(24, 12, 24, 24),
51
+ child: Observer(
52
+ builder: (_) => ListView.separated(
53
+ itemCount: unspentCoinsListViewModel.items.length,
54
+ separatorBuilder: (_, __) =>
55
+ SizedBox(height: 15),
56
+ itemBuilder: (_, int index) {
57
+ final item = unspentCoinsListViewModel.items[index];
58
25
- return GestureDetector(
26
- onTap: () {print('Item taped');},
27
- child: UnspentCoinsListItem(
28
- address: item.address,
29
- amount: item.amount,
30
- isFrozen: item.isFrozen,
31
- note: item.note,
32
- isSending: item.isSending,
33
- onCheckBoxTap: (value) {print('CheckBox taped');},
34
- ));
35
- }));
59
+ return GestureDetector(
60
+ onTap: () {print('Item taped');},
61
+ child: UnspentCoinsListItem(
62
+ address: item.address,
63
+ amount: item.amount,
64
+ isSending: item.isSending,
65
+ onCheckBoxTap: (value) {},
66
+ ));
67
+ }
68
+ )
69
+ )
70
+ );
71
}
37
-
72
}
\ No newline at end of file
lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
+74
-47
@@ -1,74 +1,101 @@
1
import 'package:auto_size_text/auto_size_text.dart';
2
+import 'package:cake_wallet/palette.dart';
3
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
4
import 'package:flutter/material.dart';
5
import 'package:flutter/cupertino.dart';
6
6
-class UnspentCoinsListItem extends StatelessWidget {
7
+class UnspentCoinsListItem extends StatefulWidget {
8
UnspentCoinsListItem({
9
@required this.address,
10
@required this.amount,
10
- @required this.isFrozen,
11
- @required this.note,
11
@required this.isSending,
12
@required this.onCheckBoxTap,
14
-});
13
+ });
14
15
final String address;
16
final String amount;
18
- final bool isFrozen;
19
- final String note;
17
final bool isSending;
18
final Function(bool) onCheckBoxTap;
19
20
+ @override UnspentCoinsListItemState createState() =>
21
+ UnspentCoinsListItemState(
22
+ address: address,
23
+ amount: amount,
24
+ isSending: isSending,
25
+ onCheckBoxTap: onCheckBoxTap
26
+ );
27
+
28
+}
29
+
30
+class UnspentCoinsListItemState extends State<UnspentCoinsListItem> {
31
+ UnspentCoinsListItemState({
32
+ @required this.address,
33
+ @required this.amount,
34
+ @required this.isSending,
35
+ @required this.onCheckBoxTap,
36
+ }) : checkBoxValue = isSending;
37
+
38
+ static const amountColor = Palette.darkBlueCraiola;
39
+ static const addressColor = Palette.darkGray;
40
+ static const selectedItemColor = Palette.paleCornflowerBlue;
41
+ static const unselectedItemColor = Palette.moderateLavender;
42
+
43
+ final String address;
44
+ final String amount;
45
+ final bool isSending;
46
+ final Function(bool) onCheckBoxTap;
47
+
48
+ bool checkBoxValue;
49
+
50
@override
51
Widget build(BuildContext context) {
25
- final textStyle = TextStyle(
26
- fontSize: 16,
27
- fontWeight: FontWeight.w500,
28
- color: Theme.of(context)
29
- .primaryTextTheme
30
- .title
31
- .color);
52
+ final itemColor = checkBoxValue? selectedItemColor : unselectedItemColor;
53
54
return Container(
34
- padding: EdgeInsets.fromLTRB(24, 16, 24, 16),
35
- color: Theme.of(context).backgroundColor,
36
- child: Column(
37
- crossAxisAlignment: CrossAxisAlignment.start,
55
+ height: 62,
56
+ padding: EdgeInsets.all(12),
57
+ decoration: BoxDecoration(
58
+ borderRadius: BorderRadius.all(Radius.circular(12)),
59
+ color: itemColor),
60
+ child: Row(
61
+ mainAxisSize: MainAxisSize.max,
62
+ crossAxisAlignment: CrossAxisAlignment.center,
63
children: [
39
- Text(
40
- address ?? 'Address',
41
- style: textStyle,
42
- ),
43
- Padding(
44
- padding: EdgeInsets.only(top: 12),
45
- child: Text(
46
- amount ?? 'Amount',
47
- style: textStyle,
48
- )
49
- ),
50
- if (isFrozen ?? false) Padding(
51
- padding: EdgeInsets.only(top: 12),
52
- child: Text(
53
- 'Freeze',
54
- style: textStyle,
55
- )
56
- ),
57
- if (note?.isNotEmpty ?? false) Padding(
58
- padding: EdgeInsets.only(top: 12),
59
- child: AutoSizeText(
60
- note,
61
- style: textStyle,
62
- maxLines: 1
63
- )
64
- ),
64
Padding(
66
- padding: EdgeInsets.only(top: 12),
65
+ padding: EdgeInsets.only(right: 12),
66
child: StandardCheckbox(
68
- value: isSending,
69
- caption: 'Sending',
70
- onChanged: onCheckBoxTap
67
+ value: checkBoxValue,
68
+ onChanged: (value) {
69
+ onCheckBoxTap(value);
70
+ checkBoxValue = value;
71
+ setState(() {});
72
+ }
73
)
74
+ ),
75
+ Expanded(
76
+ child: Column(
77
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
78
+ crossAxisAlignment: CrossAxisAlignment.start,
79
+ children: [
80
+ AutoSizeText(
81
+ amount ?? 'Amount',
82
+ style: TextStyle(
83
+ color: amountColor,
84
+ fontSize: 16,
85
+ fontWeight: FontWeight.w600
86
+ ),
87
+ maxLines: 1,
88
+ ),
89
+ AutoSizeText(
90
+ address ?? 'Address',
91
+ style: TextStyle(
92
+ color: addressColor,
93
+ fontSize: 12,
94
+ ),
95
+ maxLines: 1,
96
+ )
97
+ ]
98
+ )
99
)
100
],
101
)
lib/src/widgets/standard_checkbox.dart
+11
-11
@@ -44,9 +44,6 @@ class StandardCheckboxState extends State<StandardCheckbox> {
44
Container(
45
height: 24.0,
46
width: 24.0,
47
- margin: EdgeInsets.only(
48
- right: 10.0,
49
- ),
47
decoration: BoxDecoration(
48
border: Border.all(
49
color: Theme.of(context)
@@ -65,14 +62,17 @@ class StandardCheckboxState extends State<StandardCheckbox> {
62
)
63
: Offstage(),
64
),
68
- Text(
69
- caption,
70
- style: TextStyle(
71
- fontSize: 16.0,
72
- color: Theme.of(context)
73
- .primaryTextTheme
74
- .title
75
- .color),
65
+ if (caption.isNotEmpty) Padding(
66
+ padding: EdgeInsets.only(left: 10),
67
+ child: Text(
68
+ caption,
69
+ style: TextStyle(
70
+ fontSize: 16.0,
71
+ color: Theme.of(context)
72
+ .primaryTextTheme
73
+ .title
74
+ .color),
75
+ )
76
)
77
],
78
),
lib/view_model/send/send_view_model.dart
+5
@@ -55,6 +55,8 @@ abstract class SendViewModelBase with Store {
55
_settingsStore.priority[_wallet.type] = priorities.first;
56
}
57
58
+ isBitcoinWallet = _wallet is BitcoinWallet;
59
+
60
_setCryptoNumMaximumFractionDigits();
61
}
62
@@ -182,6 +184,9 @@ abstract class SendViewModelBase with Store {
184
@observable
185
PendingTransaction pendingTransaction;
186
187
+ @observable
188
+ bool isBitcoinWallet;
189
+
190
@computed
191
String get balance => _wallet.balance.formattedAvailableBalance ?? '0.0';
192
lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
+25
-12
@@ -5,32 +5,45 @@ part 'unspent_coins_list_view_model.g.dart';
5
6
const List<Map<String, dynamic>> unspentCoinsMap = [
7
<String, dynamic>{
8
- "address" : "11111111111111121111132432432432432432432443124324324234324324324324332424",
9
- "amount" : "222",
8
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
9
+ "amount" : "0.00358 BTC",
10
"isFrozen" : true,
11
"note" : "333cvgf23132132132132131321321314rwrtdggfdddewq ewqasfdxgdhgfgfszczcxgbhhhbcgbc"},
12
<String, dynamic>{
13
- "address" : "444",
14
- "amount" : "555",
13
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
14
+ "amount" : "0.00567894 BTC",
15
"note" : "sfjskf"},
16
<String, dynamic>{
17
- "address" : "777",
18
- "amount" : "888",
17
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
18
+ "amount" : "0.00087 BTC",
19
"isFrozen" : false},
20
<String, dynamic>{
21
- "address" : "11111111111111121111132432432432432432432443124324324234324324324324332424",
22
- "amount" : "222",
21
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
22
+ "amount" : "0.00012 BTC",
23
"isFrozen" : true,
24
"note" : "333cvgf23132132132132131321321314rwrtdggfdddewq ewqasfdxgdhgfgfszczcxgbhhhbcgbc"},
25
<String, dynamic>{
26
- "address" : "444",
27
- "amount" : "555",
26
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
27
+ "amount" : "0.00574 BTC",
28
"note" : "sffsfsdsgs"},
29
<String, dynamic>{
30
- "address" : "777",
31
- "amount" : "888",
30
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
31
+ "amount" : "0.000482 BTC",
32
"isFrozen" : false},
33
<String, dynamic>{},
34
+ <String, dynamic>{
35
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
36
+ "amount" : "0.00012 BTC",
37
+ "isFrozen" : true,
38
+ "note" : "333cvgf23132132132132131321321314rwrtdggfdddewq ewqasfdxgdhgfgfszczcxgbhhhbcgbc"},
39
+ <String, dynamic>{
40
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
41
+ "amount" : "0.00574 BTC",
42
+ "note" : "sffsfsdsgs"},
43
+ <String, dynamic>{
44
+ "address" : "bc1qm80mu5p3mf04a7cj7teymasf04dwpc3av2fwtr",
45
+ "amount" : "0.000482 BTC",
46
+ "isFrozen" : false},
47
];
48
49
class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCoinsListViewModel;